ADR-0005 · Schema v2 caja: todas las raw son históricas

ADR-0005 · Schema v2 caja: todas las raw son históricas

  • Status: ✅ Accepted (Mayo 2026)
  • Fecha: 2026-05-21
  • Supersedes: Schema v1 (Marzo–Abril 2026)
  • Tags: caja · bd · v2

Contexto

En el schema v1 de caja:

  • caja_raw_egresos_caja se trataba como catálogo (TRUNCATE per sync).
  • Las otras caja_raw_* eran históricas por sync_id.

Problema: Tesorería leía caja_raw_egresos_caja para mostrar saldo de caja e ingresos/egresos por mes. Como se truncaba en cada sync, sólo mostraba el último mes.

Decisión

En v2 (Mayo 2026):

  • TODAS las raw son históricas por sync_id (incluso egresos_caja).
  • Todas tienen creado_at TIMESTAMP para auditoría.
  • Nueva caja_cajeros: mapa denormalizado empresa·caja_nro·cajero·provincia reconstruido auto post-sync.
  • Nueva caja_audit_log: registra cada evento (sync_started, raw_batch, gastos_batch, sync_completed).
  • caja_sincronizaciones agregó finalizado_at.
  • caja_raw_conceptos agregó last_sync_id (catálogo persistente que recuerda de qué sync vino).

Migración

Los ALTER TABLE defensivos en caja_ensure_schema() migran el schema automáticamente al primer hit:

-- caja/api/_schema.php
foreach (['sync_id INT AFTER id',
          'mes TINYINT AFTER sync_id',
          'anio SMALLINT AFTER mes',
          'creado_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP'] as $col) {
    try { $pdo->exec("ALTER TABLE caja_raw_egresos_caja ADD COLUMN $col"); }
    catch (Exception $e) { /* ya existe */ }
}

-- Limpia filas legacy sin sync_id
DELETE FROM caja_raw_egresos_caja WHERE sync_id IS NULL;

Consecuencias

✅ Tesorería ahora muestra histórico real (todos los meses cargados). ✅ Cashflow puede leer saldo de cualquier mes. ✅ Auditoría completa via caja_audit_log. ✅ Performance OK con índice compuesto (mes, anio). ⚠️ Después de migrar, hay que re-sincronizar los meses anteriores que se perdieron en la TRUNCATE.

Referencias