CreaRack-SL

Deuda #274 Tanda A — alertas en tiempo real y datos honestos en Wireless (v1.85.9)

Resumen

Primera tanda (“Tanda A”) de la task #274, la deuda técnica anotada al cerrar la auditoría profunda del monitoraje (#261): seis fallos puntuales, verificados uno a uno contra el código antes de tocarlos. Tocan dos frentes: que las alertas y los datos en tiempo real lleguen al Observatory cuando de verdad ocurren, y que lo que se mide en Wireless (clientes, métricas disponibles) sea lo que cada equipo puede producir de verdad, ni más ni menos.

Qué corrige cada arreglo

  • B1-#29 — Las alertas disparadas por el Agente (Sentinel) no sonaban en el Observatory: evaluate_alerts_for_ingest() (la vía viva de [[feature—monitoring—alertas-via-viva-agente]], task #229) evaluaba y guardaba la alerta, pero el retorno se descartaba — nadie llamaba a broadcast_alert_sync. Solo el camino antiguo (sondeo desde el servidor, operations.py) hacía sonar la campana al momento; con Sentinel había que recargar la lista. terminal/api/sentinel_ingest.py::receive_bulk_metrics ahora reenvía cada alerta disparada del lote.
  • B1-#2 — La suscripción del WebSocket del Observatory se congelaba en el momento de abrir la pestaña: un target nuevo o recién habilitado no recibía metric_update hasta reconectar a mano. syncSubscriptions() (ObservatoryWebSocket.js?v=14) manda ahora el diff subscribe/unsubscribe al abrir el socket y tras cada loadTargets().
  • B1-#15 — El mismo contador de clientes se sondeaba dos veces por punto de acceso: Cambium y Xirrus declaran el mismo OID en el bucle rápido (fast_poll_oids.station_count) y en el bucle de extras (monitoring_oids.connected_clients/associated_clients) — dos walks SNMP del mismo árbol cada minuto. dedupe_monitoring_oids() (nueva función en terminal/services.py) quita del bucle de extras lo que el bucle rápido ya cubre, al construir la lista de objetivos que recibe el Agente (terminal/api/sentinel.py::get_agent_targets).
  • B1-#25 — available-metrics prometía métricas que un AP no podía dar: station_count/throughput se anunciaban siempre, aunque el AP no tuviera target SNMP o el vendor no soportara conteo rápido de clientes — paneles condenados a “Waiting for data…”. Ahora throughput exige un target con SNMP activo y station_count exige además que el perfil del vendor tenga fast_poll_oids.
  • B1-#12 — El conteo de clientes de la foto de deep discovery salía multiplicado: _count_clients_from_deep() (la misma función que usa [[feature—wireless—clientes-vivos-ahora]] para decidir cuántos clientes tiene un AP vivo) contaba la lista clients entrada por entrada — con 8 OIDs por cliente, salía ×8 cuando el AP no traía clientsPerRadio. Ahora cuenta índices únicos.
  • B1-#27 — deep_snmp_data se guardaba sin tope de tamaño: un AP con tablas SNMP grandes podía escribir un blob sin límite, releído después por todos los listados de la flota. Tope de 512 KB por foto (MAX_DEEP_SNMP_BYTES, ~×8 el tamaño real de una foto típica); lo que lo supera se rechaza con aviso en el log, sin tocar la ficha existente.

Implementación

  • terminal/api/sentinel_ingest.py — reenvío de alert_triggered (B1-#29) y tope MAX_DEEP_SNMP_BYTES en receive_deep_discovery_result (B1-#27).
  • terminal/services.py — nueva función dedupe_monitoring_oids(monitoring_oids, fast_poll_oids) (B1-#15).
  • terminal/api/sentinel.py::get_agent_targets — llama al dedupe antes de mandar la config al Agente.
  • monitoring/api/wireless.py — _count_clients_from_deep() cuenta por índice (B1-#12); get_available_metrics() exige productor real por métrica (B1-#25).
  • static/js/pages/observatory/ObservatoryWebSocket.js?v=14 / observatory.js — syncSubscriptions(), llamada al abrir el socket y tras cada loadTargets() (B1-#2).

Tests

tests/monitoring/test_deuda_274_tanda_a.py (10 tests, uno por comportamiento) + frontend/src/__tests__/static/observatory_ws_subscriptions.test.js (3 tests de contrato sobre syncSubscriptions).

Límite honesto

El efecto real de “menos carga SNMP” (B1-#15) y de las métricas honestas (B1-#25) se verá con la flota del CCIB en septiembre (task #271) — hoy solo hay un AP vivo para probar contra hardware real. Sin cambio en la ayuda de usuario (ningún flujo ni pantalla nueva).

Commits relacionados

  • 6518b2a8 (2026-08-27) — fix(monitoring): deuda #274 Tanda A, PR #446, v1.85.9.

Véase también

  • [[feature—monitoring—alertas-via-viva-agente]]
  • [[feature—monitoring—auditoria-261-ciclo-4-cableado-observatory]]
  • [[feature—wireless—clientes-vivos-ahora]]
  • [[entity—monitoring—consumer—realtime-websocket]]
  • [[feature—wireless—deep-discovery-timestamp]]
  • [[crearack-tech—architecture—wireless-monitor]]