ADR — Migración de METAS MES (costos) a Data Warehouse (.db)
Implementada/Aceptada (2026-06-08, commit 64febc8). Propuesta original 2026-06-07;
implementada mediante el change SDD costos-metas-a-dw (archivado en
openspec/changes/archive/2026-06-08-costos-metas-a-dw/). Verificación PASS-WITH-WARNINGS
(0 bloqueantes).
Contexto
Sección titulada «Contexto»Situación actual de METAS MES en la planilla
Sección titulada «Situación actual de METAS MES en la planilla»Las hojas METAS MES0 y METAS MES de la planilla de costos no contienen cálculos propios: son artefactos de reshape y acumulación manual que existen por una limitación del modelo de la hoja.
METAS MES0 es un transpose puro. Fórmulas:
=TRANSPONER('COSTOS OSORNO'!D49:P49) → columna id_Brigada=TRANSPONER('COSTOS OSORNO'!D44:P44) → columna HB Día EsperadoLa planilla organiza las 13 brigadas de Osorno como columnas (D:P) en la hoja COSTOS OSORNO. TRANSPONER las convierte en filas para producir una tabla [id_Brigada, HB Día Esperado] correspondiente al mes activo del selector (fila 52).
METAS MES = apilado vertical de METAS MES0 de distintos meses. El operador cambia el selector al mes deseado, copia METAS MES0 y pega los valores al final de METAS MES. Existe solo porque la planilla calcula un mes a la vez: para tener la serie histórica hay que repetir este proceso manualmente mes a mes.
Contraste con la lógica pesada
Sección titulada «Contraste con la lógica pesada»Mientras que METAS MES/MES0 son artefactos manuales frágiles, la lógica de costos pesada ya vive en Python:
- El pipeline
business_costos.pycomputa toda la lógica por brigada-mes de forma autónoma (SCD en memoria, cross-join vectorizado, sentinels YAML, rentabilidad, divisor 20 días). ResultadoCostos.costo_por_hhya contiene la información equivalente a METAS MES en formato largo(zonal, id_Brigada, mes), cubriendo todos los meses de una corrida en un solo paso.- Hoy persiste solo a Excel y GSheets; no escribe a ningún
.dby no está en PIPELINES_V2.
El objetivo de esta ADR es llevar costo_por_hh al Data Warehouse y hacer que METAS MES sea una vista SQL, eliminando el proceso manual de la planilla.
Opciones evaluadas
Sección titulada «Opciones evaluadas»Opción A — Mantener METAS MES en la planilla (status quo)
Sección titulada «Opción A — Mantener METAS MES en la planilla (status quo)»Seguir acumulando manualmente mes a mes con el selector + copiar-pegar.
Descartada: frágil (error humano, olvido); no es reproducible; no integra con el DW; no escala a más zonales.
Opción B — Volcar costo_por_hh directamente a fact_costos_hh (ELEGIDA)
Sección titulada «Opción B — Volcar costo_por_hh directamente a fact_costos_hh (ELEGIDA)»df.to_sql("fact_costos_hh", ...) desde el resultado ya computado por el pipeline. METAS MES pasa a ser un SELECT.
Elegida porque: no requiere lógica nueva (el cálculo ya existe); grano natural del dataframe; idempotente (replace + key); METAS MES se convierte en vista trivial; integra con el epílogo --migrate del orquestador (ADR-Data-Warehouse-Epilogue).
Opción C — Tabla intermedia fact_costos_metas separada
Sección titulada «Opción C — Tabla intermedia fact_costos_metas separada»Crear una tabla con solo [mes, zonal, id_Brigada, hb_dia_total] en lugar de la tabla completa.
Descartada: duplica información que ya está en fact_costos_hh; pierde el contexto de costos completo; complica el linaje.
Decisión
Sección titulada «Decisión»Opción B. Se crea fact_costos_hh como volcado directo de costo_por_hh (grano: zonal, id_Brigada, mes). Las hojas METAS MES / METAS MES0 desaparecen como artefactos independientes: METAS MES pasa a ser la vista/SELECT:
SELECT mes, zonal, id_Brigada, hb_dia_totalFROM fact_costos_hh;Esquema fact_costos_hh
Sección titulada «Esquema fact_costos_hh»| Campo | Tipo SQLite | Origen | Nota |
|---|---|---|---|
zonal | TEXT | pipeline | ”OSORNO” / “CHILOE” |
id_Brigada | TEXT | fila 49 | Pregunta abierta: TEXT (BBPP-OS-01) vs INTEGER (1-13) |
mes | TEXT (YYYY-MM-01) | ciclo de corrida | Primer día del mes como string ISO |
subtotal_personal | INTEGER | detalle agregado | — |
subtotal_flota | INTEGER | detalle agregado | — |
subtotal_gastos_grales | INTEGER | detalle agregado | — |
total_sin_vehiculos | INTEGER | fila 37 | — |
total_valor_brigada | INTEGER | fila 38 | CON vehículos |
rentabilidad | REAL | fila 39 | Factor (ej. 0.08 = 8 %) |
total_sin_vhc_utilidad | INTEGER | fila 40 | — |
total_costos_utilidad | INTEGER | fila 41 | ”META ZONAL” |
hh_disponibles | REAL | cálculo interno | — |
hb_mensual | REAL | fila 47 | CON vehículos |
hb_dia_total | REAL | fila 44 | Ex hb_dia_esperado — MANT. CORRECTIVO, CON vehículos |
hb_mensual_sv | REAL | fila 47 | SIN vehículos |
hb_dia_prod | REAL | fila 48 | Ex hb_dia_esperado_sv — PROGRAMACIÓN, SIN vehículos |
Alternativa opcional: fact_costos_detalle con grano brigada × mes × ítem (el nivel detalle de ResultadoCostos). Útil para auditoría; no bloquea la decisión principal.
Decisión de nomenclatura
Sección titulada «Decisión de nomenclatura»Se renombran dos campos en toda la capa Python y DW:
| Nombre actual | Nombre nuevo | Criterio |
|---|---|---|
hb_dia_esperado | hb_dia_total | Nombre por criterio consistente: “total” = CON vehículos (MANT. CORRECTIVO) |
hb_dia_esperado_sv | hb_dia_prod | ”prod” = productividad/programación, SIN vehículos |
El par hb_dia_total / hb_dia_prod es corto, simétrico y semánticamente claro.
Archivos afectados por el rename:
domains/costos/costos_schema.pydomains/costos/business_costos.pydomains/costos/excel_writer_costos.pydomains/costos/ACTUALIZAR_COSTOS.py
Consecuencias
Sección titulada «Consecuencias»Positivas
Sección titulada «Positivas»- METAS MES deja de ser un proceso manual; pasa a ser una vista SQL reproducible.
fact_costos_hhintegra con el epílogo--migratedel orquestador: un solorun_pipeline.py --all --migrateactualiza el DW y Supabase.- Nomenclatura más clara y consistente para consumidores (Power BI, futuros análisis).
- Cobertura histórica sin límite: la corrida calcula todos los meses del rango de una vez.
Negativas
Sección titulada «Negativas»- El rename requiere tocar 4 archivos Python y actualizar Power BI (campos calculados que referencien los nombres viejos).
- Las hojas COSTOS / METAS de la planilla quedan deprecadas; hay que coordinar con el equipo el momento del corte.
Neutras
Sección titulada «Neutras»- La planilla de Google Sheets puede seguir funcionando en paralelo durante la transición (no se elimina hasta que el DW esté validado).
Estado de implementación (2026-06-08, commit 64febc8)
Sección titulada «Estado de implementación (2026-06-08, commit 64febc8)»| Item | Estado | Nota |
|---|---|---|
export_costos() en data_warehouse.py invocada desde populate() | ✅ Implementado | Integración por populate(), NO por PIPELINES_V2 (costos no es BasePipeline) |
fact_costos_hh en data_warehouse.db | ✅ Implementado | Grano (zonal, id_Brigada, mes), 16 cols, replace+guard |
Vista metas_mes | ✅ Implementado | DROP+CREATE en cada export_costos() |
Mapping Supabase (MAPPINGS_DATA_WAREHOUSE) | ✅ Implementado | migrate_config.py actualizado |
Rename hb_dia_esperado/sv → hb_dia_total/prod | ✅ Implementado | BREAKING CHANGE — ver nota de migración |
| Relaciones en Power BI | ⏳ Pendiente | Configuración manual del modelo PBI fuera de scope |
| Deprecar hojas COSTOS / METAS en GSheets | ⏳ Pendiente | Post-validación del DW con datos reales |
Nota de integración: El pipeline costos NO es un
BasePipeline(no consume correos IMAP). La integración al DW se hace directamente enpopulate()dedata_warehouse.py, siguiendo el patrón deexport_presupuesto_inicial()yexport_dim_ot(). No se registra en PIPELINES_V2.
Preguntas abiertas
Sección titulada «Preguntas abiertas»| Pregunta | Opciones | Impacto |
|---|---|---|
id_Brigada: ¿TEXT o INTEGER? | TEXT (BBPP-OS-01) vs INTEGER (1-13) | Joins con dim_brigada, compatibilidad con planilla |
¿Incluir fact_costos_detalle? | Sí (grano ítem) / No (solo fact_costos_hh) | Tamaño del DW, utilidad para auditoría |
| ¿El rename aplica solo a capa .db o también a nombres internos de Python? | Solo DW (alias en to_sql) vs rename total | Riesgo de inconsistencia entre capas |
Ver también
Sección titulada «Ver también»- Pipeline-Costos — MOC del pipeline (implementación actual verificada y contexto completo)
- ADR-Data-Warehouse-Epilogue — epílogo
--migratedel orquestador; contexto de integración DW - Indice-ADRs — registro de decisiones