ADR: Integración de `alertas_waypoint` al Data Warehouse
Aceptada (2026-06-01). Diseñada e implementada vía SDD (cambio
alertas-waypoint-al-dw, archive Engram #1326). Opción C aplicada: build_df
puro + _extract_latlong (geo desde HTML), builder export_alertas_waypoint() →
fact_alertas_waypoint + dim_vehiculo en data_warehouse.db, sink en
migrate_config.py. Verify PASS WITH WARNINGS: 36 tests nuevos, 12/12 scenarios
COMPLIANT, datos reales 1726 filas con geo 100% y FK 100%, auditoría 9/9 tras
refactor CA-2 (DRY)/CA-3 (SRP). Predecessors: proposal #1319, spec #1320, design
#1321, tasks #1322, apply-progress #1324, verify #1325.
:::note Esta ADR cierra parcialmente dos ADRs pendientes del índice Documenta el flujo real pipeline → DW (gap de ADR-Ingeldata-vs-Datawarehouse) y aplica el patrón de sink analítico (gap de ADR-Sink-Connectors). :::
Contexto
Sección titulada «Contexto»Estado actual del pipeline
Sección titulada «Estado actual del pipeline»alertas_waypoint (alertas GPS Waypoint/Tranciti) termina en Excel, no llega al
DW ni a Power BI por el canal estándar. Su pipeline solo implementa ingest → final:
ingest()→ IMAP víaIMAPConnector(patrón Hexagonal F2.1).final()→build_excel_from_raw_alertas_waypoint()→SALIDAS/alertas_waypoint_{timestamp}.xlsx(3 hojas).- No implementa
store(),process()nipublish().
Cómo llega realmente el dato al DW (flujo verificado)
Sección titulada «Cómo llega realmente el dato al DW (flujo verificado)»Hallazgo importante: ningún pipeline implementa la etapa store(). La carga al DW
NO es una etapa del pipeline, sino un epílogo separado en scripts/db/. El sistema
tiene tres capas SQLite en SALIDAS/db/:
| Capa | Archivo | Lo construye | Contenido |
|---|---|---|---|
| Operacional | ingeldata.db | core/sqlite_store.py (save_facturas, save_pedidos_*, save_valorizaciones, save_gantt) + trazabilidad | Tablas con processed_by_version + pipeline_runs, raw_files, etc. |
| Curated | SALIDAS/db/curated/*.db (+ .pkl) | pipelines escriben .pkl → scripts/db/export_to_sqlite.py los inserta | Staging por dominio (facturacion, pedidos_HES/SAP) |
| Analítica (DW) | data_warehouse.db | scripts/db/data_warehouse.py --populate | Star schema fact_* / dim_*, centrado en dim_ot. Es lo que Power BI consume |
pipeline (ingest→final, Excel/curated) │ ▼scripts/db/export_to_sqlite.py → ingeldata.db (operacional/curated) │scripts/db/data_warehouse.py --populate (lee GSheets + CSV + Excel + calendario) → data_warehouse.db (star schema) │scripts/db/supabase_destinations.py → Supabase PostgreSQL → Power BI Servicedata_warehouse.db se alimenta hoy de fuentes externas (Google Sheets, CSV de
gantt, Excel de productividad, calendario generado), no del store() de los pipelines.
Usa save_dataframe(df, tabla, conn, if_exists="replace").
El problema de grano
Sección titulada «El problema de grano»El star schema actual gira en torno a dim_ot (OT / proyecto / zonal). Las alertas
son de grano evento-vehículo (patente + fecha/hora del evento): no tienen OT. No
encajan en dim_ot. Por lo tanto, alertas debe formar una constelación nueva con
sus propias dimensiones, compartiendo solo dim_calendario.
Opciones evaluadas
Sección titulada «Opciones evaluadas»Opción A — Solo Excel + conector de carpeta en Power BI
Sección titulada «Opción A — Solo Excel + conector de carpeta en Power BI»Dejar el Excel y que Power BI lea la carpeta SALIDAS/ tomando el más reciente.
Descartada como solución de DW: queda fuera del modelo, sin Supabase / Power BI Service, y el nombre con timestamp complica el refresh. Sirve solo como stop-gap para hoy.
Opción B — Tabla operacional en ingeldata.db (capa curated)
Sección titulada «Opción B — Tabla operacional en ingeldata.db (capa curated)»Agregar alertas_waypoint a init_schema(), un save_alertas_waypoint(), escribir el
.pkl curated y sumarlo a export_to_sqlite.py.
Pros: sigue el patrón curated existente; da trazabilidad operacional.
Cons: ingeldata.db es operacional, no es el modelo analítico que Power BI
consume; no resuelve grano/dimensiones; no llega solo a Power BI. Útil como sub-paso,
no como destino final.
Opción C — Constelación analítica propia en data_warehouse.db (ELEGIDA)
Sección titulada «Opción C — Constelación analítica propia en data_warehouse.db (ELEGIDA)»Agregar un builder export_alertas_waypoint() en scripts/db/data_warehouse.py que
construya una constelación nueva:
fact_alertas_waypoint— grano: 1 fila por alerta (message_idcomo clave natural / dedup). Medidas:velocidad_real_kmh,velocidad_config_kmh,exceso_kmh, flags portipo_alerta. FKs: fecha del evento →dim_calendario, patente →dim_vehiculo.dim_vehiculo(nueva) — patente, marca, modelo, año, flota, grupo, zonal. SCD tipo 1 (replace) es suficiente.dim_calendario— se reutiliza la existente.dim_conductor(opcional) — si se quiere analizar por conductor.
Fuente del dato: leer el RAW/curated del pipeline (parquet) en vez de re-parsear, lo que
exige un refactor menor: separar en process_alertas_waypoint_from_raw.py la
construcción del DataFrame de la escritura del Excel (hoy están acopladas y solo devuelve
el path). Refresh replace full (volumen bajo: ~1.726 alertas feb–may 2026).
Elegida porque: Power BI lo consume por el mismo canal estándar (DW → Supabase);
el modelo queda correcto por grano; reutiliza dim_calendario; el sync a Supabase lo
arrastra automáticamente al incluir las tablas nuevas.
Decisión
Sección titulada «Decisión»Opción C, con la Opción B como sub-paso opcional si se desea trazabilidad
operacional en ingeldata.db. Camino mínimo viable:
- Refactor: exponer el DataFrame parseado desde
process_alertas_waypoint_from_raw.py(separar build df de write excel). export_alertas_waypoint()endata_warehouse.py→fact_alertas_waypoint+dim_vehiculo.- Flag
--alertas-waypointe inclusión en--populate. - Incluir las tablas nuevas en
supabase_destinations.py. - Power BI: agregar al modelo y crear la relación con
dim_calendario.
Decisiones de diseño puntuales
Sección titulada «Decisiones de diseño puntuales»| Punto | Decisión |
|---|---|
| Grano de la fact | 1 fila por alerta; dedup por message_id |
Vínculo con dim_ot | No — alertas no son OT; constelación independiente |
dim_vehiculo | Nueva, por patente; SCD tipo 1 (replace) |
| Refresh | replace full (volumen bajo) |
processed_by_version | Solo si se adopta Opción B (capa curated). En data_warehouse.db las tablas no llevan versión, consistente con las demás fact_/dim_ |
Archivos a tocar (cuando se implemente)
Sección titulada «Archivos a tocar (cuando se implemente)»| Archivo | Cambio |
|---|---|
domains/alertas_waypoint/process_alertas_waypoint_from_raw.py | Separar build_df de write_excel; exponer el DataFrame parseado |
scripts/db/data_warehouse.py | export_alertas_waypoint() + flag --alertas-waypoint + en --populate |
scripts/db/supabase_destinations.py | Incluir fact_alertas_waypoint + dim_vehiculo en el sync |
core/sqlite_store.py (opcional B) | init_schema() tabla alertas + save_alertas_waypoint() |
scripts/db/export_to_sqlite.py (opcional B) | Rama de export para alertas curated |
| Power BI (modelo) | Añadir fact_alertas_waypoint + dim_vehiculo; relación a dim_calendario |
Consecuencias
Sección titulada «Consecuencias»Positivas
Sección titulada «Positivas»- Alertas disponibles en Power BI Service por el canal estándar (DW → Supabase).
- Modelo analítico correcto por grano (evento-vehículo) reutilizando
dim_calendario. - Sync a Supabase automático al registrar las tablas nuevas.
- Documenta el flujo real pipeline → DW (cierra parcialmente ADR-Ingeldata-vs-Datawarehouse).
Negativas
Sección titulada «Negativas»- Refactor del pipeline para desacoplar DataFrame/Excel.
- Nueva
dim_vehiculoque mantener. - Hay que mantener el registro de las tablas en el sync a Supabase.
Neutras
Sección titulada «Neutras»- Si nunca se cruza con OT, la constelación queda aislada del resto del modelo — esperable: las alertas son operación de flota, no de proyecto.
Ver también
Sección titulada «Ver también»- Pipeline-Alertas-Waypoint — pipeline-referencia (estado actual: solo Excel)
- DB-Structures-IngelCoding — estructura de las 3 capas SQLite
- Arquitectura-Persistencia — raw / processed / output stores
- Reference-BasePipeline — contrato de etapas (
storeopcional, hoy no usado) - ADR-Source-Connectors — patrón Hexagonal; ADR-Sink-Connectors (pendiente) es la cara opuesta aplicable aquí
- Indice-ADRs — registro de decisiones
- Código:
scripts/db/data_warehouse.py,core/sqlite_store.py,scripts/db/export_to_sqlite.py,scripts/db/supabase_destinations.py