fix(alertas): el aviso de sincronización llevaba a una vista que no existe
Auditoría de los destinos de todas las alertas contra el árbol de rutas real de los siete portales. De 15 enlaces, 14 resuelven; uno no y estaba repetido en cuatro lugares.
/oae/fuentes nunca existió: no hay frontend/app/fuentes/ ni ninguna vista
del OAE que lea data_sources. Era el action_url de sync.outdated (dos
salidas) y de data.source_stale, más el default_action_url de la tabla.
El aviso llegaba bien y el clic daba 404 — parece que el portal se rompió, no
que el enlace está mal.
Ahora van a /admin/logs, que es donde la pregunta se contesta y se arregla:
estado del scheduler, sync_google_sheets con su botón de correr a mano e
historial filtrable. Las dos alertas ya eran de audiencia admin, así que el
destino no saca a nadie de su portal.
La migración corrige lo ya guardado: el default vive en RULE_SCHEMA, pero
una regla creada guardó su action_url en la fila, y las notificaciones
emitidas también. Una notificación abierta cuyo enlace da 404 no es historia,
es una tarea que nadie puede atender.
Y ti_doc_api queda declarada en las DOS whitelists — RULE_SCHEMA del
router y la copia embebida del evaluador. Faltar en una deja crear la regla y
que el evaluador la descarte en silencio. Con esto el umbral
ti_doc_api_dias_por_vencer (90), que existía sin que nadie pudiera
vigilarlo, ya tiene sobre qué medirse. Su destino es /ti/..., no /oae/...:
Documentación API sólo vive en portal_ti y se dejó fuera del árbol compartido
a propósito.
Verificado: las 11 tablas de las dos whitelists coinciden en columnas y tipos,
y las 15 columnas declaradas existen en TiDocApi con el tipo que dicen.
ci_validate_models.py en verde.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com Claude-Session: https://claude.ai/code/session_01VCiQdtADgfKmYLdzXto547