MOVILBA-34 parte 2: llevar expediente_baja a PROD (DDL + vista) y backfillear 2440 filas cerradas desde RUTAP
vehiculo_historial tiene UNA sola columna 'expediente' y guarda ahi el expte de ALTA del tramite; el expte de BAJA no tiene donde ir y se pierde. Ya hay ~2440 filas cerradas en PROD sin su expte de baja (2274 del backfill 08-14, 2 de MOVILBA-24, 164 de MOVILBA-19). Fix en 3 partes: (1) DDL agregar columna expediente_baja a vehiculo_historial (la actual queda como expediente de alta); (2) backfill de las filas cerradas desde rutap.v_rutap_latest.expte_baja, matcheando por dominio+fecha_alta; (3) UI: mostrar el expte de baja en la tarjeta Historial del Vehiculo (/vehiculos/[id]) y en el export si corresponde. Jira MOVILBA-34. Reglas de lane: WRITE LOCK + GO de Elazar antes de tocar prod, ensayo apply=false completo del ejecutor, gates por DELTA intra-transaccion (los absolutos vencen con commits vecinos).
Questions
Activity
-
MOVILBA-34 parte 2: llevar expediente_baja a PROD (DDL + vista) y backfillear 2440 filas cerradas desde RUTAP
-
CORRECCION: la parte de codigo YA ESTA HECHA por coder-mba-l-cc en dev (commit 092bf778, v5.3.196): DDL expediente_baja en dev, vista, UI historial, PDF, export. Lo que queda es SOLO prod: (1) DDL identico en prod (columna no existe alli, verificado con \d), (2) deploy del codigo a prod, (3) backfill de las 2440 filas cerradas desde rutap.v_rutap_latest.expte_baja. Cobertura medida hoy en prod: 2440 cerradas, 0 sin match por dominio+fecha_alta, 2418 con match unico (139 de esas traen expte_baja NULL en el libro, quedan NULL), 22 con match MULTIPLE que necesitan regla de desempate explicita. Gates por DELTA intra-tx; el backfill es UPDATE, asi que el gate es 'filas con expediente_baja NOT NULL pasa de 0 a N'.
-
PLAN CERRADO 08-14. Tiebreak (db03, adoptado): colapsar un multi-match SOLO si todos los candidatos comparten el mismo expte_baja normalizado (o todos NULL); si no, EXCLUIR y reportar id + todos los candidatos. Medido en prod con normalizacion (nbsp->espacio, whitespace colapsado): de los 22 multi, 10 colapsan y 12 se excluyen. Set a actualizar = 2418 single + 10 = 2428 candidatos, menos los 139 con fuente NULL. Gates (db03, adoptados): derivar de la relacion target final (una fila por historial_id), N = count(target con expte_baja NOT NULL); UPDATE solo ids con destino NULL, RETURNING id, exigir devueltas = N; post: expediente_baja NOT NULL = N, total de filas de vehiculo_historial SIN CAMBIO, y assert de que los 139 siguen NULL; las 12 exclusiones son reporte ASERTADO, no skip silencioso. fecha_alta del snapshot actual es ISO, parsear defensivo. Implementa db02-mba-l-cc.
-
db02-mba-l-cc / db
-
Plan cerrado y auditado; pasa a db02 para implementar.
-
TIEBREAK FINAL (medido, no elegido): escalera de 3 pasos. (1) expte_baja normalizado identico entre candidatos -> colapsa: resuelve 10 de 22 (regla db03). (2) de los 12 restantes, la fila del libro cuya fecha_baja = vdc.fecha_vigencia_hasta del vehiculo: resuelve 10, match unico, 0 ambiguos (regla coder). (3) los 2 sin match de fecha_vigencia_hasta se EXCLUYEN y se reportan con todos sus candidatos. Total: 2418 single + 10 + 10 = 2438 candidatos, menos 139 con fuente NULL, y 2 exclusiones asertadas. SECUENCIA VINCULANTE: (a) DDL prod primero - archivo de coder docs/migrations/2026-08-14-movilba-34-expediente-baja.sql (columna + v_vehiculo_historial con expediente_baja + GRANT condicional + gate de filas), mas docs/migrations/2026-08-14-export-excluye-bajas.sql; (b) deploy de codigo a prod, de coder, DESPUES de los dos DDL (drizzle ya selecciona expediente_baja de la vista: deployar antes tira 500 en el historial); (c) recien ahi el backfill de db02.
-
CLAVE FINAL (propuesta db02, re-medida y confirmada por coder02 por separado - la escalera de 3 reglas queda DESCARTADA): dominio normalizado + rutap.fecha_alta = vh.fecha_expediente + rutap.fecha_baja = vh.borrado_en::date. Medicion independiente identica: 2440 cerradas, 2438 single, 0 sin match, 2 multi, 0 conflictos reales de valor, 147 con fuente NULL. Los 22/12 'conflictos' anteriores eran artefacto de una clave incompleta: fecha_vigencia_hasta es UNA por vehiculo (solo desambigua el ultimo periodo), borrado_en es por FILA de historial (desambigua todos). Los 2 residuales (7394/7400, AD956UK) caen en la regla 1 de db03: un solo valor no nulo -> colapsan. El reporte de exclusiones queda con conteo esperado 0 y ese cero es el gate. Cruce contra 'expediente de la fila siguiente de la cadena' (1851 si / 238 no / 204 sin sucesor) es INFORMATIVO, nunca gate: un periodo puede cerrar sin abrir otro.
-
NUMEROS CORREGIDOS por db02 (medidos, reemplazan los mios): N a escribir = 2293, no 2438 - 2438 era el count de filas con MATCH, de las cuales 2293 traen expediente y 147 lo traen NULL/vacio (2293+147=2440). Las que quedan NULL son 147, no 139: el 139 salia de la clave de 2 campos. WHITESPACE: normalizar SOLO para comparar y escribir el btrim crudo - 928 expedientes tienen espacios internos multiples REALES y colapsarlos reescribiria 928 valores en silencio; 0 necesitan trim, 0 CR/LF, 0 NBSP, largo max 68. Sin efectos laterales: vehiculo_historial tiene UN trigger y es de DELETE, no hay trigger de UPDATE ni tabla _archive. ORDEN DECIDIDO (camino a): DDL de coder en prod con su GO -> recien ahi db02 corre el ensayo apply=false COMPLETO contra la columna real -> write lock + GO del backfill -> deploy de codigo. Se RECHAZA ensayar simulando el DDL en una transaccion con rollback: toma ACCESS EXCLUSIVE sobre vehiculo_historial en prod en horario habil y no aporta informacion que no se tenga gratis diez minutos despues. Archivo: docs/migrations/2026-08-14-movilba-36-backfill-expediente-baja-PROD.sql
-
COMMITEADO EN PROD 08-14 con GO. Secuencia completa: DDL de coder (expediente_baja varchar(110) + v_vehiculo_historial + v_vehiculos_export sin Bajas) -> code deploy main 18b8b61a v5.3.198 -> backfill de db02, 2293 filas escritas. Output real = ensayo: 0 excepciones, censo 2440/0 sin match/2293 con expediente/147 sin, delta no nulos 2293, total de tabla 4045 SIN CAMBIO. Verificado como svc_nextjs: 0 filas abiertas tocadas, las 147 siguen NULL, la vista sirve las 2293. Las 147 sin expediente en RUTAP quedan asi hasta que Eugenia las complete: no es hueco de la app. Clave final: dominio + fecha_alta=fecha_expediente + fecha_baja=borrado_en::date (la escalera de tiebreaks se descarto por innecesaria).