7913116a8e
- .claude/agents/fn-analizador/SKILL.md - .claude/agents/fn-constructor/SKILL.md - .claude/agents/fn-executor/SKILL.md - .claude/agents/fn-mejorador/SKILL.md - .claude/agents/fn-orquestador/SKILL.md - .claude/agents/fn-recopilador/SKILL.md - .claude/commands/app.md - .claude/commands/compile.md - .claude/commands/cpp-app.md - .claude/commands/create_functions.md - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
182 lines
9.4 KiB
YAML
182 lines
9.4 KiB
YAML
# 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: <path>" 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).
|