Ir al contenido

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). :::

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ía IMAPConnector (patrón Hexagonal F2.1).
  • final()build_excel_from_raw_alertas_waypoint()SALIDAS/alertas_waypoint_{timestamp}.xlsx (3 hojas).
  • No implementa store(), process() ni publish().

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/:

CapaArchivoLo construyeContenido
Operacionalingeldata.dbcore/sqlite_store.py (save_facturas, save_pedidos_*, save_valorizaciones, save_gantt) + trazabilidadTablas con processed_by_version + pipeline_runs, raw_files, etc.
CuratedSALIDAS/db/curated/*.db (+ .pkl)pipelines escriben .pklscripts/db/export_to_sqlite.py los insertaStaging por dominio (facturacion, pedidos_HES/SAP)
Analítica (DW)data_warehouse.dbscripts/db/data_warehouse.py --populateStar 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 Service

data_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 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.

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_id como clave natural / dedup). Medidas: velocidad_real_kmh, velocidad_config_kmh, exceso_kmh, flags por tipo_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.

Opción C, con la Opción B como sub-paso opcional si se desea trazabilidad operacional en ingeldata.db. Camino mínimo viable:

  1. Refactor: exponer el DataFrame parseado desde process_alertas_waypoint_from_raw.py (separar build df de write excel).
  2. export_alertas_waypoint() en data_warehouse.pyfact_alertas_waypoint + dim_vehiculo.
  3. Flag --alertas-waypoint e inclusión en --populate.
  4. Incluir las tablas nuevas en supabase_destinations.py.
  5. Power BI: agregar al modelo y crear la relación con dim_calendario.
PuntoDecisión
Grano de la fact1 fila por alerta; dedup por message_id
Vínculo con dim_otNo — alertas no son OT; constelación independiente
dim_vehiculoNueva, por patente; SCD tipo 1 (replace)
Refreshreplace full (volumen bajo)
processed_by_versionSolo 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_
ArchivoCambio
domains/alertas_waypoint/process_alertas_waypoint_from_raw.pySeparar build_df de write_excel; exponer el DataFrame parseado
scripts/db/data_warehouse.pyexport_alertas_waypoint() + flag --alertas-waypoint + en --populate
scripts/db/supabase_destinations.pyIncluir 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
  • 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).
  • Refactor del pipeline para desacoplar DataFrame/Excel.
  • Nueva dim_vehiculo que mantener.
  • Hay que mantener el registro de las tablas en el sync a Supabase.
  • 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.
  • 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 (store opcional, 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