--- name: audit_data_table_usage kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "AuditDataTableUsage(registryRoot string) ([]DataTableUsageEntry, error)" description: "Escanea apps C++ del registry que declaran uses_modules: [data_table_cpp] y detecta anti-patrones en su uso de data_table::render: ImGui::BeginTable inline, State stack-local (no persistente), render sin BeginChild host, event sink ignorado, y enlace cmake faltante." tags: [audit, data_table, cpp, lint, doctor, modules] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] tested: false tests: [] test_file_path: "" file_path: "functions/infra/audit_data_table_usage.go" params: - name: registryRoot desc: "Raiz absoluta del repositorio fn_registry. Se escanean apps/*, projects/*/apps/*. Solo procesa apps con lang: cpp y uses_modules incluye data_table_cpp." output: "Slice de DataTableUsageEntry, uno por app C++ con uses_modules: [data_table_cpp]. Status: ok (sin findings warn/error), warn (hay findings), n/a (no declara data_table_cpp)." --- ## Ejemplo ```go import "fn-registry/functions/infra" entries, err := infra.AuditDataTableUsage("$HOME/fn_registry") if err != nil { panic(err) } for _, e := range entries { if e.Status == "warn" { fmt.Printf("[%s] %s\n", e.AppID, e.DirPath) for _, f := range e.Findings { fmt.Printf(" %s (%s) %s:%d %s\n", f.Kind, f.Severity, f.File, f.Line, f.Snippet) } } } ``` Expuesto via CLI (una vez integrado en `fn doctor`): ```bash fn doctor data-table # tabla legible fn doctor data-table --json # JSON para agentes ``` ## Cuando usarla - Tras anadir `data_table_cpp` a un nuevo app, verifica que el patron canonico se sigue. - Como gate pre-merge cuando se toca código de integración de data_table. - Periodicamente para detectar apps que usan `ImGui::BeginTable` directamente en lugar de `data_table::render`. - Para auditar que el event sink (`TableEvent`/`events_out`) se consume donde se necesita interactividad. ## Gotchas - `isInsideFunctionBody` es heuristica de balance de llaves: falsos positivos posibles con lambdas o structs anonimos. Ruido bajo en codigo real. - `no_child_host` mira 30 lineas hacia atras del `data_table::render(`. Si el BeginChild esta mas lejos (extraido en helper), se reportara falso positivo. Severidad `warn`, no `error`. - `inline_begintable` suprime findings cuando el archivo contiene `data_table` y `modules` en su path relativo (evita ruido del modulo mismo). - Apps cuyo directorio no existe en el PC local (sub-repos no clonados) se marcan `warn: directory_missing` en vez de analizarse. Esperado en entorno multi-PC. - `cmake_missing_link` usa `if(TARGET fn_module_data_table)` pattern (conditional link). La funcion detecta la presencia de la string `fn_module_data_table` en CMakeLists.txt, sea en `target_link_libraries` o en el guard.