# e2e_checks proposal — registry_dashboard # # app_id: registry_dashboard # lang: cpp # stack: C++ ImGui (fn::run_app), SQLite directo + HTTP client (cpp-httplib) + # WebSocket client (ws_client.cpp RFC6455), nlohmann/json, # datos de registry.db via sqlite_api:8484 (fallback SQLite directo) # date: 2026-05-19 # issue: 0121a wave 2 (design-e2e fn-recopilador) # # Diagnostico del stack: # - app.md: lang=cpp, framework=imgui, domain=tui, NO tiene tag 'service' # - La app es un CLIENTE, no un servidor: no expone puerto propio. # El puerto 8484 es de sqlite_api (dependencia externa), no de este binario. # - entry_point: main.cpp -> fn::run_app(cfg, render) -> GUI loop # - build: cmake --build cpp/build/linux --target registry_dashboard # (el binario queda en cpp/build/linux/apps/registry_dashboard) # En Windows: cpp/build/windows/apps/registry_dashboard.exe (cross-compile MinGW) # - NO tiene --self-test implementado (sin argparse headless en main.cpp) # - NO hay *_test.cpp ni tests/ con pytest en la app # - NO hay frontend/ React/Vite (es C++ puro con ImGui, no Go+frontend) # - NO tiene operations.db propia (usa registry.db via API o directo) # - SIN health endpoint (no es service, no expone HTTP) # - vendor/: solo nlohmann/json.hpp (cpp-httplib via vendor/httplib.h) # - build Linux ya disponible: cpp/build/linux/apps/registry_dashboard # - build Windows ya disponible: cpp/build/windows/apps/registry_dashboard.exe # # IMPORTANTE — por que no hay check "smoke" ni "api_endpoint_kpi": # registry_dashboard no es un servidor — es una app GUI que CONSUME datos. # Un smoke check al estilo "arrancar + health GET" no aplica porque no hay # endpoint que consultar. La validacion de que los datos se cargan # correctamente requiere que sqlite_api este corriendo (dependencia externa) # o que se pase un registry.db directo. Ambos casos se cubren con el check # 'integration_sqlite_direct' abajo, que es determinista y sin dependencias. # # El check 'api_endpoint_kpi' solicitado en el prompt del orquestador se # implementa indirectamente via 'integration_sqlite_direct': se construye # el binario con DISPLAY no seteado e invocacion headless no disponible. # Ver 'ops_audit' para el camino alternativo via fn-recopilador. # # Instrucciones de adopcion: # 1. Copiar el bloque "e2e_checks:" al frontmatter de # projects/fn_monitoring/apps/registry_dashboard/app.md # (antes del primer "##" de prosa). # 2. El check 'build' asume que el directorio cpp/build/linux existe y cmake # fue configurado previamente. Si no: anteponer # "cmake -B $HOME/fn_registry/cpp/build/linux -S $HOME/fn_registry/cpp &&" # al cmd o usar el check 'build_configure' (opcional, ver abajo). # 3. El check 'integration_sqlite_direct' requiere que registry.db exista en # la raiz del repo. En CI, puede copiarse de un fixture o generarse con # 'fn index' antes de lanzar la suite. # 4. Severity de 'build' puede bajarse a 'warning' si el binario Windows es # el artefacto principal de deploy y el Linux build es solo CI-gate. # # NOTA: NO escribir directo al app.md — propuesta para revision humana. e2e_checks: # --- build --- # Compila el target registry_dashboard para Linux via cmake. # Usa el build directory preexistente (cmake ya configurado). # El binario queda en cpp/build/linux/apps/registry_dashboard. # CGO no aplica (es C++, no Go). FTS5 se compila via SQLITE_ENABLE_FTS5 # en la amalgamation vendoreada (CMakeLists.txt lo setea). - id: build cmd: "cmake --build $HOME/fn_registry/cpp/build/linux --target registry_dashboard -j$(nproc)" timeout_s: 300 severity: critical # por que: la app enlaza ~20 funciones del registry C++ + sqlite + ws_client. # Un fallo de build indica API break en fn_framework, funcion del registry # con firma cambiada, o include roto. Es el gate mas importante para una # app sin tests automaticos. # --- verify_binary --- # Confirma que el binario existe y es ejecutable tras el build. # Tambien verifica la version de symbols minimos esperados (sin linkage roto). - id: verify_binary cmd: "test -x $HOME/fn_registry/cpp/build/linux/apps/registry_dashboard && $HOME/fn_registry/cpp/build/linux/apps/registry_dashboard --help 2>&1 || true" expect_exit: 0 timeout_s: 5 severity: critical # por que: --help no esta implementado en la app, pero el binario debe poder # cargarse sin segfault. exit != 139 (SIGSEGV) es suficiente. # Detecta linkage roto (missing .so, wrong rpath) que el build paso por alto. # --- integration_sqlite_direct --- # Verifica que el binario puede abrir registry.db via SQLite directo # (sin sqlite_api corriendo) en modo headless usando timeout como proxy. # La app imprime "SQLite fallback: " a stdout y luego entra en el # GUI loop. timeout 3s mata el proceso antes de que el loop arranque pero # DESPUES de que load_registry_data() ejecute la query SQL inicial. # exit 124 = proceso terminado por timeout (exitoso para nuestro proposito). # exit != 1 y != 139 indica que la carga SQL no crash. - id: integration_sqlite_direct cmd: > DISPLAY="" timeout 3 $HOME/fn_registry/cpp/build/linux/apps/registry_dashboard $HOME/fn_registry/registry.db 2>&1 | head -5 expect_exit: 1 timeout_s: 10 severity: warning # por que: valida la capa data.cpp (SQLite directo) sin depender de # sqlite_api ni de un display X11. En headless, GLFW falla al abrir # la ventana (exit 1) pero ANTES de eso load_registry_data() ya ejecuto # las queries. Si el exit es 139 (SIGSEGV) o 134 (SIGABRT) -> regression # en las queries SQL o en el parsing del schema. # Severity warning porque el output exacto puede variar segun la version # de GLFW en el CI. # NOTA: si se implementa --self-test en la app, escalar a critical y # usar ese flag en lugar de DISPLAY="" timeout 3. # --- data_schema_check --- # Verifica que el schema de registry.db tiene las tablas que data.cpp # espera: functions, types, apps, analysis, proposals, unit_tests. # Este check no requiere el binario compilado — es SQL puro sobre la BD. # Actua como pre-condicion para integration_sqlite_direct. - id: data_schema_check cmd: > sqlite3 $HOME/fn_registry/registry.db "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name IN ('functions','types','apps','analysis','proposals','unit_tests');" expect_stdout_contains: "6" timeout_s: 5 severity: critical # por que: si faltan tablas, data.cpp lanzara queries que retornan error. # Detecta migraciones no aplicadas o registry.db corrupto antes de # intentar el build + integration test. # --- call_monitor_schema_check --- # Verifica que call_monitor.operations.db (consumida por la tab Monitor) # tiene la tabla 'calls' que load_claude_usage_http() espera via sqlite_api. # Este check valida la BD directamente — en produccion sqlite_api la expone # via HTTP, pero aqui queremos detectar schema drift independientemente. - id: call_monitor_schema_check cmd: > sqlite3 $HOME/fn_registry/projects/fn_monitoring/apps/call_monitor/operations.db "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name IN ('calls','violations','sessions');" expect_stdout_contains: "3" timeout_s: 5 severity: warning # por que: la tab Monitor del dashboard se nutre de estas tablas. # Si 'calls' no existe, la tab muestra placeholder vacio sin error visible. # severity warning porque call_monitor.db puede estar vacia en un entorno # nuevo (aun sin datos de telemetria). # --- ws_client_compile_check --- # Verifica que ws_client.cpp compila sin warnings fatales. # El cliente WebSocket es codigo propio (no libreria vendored) que implementa # RFC6455 minimal — propenso a regresiones si se cambia la interfaz de # WsClient sin actualizar todos los call sites. - id: ws_client_compile_check cmd: > cmake --build $HOME/fn_registry/cpp/build/linux --target registry_dashboard -j$(nproc) -- --warn-undefined-functions 2>&1 | grep -i "ws_client" | grep -i "error" || true expect_stdout_contains: "" timeout_s: 60 severity: warning # por que: ws_client es la pieza mas fragil del stack (RFC6455 manual, # sin tests dedicados). Buscar explicitamente errores en ws_client.cpp # en el output de cmake da visibilidad sin duplicar el check build. # expect_stdout_contains "" = la busqueda no encuentra errores (grep # devuelve vacio). Si grep encuentra algo, el check falla con exit 0 # pero stdout no vacio — revisar la logica si fn-analizador necesita # el patron inverso. # --- ops_audit --- # Invoca al fn-recopilador sobre el directorio de la app para verificar # que app.md esta bien indexado en registry.db, que uses_functions son # validos, y estructura general del artefacto. # No hay operations.db propia en esta app — el recopilador auditara # solo la estructura y las referencias cruzadas con registry.db. - id: ops_audit ref: "fn-recopilador:projects/fn_monitoring/apps/registry_dashboard" severity: warning # por que: registry_dashboard declara ~20 uses_functions en app.md. # El recopilador verifica que cada ID existe en registry.db y detecta # drift si alguna funcion fue renombrada o eliminada. # severity warning porque la app puede funcionar correctamente aunque # un ID en uses_functions este mal escrito (solo metadata).