# app_id: services_api # lang: go (CGO_ENABLED=1, go-sqlite3, NO fts5 — no FTS5 features in this app) # stack: net/http + SQLite (go-sqlite3) + SSH polling (ssh_exec_go_infra) # dir_path: apps/services_api # entry: main.go (--bind / --once / --registry / --db flags) # service: port 8485, health /api/health, systemd-user # ops.db: SI — service_state + service_transition (001_init.sql applied) # sin entities/relations/executions del schema fn_operations # tests: NO (*_test.go absent) — solo --once como smoke gate # basicAuth: NO detectado en main.go / check.go # ssh: SI — probeRemote usa infra.SSHExec (ssh_exec_go_infra) # e2e port: 8585 (prod 8485 + 100, evita colision) # issue: 0121a wave 2 — design-e2e services_api # date: 2026-05-19 # # INSTRUCCIONES PARA EL HUMANO: # 1. Revisar y ajustar comentarios; luego copiar el bloque e2e_checks: # al frontmatter de apps/services_api/app.md (despues de service: block). # 2. El check ops_audit invoca fn-recopilador sobre operations.db propia # (NO usa el schema estandar fn_operations — solo service_state/service_transition). # 3. El check smoke_once usa --once + --db efimera para no contaminar la BD # de produccion ni necesitar registry.db real (usa /tmp/fn_e2e_sreg.db con # un registry.db vacio). # 4. smoke_health sube el binario como daemon real en puerto 8585 y verifica # /api/health. Requiere que el check build haya producido el binario. # 5. No hay go test porque no existen *_test.go. Si se añaden tests en el # futuro, activar el check tests descomentando la entrada correspondiente. e2e_checks: # ----------------------------------------------------------------------- # 1. BUILD # CGO_ENABLED=1 porque go-sqlite3 requiere cgo (no hay fts5 en este app, # pero el flag no rompe nada y evita confusion futura si se añade FTS). # ----------------------------------------------------------------------- - id: build cmd: "cd $HOME/fn_registry/apps/services_api && CGO_ENABLED=1 go build -o services_api ." timeout_s: 120 severity: critical # por que: si no compila no hay nada que probar # ----------------------------------------------------------------------- # 2. SMOKE --once # Corre un ciclo completo de checks sin arrancar el HTTP server. # Usa una BD efimera en /tmp y apunta el registry a fn_registry real # (read-only); las queries a registry.db devuelven los targets reales del PC. # Exit 0 = el loop no peta al cargar targets + persistir en ops_db. # ----------------------------------------------------------------------- - id: smoke_once cmd: > cd $HOME/fn_registry/apps/services_api && FN_REGISTRY_ROOT=$HOME/fn_registry ./services_api --once --registry $HOME/fn_registry --db /tmp/services_api_e2e.db --bind 127.0.0.1:8585 timeout_s: 45 severity: critical # por que: valida que loadTargets + probeLocal + upsertState no panican # Nota: SSH remotes daran no-route (sin config SSH en CI) — eso es correcto # y no falla el check; el exit code del proceso es 0 si completo el ciclo. # ----------------------------------------------------------------------- # 3. SMOKE HTTP + HEALTH # Arranca el server en background en puerto 8585 con BD efimera, # espera que /api/health responda 200. # ----------------------------------------------------------------------- - id: smoke_health cmd: > cd $HOME/fn_registry/apps/services_api && ./services_api --bind 127.0.0.1:8585 --registry $HOME/fn_registry --db /tmp/services_api_e2e_http.db --interval 300s & health: "http://127.0.0.1:8585/api/health" timeout_s: 15 severity: critical # por que: verifica que el HTTP server arranca y responde en el puerto # declarado en service.port (proxy: 8585 en lugar de 8485) # ----------------------------------------------------------------------- # 4. ENDPOINT /api/services (warning — depende de datos del PC) # Valida que el endpoint responde JSON bien formado con el campo self_pc. # Es warning porque en un PC sin ~/.fn_pc o sin registry.db poblado # puede devolver lista vacia pero eso no es un bug. # ----------------------------------------------------------------------- - id: check_services_endpoint cmd: > curl -sf http://127.0.0.1:8585/api/services | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'services' in d and 'self_pc' in d" timeout_s: 10 severity: warning # por que: smoke de formato de respuesta del endpoint principal que # services_monitor (C++) consume. Un cambio de schema JSON rompe el cliente. # ----------------------------------------------------------------------- # 5. ENDPOINT /api/pcs (warning) # Valida que /api/pcs responde con el campo pcs. # ----------------------------------------------------------------------- - id: check_pcs_endpoint cmd: > curl -sf http://127.0.0.1:8585/api/pcs | python3 -c "import sys,json; d=json.load(sys.stdin); assert 'pcs' in d" timeout_s: 10 severity: warning # por que: services_monitor usa /api/pcs para la barra lateral de PCs # ----------------------------------------------------------------------- # 6. OPS AUDIT # Invoca fn-recopilador sobre la operations.db propia. # NOTA: esta BD tiene schema propio (service_state, service_transition), # NO el schema estandar fn_operations (entities/relations/executions). # El recopilador auditara estructura y datos vivos. # ----------------------------------------------------------------------- - id: ops_audit ref: "fn-recopilador:apps/services_api" severity: warning # por que: detecta inconsistencias en service_state (ej. overall invalido, # last_check_ts cero en todas las filas = --once nunca corrio) # ----------------------------------------------------------------------- # OMITIDO: tests # No existen *_test.go en apps/services_api. Activar cuando se añadan. # # - id: tests # cmd: "cd $HOME/fn_registry/apps/services_api && CGO_ENABLED=1 go test -count=1 ./..." # timeout_s: 120 # severity: critical # -----------------------------------------------------------------------