CreaRack-SL

Feature: Avisos del requisito 24/7 del Sentinel

Resumen

Comunicación clara y contextual sobre el requisito 24/7 de la monitorización con Sentinel. El sistema avisa de forma persistente (tranquila) en varios sitios clave cuando Sentinel está activo, y muestra un aviso destacado (warning/naranja) cuando no hay monitorización 24/7 porque no hay un agente Primary asignado en un dispositivo siempre encendido — incluyendo, desde la task #190, el propio menú lateral (sidebar) de Sentinel Mode, que se despliega solo para que el aviso no pase desapercibido.

Enfoque del diseño: “Informar siempre, alarmar al faltar” — el usuario siempre sabe el estado de su monitorización 24/7, sin necesidad de expandir paneles ocultos.

Implementación

Nuevos estilos CSS

Archivo modificado: static/css/components.css

Se añadieron 92 líneas de CSS nuevo con los siguientes componentes de UI:

.info-note — Nota informativa tranquila

  • Flex layout con rail lateral (línea gris de 2px).
  • Texto pequeño (12.5px) en color secundario, con énfasis (strong) en color primario.
  • Usado cuando Sentinel está activo: comunica que la monitorización 24/7 corre y requiere un dispositivo siempre encendido.

.alert — Aviso destacado (warning)

  • Borde izquierdo de 3px en naranja (var(--warning), RGB 255/152/0).
  • Fondo suave (9% del warning mezclado con card-bg).
  • Estado visual: recuperable, no caída en curso.
  • Contiene .alert-title (13.5px, weight 650) y .alert-body (12.5px) + .alert-actions (botones/links opcionales).

.sentinel-caption + .fleet-caption — Leyendas persistentes

  • Texto muy pequeño (11.5-12px) en color secundario, siempre visible.
  • .sentinel-caption: aparece en el panel Sentinel Mode del sidebar.
  • .fleet-caption: aparece en el widget Agent Fleet del overview (ej. “24/7 monitoring (Sentinel) runs on your Primary agent…”).

.badge-primary — Etiqueta “Primary”

  • Badge azul (accent color) que marca la celda del agente Primary en el Fleet Manager.
  • Text-transform: uppercase, pequeño (10px, weight 700).
  • Comunicación visual clara: “Este es el agente en el que corre Sentinel”.

.sentinel-header-dot.off — Indicador en la cabecera

  • Punto/dot naranja en la cabecera del panel Sentinel Mode cuando no hay monitorización (sentinel_active: false).
  • Visible incluso con el panel colapsado — alerting sin necesidad de expandir.

JavaScript — Lógica de avisos

Función principal: _renderFleetSentinelNotice(fleet) en static/js/base.js

// Fleet Manager modal (tarea #182)
function _renderFleetSentinelNotice(fleet) {
    const el = document.getElementById('fleet-sentinel-notice');
    if (!el) return;
    
    // State A: ¿hay algún agente online con Sentinel activo?
    const sentinelActive = Array.isArray(fleet) && 
        fleet.some(a => a.status === 'online' && a.sentinel_active);
    
    if (sentinelActive) {
        // Mostrar nota tranquila
        el.innerHTML = `<div class="info-note">...</div>`;
    } else {
        // Mostrar alerta naranja
        el.innerHTML = `<div class="alert">...</div>`;
    }
}

Llamada en el flujo:

  • Se invoca desde loadAgentFleetData() tras cargar el objeto fleet desde /api/agent/fleet.
  • El modal Fleet Manager tiene un contenedor <div id="fleet-sentinel-notice"> que se rellena dinámicamente.

En Observatory Agent (static/js/pages/observatory/ObservatoryAgent.js):

  • Se evalúa fleet.some(a => a.status === 'online' && a.sentinel_active).
  • Si hay agentes pero ninguno es Primary con Sentinel activo, se prepend un .alert al contenido.
  • Mensaje: “No agent is set as Primary, so Sentinel is not watching your infrastructure”.
  • Desde task #190: además dispara document.dispatchEvent(new CustomEvent('observatory:fleet-sentinel', { detail: { hasAgents, sentinelActive } })) con el mismo dato ya calculado, para que otros widgets (el sidebar) reaccionen sin volver a llamar a la API.

Archivo modificado: static/js/pages/observatory/ObservatorySentinel.js

Antes, el aviso de “24/7 monitoring is off” solo vivía en el widget Agent Fleet del overview; el menú lateral (sidebar) de Sentinel Mode no decía nada si el usuario no lo desplegaba. La task #190 cierra ese hueco:

  • _initOrgSentinelNotice(obs) se registra una vez (guard obs._orgNoticeBound) al primer loadSentinelConfig() y escucha observatory:fleet-sentinel.
  • Al recibir el evento, calcula off = hasAgents && !sentinelActive y:
    • Muestra/oculta el nuevo bloque <div class="alert hidden" id="sentinel-org-notice"> dentro del panel (mismo copy que el aviso del widget Agent Fleet: “24/7 monitoring is off” / “No agent is set as Primary…”).
    • Despliega el panel una sola vez por carga (obs._orgNoticeExpanded) si estaba colapsado — si el usuario vuelve a plegarlo, se respeta su elección el resto de la sesión.
    • Actualiza el punto de la cabecera vía _updateSentinelHeaderDot(obs), que ahora corta antes de calcular el modo cloud/local si obs._orgSentinelOff es true (el punto se queda naranja “apagado” independientemente del modo configurado).
  • Sin segunda llamada a la API: el dato viene del widget Agent Fleet (ObservatoryAgent.js), que ya consulta /api/agent/fleet. El sidebar no toca el sondeo local /api/agent/status (_checkAgentHealth), que es de otro dueño.

Cambios en templates HTML

templates/base.html

  • Nuevo contenedor <div id="fleet-sentinel-notice"> en el modal Fleet Manager.
  • Rellenado por la función _renderFleetSentinelNotice(fleet) que se invoca desde loadAgentFleetData().

templates/monitoring/observatory.html

  • Sidebar Sentinel Mode: nuevo <div class="sentinel-caption"> con texto persistente.
    • Texto: “24/7 monitoring runs on the Primary agent. Keep it on a device that stays on.”
    • Task #190: nuevo <div class="alert hidden" id="sentinel-org-notice"> dentro de .sentinel-panel, encendido/apagado por ObservatorySentinel.js.
  • Widget Agent Fleet (overview): nuevo <p class="fleet-caption"> encima de la grid de agentes.
    • Texto con énfasis: “24/7 monitoring (Sentinel) runs on your Primary agent. Keep it on a device that stays on — a server or mini-PC, not a laptop.”

Comportamiento

State A: Sentinel activo (hay agente Primary online con sentinel_active: true)

  • Fleet Manager modal: muestra nota tranquila .info-note con rail lateral gris.
    • Texto: “The Primary agent runs Sentinel — your 24/7 monitoring. It must be installed on a device that stays powered on…”
  • Observatory Agent widget: NO muestra alerta (condición fleet.length > 0 && !_sentinelActive es falsa).
  • Sidebar Sentinel Mode: aviso #sentinel-org-notice oculto, punto de cabecera según el modo configurado (verde/naranja/rojo normal).
  • Captions persistentes: visibles en sidebar y overview.

State B: Sentinel inactivo (no hay Primary o no tiene sentinel_active)

  • Fleet Manager modal: muestra aviso naranja .alert.
    • Título: “No Primary assigned — 24/7 monitoring is off”
    • Body: “Sentinel runs on the Primary agent and must live on a device that stays powered on…”
    • Refuerzo visual: borde naranja (RGB 255/152/0), fondo suave.
  • Observatory Agent widget: muestra alerta en la parte superior.
    • Título: “24/7 monitoring is off”
    • Body: “No agent is set as Primary, so Sentinel is not watching your infrastructure…”
  • Sidebar Sentinel Mode: muestra el mismo aviso destacado dentro del panel y se despliega solo una vez si estaba plegado; el punto de cabecera se queda naranja “apagado” aunque el panel esté colapsado.

Internacionalización (i18n)

Status: Strings nuevos están marcados con ${t('...')} en JS y {% trans '...' %} en templates.

Deuda documentada:

  • Traducción al español (ES) de los avisos → Ciclo F4 (faseado para próxima iteración).
  • Los strings en inglés están traducibles pero no tienen equivalente ES aún.

Deuda técnica asociada

  1. Sidebar auto-expand + aviso destacado — RESUELTO en task #190 (commit c5b104e, v1.85.5). El sidebar Sentinel Mode escucha el evento observatory:fleet-sentinel disparado por ObservatoryAgent.js y reacciona con el aviso + auto-expand + punto naranja, sin una segunda llamada a la API.

  2. I18n ES:

    • Strings nuevos necesitan traducción → Ciclo F4.
  3. Cambios API esperados (out of scope de este PR):

    • /api/agent/fleet debe devolver campo sentinel_active en el objeto agente.
    • Status quo: asumido que ya existe (verificado en local por el autor).

Verificación local

Testeado por el autor (@Esquembri, co-authored por Claude Opus 4.8):

  • Modal muestra aviso State B (borde naranja) sin Sentinel activo. ✓
  • Captions persistentes en widget y sidebar. ✓
  • Cero errores en consola. ✓

Task #190 (v1.85.5): sidebar auto-expand + aviso + punto de cabecera verificados sobre el dato real del widget Agent Fleet, sin segunda llamada a la API.

Véase también

  • [[crearack—monitoring—fleet-manager]]
  • [[crearack—monitoring—alertas]]
  • [[feature—observability—alerting-prod-s95]]
  • [[entity—observability—service—alertmanager]]
  • [[workspace—noticias-alertas]]