Cron: stale-check.ts — Detector de nodos desactualizados en la Biblioteca
Descripción
Cron handler CF Workers que ejecuta periódicamente (cada N minutos) para calcular y registrar la salud de la Biblioteca. Es el productor de métricas: cuenta cuántos nodos están desactualizados (sin content_hash o con last_indexed_at viejo) y escribe los resultados en activity_log (tabla D1).
El nombre refiere a “stale” (desactualizado): detecta y cuantifica qué nodos del índice (bib_nodes) ya no están frescos.
Componentes principales
onRequestPost()
Propósito: Punto de entrada del cron (vía CF Workers cron trigger).
Firma:
export const onRequestPost: PagesFunction<Env> = async ({ env, request }) => { ... }
Flujo:
- Query D1 para contar nodos stale por tipo (GROUP BY node_type).
- Query D1 para contar total de nodos trackables.
- Calcular
health_percent = (total_nodes - stale_count) / total_nodes * 100. - Construir JSON de resumen.
- Escribir evento en
activity_logcon todos los detalles. - Retornar JSON con estado de ejecución.
Fuente de datos: Tabla bib_nodes (el índice completo de la Biblioteca).
Lógica de conteo (post-fix commit@99817e5)
Nodos “stale” (desactualizados)
Query:
SELECT node_type, COUNT(*) as count
FROM bib_nodes
WHERE node_type NOT IN ('endpoint', 'schema', 'doc')
AND (content_hash IS NULL OR last_indexed_at < ?)
GROUP BY node_type
ORDER BY count DESC
Filtros:
- Excluye 3 tipos que no tienen
content_hash:endpoint,schema— bulk-import OpenAPI (sin cambios file-based).doc— documentación wiki; su salud la mide el sensor Bibliotecario aparte (diagnóstico s210).
- Incluye: model, function, js_module, service, handler, etc. (nodos con
content_hash).
Criterio de staleness:
content_hash IS NULL— nunca ha sido indexado.last_indexed_at < ?— última actualización hace demasiado (threshold configurable).
Nodos “trackables” (total)
Query:
SELECT COUNT(*) as count
FROM bib_nodes
WHERE node_type NOT IN ('endpoint', 'schema', 'doc')
Este es el denominador del %. Excluye los mismos 3 tipos para mantener coherencia con el numerador.
Post-fix: Antes el denominador era COUNT(*) global (incluía endpoint/schema/doc) → % falso. Ahora es acotado → honesto.
Universo de medición
| Categoría | Qué es | ¿Se mide? | Razón |
|---|---|---|---|
| endpoint / schema | APIs bulk-import (OpenAPI) | No | Estructural, no file-based, nunca escriben content_hash |
| doc | Documentación wiki (.md) | No | La mide el sensor Bibliotecario (context documents). Indexador de docs no escribe content_hash → contarían como stale permanente (inflaban el rojo) |
| model / function / service / handler / js_module | Código vivo (Python/TS/etc.) | Sí | Tienen content_hash, representan la verdadera cobertura del índice |
Salud calculada
health_percent = (total_nodes - stale_count) / total_nodes * 100
Ejemplo post-fix:
total_nodes = 4670(Python models, TS functions, etc.)stale_count = 1000(necesitan reindexación)health_percent = (4670 - 1000) / 4670 * 100 = 78.6%
Event log en activity_log
El cron escribe un registro en activity_log con:
Columnas:
event_type='stale-check'timestamp= CURRENT_TIMESTAMPstatus='success'/'error'details= JSON con:{ "stale_count": 1000, "health_percent": 78.6, "total_nodes": 4670, "staleSummary": { "function": 500, "js_module": 300, "service": 200 } }
Este JSON es lo que health.ts lee para llenar el widget.
Decisiones de diseño
Exclusión de doc (post-fix)
Antes: Incluía ~957 doc nodos en el conteo. Problema: el indexador de documentos no escribe content_hash, así que TODOS los docs contaban como stale permanente. Esto inflaba artificialmente el “rojo” del sensor.
Después: Se excluyeron. Razón: los docs no son código; su salud la mide otro sensor (Bibliotecario-Checker que recorre archivos .md en contexto/). Este sensor solo debe medir la salud del índice de CÓDIGO.
Resultado: El drift real (p. ej. una JS module con fecha vieja) sigue siendo detectado. El sensor ahora es “honesto”.
Testing recomendado
- Ejecutar query de stale_count y total_nodes; verificar que excluyen endpoint/schema/doc.
- Simulación: crear un nodo nuevo sin content_hash; verificar que aparece en stale_count.
- Verificar que el JSON escrito en activity_log tiene keys esperadas (health_percent, total_nodes, stale_count).
- Ejecutar health.ts y comprobar que lee correctamente del activity_log.
Véase también
- [[entity—functions—handler—health-check-biblioteca]]
- [[concept—biblioteca—nodo-trackable]]
- [[entity—biblioteca—endpoint—crons]]