Volver a la wiki

Crons Health — Monitorización de los 12 crons del workspace en el Pulse

Crons Health — Monitorización de los 12 crons del workspace en el Pulse

Resumen

Implementa el sistema completo de monitorización del estado de los 12 crons del workspace CreaRackSL en la tarjeta “Crons del sistema” de la banda 4 del Pulse (PulsePanel.tsx). Introducido en el commit 009ca75 (s82, 2026-05-24), cierra el pendiente de s81 en el que 9 de 12 filas mostraban ”—” al carecer de datos reales.

Tras esta feature, 11 de 12 crons tienen lastRun real. El cron pg_dump CreaRack-Pro permanece con ”—” honesto por no tener telemetría accesible desde el workspace (Regla 13: sin fakes).

Motivación (s81 → s82)

Antes de s82, CronsHealthCard recibía solo data.bibliotecario (los 3 crons del Bibliotecario con datos reales) y construía el resto de filas con lastRun: null hardcodeado. Los 9 crons externos (Reindex, Wiki, Sync, Backups) mostraban ”—” con el comentario “Los crons con «—» esperan al endpoint /biblioteca/crons”.

s82 completa ese endpoint y conecta la tarjeta a él.

Arquitectura

PulsePanel.tsx
  └── fetch('/biblioteca/crons') cada 60s (best-effort)
        │
        ▼
functions/biblioteca/crons.ts  (CF Access · browser)
functions/api/biblioteca/crons.ts  (Bearer · server-to-server)
        │  ambos llaman a:
        ▼
functions/_lib/crons.ts
  └── buildCronsReport(env: CronsEnv): Promise<CronsReport>
        ├── D1: bib_wiki_log         → Bibliotecario ingest/curate/lint
        ├── D1: bib_nodes (MAX .py)  → Reindex AST Python
        ├── D1: activity_log         → DR Backups workspace
        └── GitHub Actions API (×6)  → workflows reindex-ts, reindex-cm,
                                        wiki-drift, wiki-translate,
                                        wiki-weekly, sync-cascade

Componentes nuevos

functions/_lib/crons.ts — Builder (299 LOC)

Biblioteca compartida que reúne los datos de todas las fuentes. Exporta:

IDs de workflows GHA verificados en s82:

WorkflowID
bib-reindex-ts.yml265753720
bib-reindex-claude-method.yml279618390
wiki-drift-check.yml276707608
wiki-translate.yml276287061
wiki-weekly-report.yml265712084
sync-cascade-detect.yml281534648

functions/biblioteca/crons.ts + functions/api/biblioteca/crons.ts — Handlers (13 LOC cada uno)

Handlers CF Pages Functions que simplemente llaman a buildCronsReport(env) y devuelven Response.json con Cache-Control: private, max-age=60. Ver [[entity—biblioteca—endpoint—crons]] para detalles de auth.

src/components/biblioteca/PulsePanel.tsx — CronsHealthCard (refactor)

Antes: recibía { bibliotecario: BibliotecarioActivity } y construía las filas de los 9 crons externos con lastRun: null hardcodeado.

Después: recibe { report: CronsReport | null }. Mientras report es null muestra un spinner “Cargando estado de los crons…”. Cuando llega el report:

Fetch en PulsePanel: fetch('/biblioteca/crons') en el useEffect junto al resto de fetches del Pulse. Es best-effort: si falla, setCrons(null) no se llama (queda en null) y la tarjeta muestra el estado de carga. Refresh automático cada 60 s (intervalo compartido del Pulse).

Criterios de color del dot

CondiciónColor
status === 'failure'var(--danger) rojo
lastRun === nullvar(--fg-dim) gris
Antigüedad > umbral de grupovar(--warning) naranja
Antigüedad ≤ umbral de grupovar(--success) verde

Umbrales por grupo:

Decisiones de diseño

Sin tabla de cache (hot-cache)

Se eligió no crear una tabla D1 propia para cachear el estado de los crons. El endpoint consulta en cada request con timeouts cortos y Promise.all. Cache-Control: private, max-age=60 evita peticiones redundantes desde el mismo navegador. Si las fuentes tardan o fallan, la tarjeta degrada limpiamente a ”—”.

Dos endpoints gemelos

/biblioteca/crons (CF Access) y /api/biblioteca/crons (Bearer) son idénticos funcionalmente. La separación sigue el patrón del workspace de tener rutas /api/* para uso programático (agentes, scripts) y rutas sin prefijo para el navegador.

pg_dump honesto

El cron pg_dump CreaRack-Pro corre en un servidor Hetzner de PROD sin escribir telemetría en ninguna tabla D1 del workspace. Se devuelve lastRun: null con un note explicativo en lugar de inventar un timestamp o leer una fuente no canónica. Esto sigue la Regla 13 del proyecto.

Estado actual (post-s82)

Véase también

Subir