Handler CF Workers: health.ts — Sensor de salud del sistema
Descripción
Handler CF Workers que expone el endpoint GET /api/health y reporta el estado de salud del sistema en tiempo real. Es el responsable de leer métricas de activity_log (tabla D1) para construir un resumen visual en el widget Salud del Sistema del panel Pulse.
El handler orquesta 4 sub-chequeos:
- checkBiblioteca() — porcentaje de nodos índexados (código trackable).
- checkBackup() — estado del backup en GCS.
- checkGraph() — integridad del grafo de conocimiento (D1).
- checkCI() + checkWiki() — estado de flujos en GitHub Actions.
Componentes principales
checkBiblioteca()
Propósito: Leer el porcentaje de salud de la Biblioteca desde activity_log (tabla de eventos D1).
Firma:
async function checkBiblioteca(env: Env): Promise<HealthRow>
Lógica post-fix (commit@99817e5):
- Lee del
activity_logel último evento del cronstale-check.ts. - Extrae
health_percent(nombre canónico; fallback acoverage_pctpara compatibilidad). - Extrae
total_nodes(universo de nodos trackable: excluye endpoint/schema/doc). - Calcula
fresh = Math.max(0, total_nodes - stale_count). - Retorna el porcentaje:
(fresh / total_nodes) * 100o elhealth_percentleído.
Corrección clave: Antes del fix, mezclaba numerador (stale_count → excluye endpoint/schema/doc) con denominador global COUNT(*) (incluye todos) → error de ~66% vs. realidad 58%. Ahora lee ambos del mismo activity_log → universo coherente.
Campos de entrada (activity_log):
stale_count— número de nodos sincontent_hasho conlast_indexed_atviejo.health_percent— % precalculado por el cron.total_nodes— COUNT de nodos trackables (ya excluye endpoint/schema/doc).
Retorna:
interface HealthRow {
service: 'biblioteca';
status: 'ok' | 'warning' | 'critical';
pct: number; // 0-100
message: string;
}
onRequestGet()
Propósito: Orquestar todos los sub-chequeos y construir el resumen JSON del widget.
Firma:
async function onRequestGet(request: Request, env: Env): Promise<Response>
Lógica:
- Llama en paralelo a
checkBiblioteca(),checkBackup(),checkGraph(), etc. - Agregando cada resultado en un array
health: HealthRow[]. - Calcula
overall_status(crítico si alguno < 50%, warning si alguno < 75%, ok si todos ≥ 75%). - Retorna JSON con array de states + timestamp.
Fuente de datos: Tabla D1 activity_log (logs de eventos de mantenimiento), tabla bib_nodes (grafo), GCS (backups).
Decisiones de diseño
Universo de “nodos trackables” (post-fix)
El cálculo de salud excluye 3 tipos de nodos que no tienen content_hash:
endpoint,schema— bulk-import de OpenAPI (estructura, no código).doc— documentación wiki (medida por otro sensor Bibliotecario).
Antes del fix: health.ts leía numerador (stale_count) del cron que YA excluía estos 3, pero dividía entre COUNT(*) global (que los incluye) → % incoherente.
Post-fix: Lee total_nodes del mismo activity_log que el numerador → garantiza coherencia.
Interacción con stale-check.ts
El cron stale-check.ts es el productor; health.ts es el consumidor:
-
stale-check.ts (cron cada N minutos):
- Cuenta
stale_count(WHERE node_type NOT IN (‘endpoint’, ‘schema’, ‘doc’) AND (content_hash IS NULL OR last_indexed_at < ?)) - Cuenta
total_nodes(WHERE node_type NOT IN (…)) - Calcula
health_percent = (total_nodes - stale_count) / total_nodes * 100 - Escribe en
activity_logcondetails: { stale_count, health_percent, total_nodes }
- Cuenta
-
health.ts (on-demand API):
- Lee del
activity_logel último evento de stale-check. - Extrae
stale_count,health_percent,total_nodes. - Retorna al widget de UI.
- Lee del
Testing recomendado
- Verificar que
total_nodesen activity_log excluye ~957 doc nodos. - Comparar % reportado en health vs. cálculo manual en D1.
- Simular drift de JS module real (date-stale) y validar que aparece en stale_count.
Véase también
- [[entity—functions—handler—stale-check-cron]]
- [[concept—observability—health-check-pattern]]
- [[entity—biblioteca—endpoint—crons]]