CreaRack-SL

Timestamp del análisis profundo (Deep Discovery)

Descripción general

Desde v1.66.16, cada resultado del análisis profundo (deep discovery) de puntos de acceso queda fechado automáticamente. La ficha del AP ahora muestra “Deep data from ” en su cabecera, resolviendo el problema de no saber cuándo era la última foto del hardware y la radio.

El problema

El análisis profundo captura una foto detallada de cada equipo (radios, clientes, hardware, inventario), pero esa foto nunca llevó fecha. El ingest guardaba con update_fields y los auto_now no se ejecutan en ese contexto, así que:

  • Un AP caído podía mostrar datos de 6 semanas sin indicación de antigüedad.
  • La interfaz no decía si la foto era reciente o histórica.
  • No había forma de validar si el problema ya estaba o es nuevo.

La solución

Campo nuevo: DeviceProfile.deep_snmp_updated_at

Modelo (network/models/profile.py):

deep_snmp_updated_at = models.DateTimeField(
    null=True,
    blank=True,
    help_text="Cuándo se tomó la foto del deep discovery (null = anterior a v1.66.16)",
)
  • null=True: el histórico queda sin fecha (datos previos a 2026-08-14).
  • Se llena automáticamente en el ingest (sentinel_ingest.py) al guardar con éxito.

Migración

network 0060 añade el campo vacío; se rellena a futuro.

Exposición en APIs

  1. DeviceProfileListOut (network/api/common.py):

    • Nuevo field: deep_snmp_updated_at: str | None = None
    • Resolver: serializa a ISO si no es null.
  2. Wireless deep-data (monitoring/api/wireless.py):

    • GET /api/network/auto-provision/profiles/{id} devuelve deep_data_as_of con el timestamp.

Ingest: marcado del sello

terminal/api/sentinel_ingest.py > receive_deep_discovery_result():

if success:
    profile.deep_snmp_updated_at = timezone.now()
    profile.save(update_fields=["deep_snmp_data", "deep_snmp_updated_at"])

Contrato:

  • ✅ Resultado exitoso → deep_snmp_updated_at se estampa con timezone.now().
  • ✅ Resultado fallido → no toca nada (null se mantiene).

Presentación en la ficha del AP

static/js/pages/wireless/WirelessDetail.js:

const asOf = this._deepAsOf.get(profileId);
const when = new Date(asOf).toLocaleString();
asOfEl.textContent = ' · ' + interpolate(t('Deep data from %(date)s'), { date: when }, true);

Catálogo (locale/es/LC_MESSAGES/djangojs.po):

msgid "Deep data from %(date)s"
msgstr "Deep data del %(date)s"

Renderiza junto a FW: IP · vendor model · FW vX.Y · Deep data from 14/08/2026 11:39

Matiz importante: histórico sin fecha

La decisión asumida (14-08 con Edu):

Solo se fechan los discovers a partir de ahora. El histórico queda null y la ficha no enseña fecha hasta el primer deep discover nuevo de cada equipo.

  • Razón: imposible infierir la fecha de una foto antigua sin registro.
  • Impacto: APs sin analizar desde v1.66.16 no mostrarán fecha en su ficha.
  • Aceptable: el próximo análisis (auto-triggered cada 5 min) la llenará.

Tests

tests/api/test_deep_discovery_timestamp.py:

  1. test_successful_result_stamps_updated_at: POST con success=true rellena deep_snmp_updated_at.
  2. test_failed_result_does_not_stamp: POST con success=false deja deep_snmp_updated_at sin cambiar.

Ambos fijan el contrato y evitan regresión.

Impacto en líneas de versión

  • CHANGELOG.md: v1.66.16 documenta el cambio.
  • RELEASE_NOTES.md: entrada pública explicando el beneficio y el matiz.
  • config/settings/base.py: APP_VERSION = "1.66.16".
  • README.md: versión actualizada a 1.66.16.

Véase también

  • [[entity—network—model—deviceprofile]]
  • [[concept—monitoring—observability]]
  • [[concept—saas—data-integrity]]
  • [[feature—monitoring—wireless-detail-dashboard]]
  • [[feature—monitoring—sentinel-insight-deduplication]]