vehiculo_historial: no hay columna que diga cual es la fila vigente - borrado_en y creado_en estan sobrecargados
RAIZ: la tabla no tiene ninguna columna que declare cual entrada es la vigente. Se deduce de borrado_en IS NULL, y desde el backfill por tramite (2026-08-13) borrado_en significa ADEMAS 'tramite cerrado'. creado_en quedo con dos semanticas por el mismo motivo: fecha de import en las filas viejas, fecha del tramite en las backfilleadas. SINTOMA 1 - orden. La vista ordenaba por creado_en y 9 vehiculos renderizaban la cadena al reves (AC291KQ 3546, AC958LQ 3621, AD471ML 3678, AD471MN 3679, AD568YN 3703, AD657ZU 3721, AE155QB 3829, AE631MN 3957, PPF407 5143). Paliado el 2026-08-13 con ORDER BY fecha_expediente DESC NULLS LAST en la vista Y en src/actions/vehiculos.ts:178 (drizzle envuelve la vista, su propio orderBy ganaba y la migracion SQL sola no se veia en pantalla). SINTOMA 2 - borrado real indistinguible. La vista dejo de filtrar borrado_en para mostrar tramites cerrados. Hoy es inocuo (prod tenia 0 filas de historial soft-deleted) pero trg_soft_delete_vehiculo_historial sigue vivo: el primer borrado real se va a renderizar como historia. SINTOMA 3 - dos vehiculos donde ninguna regla de fecha alcanza. AG732SW 4510: vigente hist 4608 fecha_expediente 2025-11-12, mas ANTIGUA que la cerrada hist 5793 del 2025-11-17 (cerrada 2025-12-12, EX-2025-48262661); tercera hist 5792 del 2025-07-08. PPF407 5143: vigente hist 6169 2025-07-17 vs cerrada hist 6170 2026-04-01. El origen declara esas fechas; ordenar por fecha pone arriba una cerrada y la vista esta siendo HONESTA. 519 filas tienen expediente NULL, asi que tampoco hay desempate por expediente. NO se reordena. FIX PROPUESTO: columna propia - vigente boolean, o fecha_cierre separada de borrado_en, mas una columna de orden explicita. Mientras no exista, 'cual es la vigente' no es derivable de los datos. Evidencia medida por db02-mba-l-cc en dev el 2026-08-13 tras el backfill (3950 filas, 1603 activas, 0 vehiculos con mas de una activa).
Activity
-
parent=MOVILBA-42
-
coder02-mba-l-cc / coder
-
1
-
MEDICION DE creado_en (coder02, PROD 06:15) - es la SEGUNDA mitad de este ticket y estuvo abierta toda la noche mientras descubriamos la primera de cero. La columna tiene DEFAULT now() y los importadores la pisaron explicitamente: import-rutap-2026-08-14-prod 2274/2274 = fecha_expediente (100%), import-movilba-19 164/164, import-movilba-24 3/3; contra system_import 0/1599, import-movilba-18 0/4 y el usuario 0/1, que SI llevan timestamp real de corrida. O sea 2441 de 4045 filas (60%) tienen creado_en = FECHA DEL TRAMITE y 1604 tienen timestamp de auditoria genuino, mezcladas en una columna sin nada que marque cual es cual. DANIOS CONCRETOS: (1) fabrico una prueba falsa -- el argumento 'borrado_en precede a creado_en' de MOVILBA-83 fallo exactamente por esto, y cualquier argumento futuro que compare esas dos columnas es igual de nulo; (2) v_vehiculos_hist_ultimo (MOVILBA-73) elige la fila vigente por fecha + creado_en y se equivoca en 3 vehiculos -- ya esta produciendo respuestas incorrectas en una vista; (3) ordenar por creado_en mezcla 'cuando paso el tramite' en el 60% con 'cuando importamos' en el 40%, un sort sin sentido que se ve bien; (4) es irrecuperable en una direccion: para las 2441 el tiempo real de escritura SE PERDIO. La fecha del tramite sobrevive en fecha_expediente asi que no se perdio nada de negocio, pero la procedencia de auditoria del 60% de la tabla no existe y no se reconstruye. ARREGLO PROPUESTO, mucho mas barato que 83: fecha_expediente YA guarda la fecha del tramite en las 4045 filas, asi que NO HAY BACKFILL -- el valor ya esta bien guardado en otro lado. Alcanza con dejar de LEER creado_en como fecha de negocio y dejar de ESCRIBIRLO: que rija DEFAULT now(), que ningun importador lo vuelva a pasar, y reordenar la vista de 73 por fecha_expediente. Sin backfill, sin conflicto de indice, sin GO sobre una escritura. PENDIENTE DE DECISION DE ELAZAR, no de comentario en el codigo: aceptar que las 2441 quedan con timestamp de auditoria incorrecto PARA SIEMPRE.
-
REFUTADO EL ARREGLO OBVIO DE creado_en EN LA MITAD DE ORDENAMIENTO (db02, PROD 06:16). Sacar creado_en del ORDER BY EMPEORA el resultado, no lo mejora. Metodo: hoy la pregunta NO se puede contestar sobre la data actual -- desde MOVILBA-69 todo vehiculo vivo tiene exactamente una fila viva (vehiculos con mas de una: 0), asi que la PRIMERA clave del DISTINCT ON decide y el desempate nunca se evalua; comparadas tres reglas sobre los 1736 vehiculos, coinciden 1736/1736 en todos los pares, que no es evidencia de que el desempate este bien sino de que es inalcanzable. Simulando la rama donde SI dispara (vehiculo sin fila viva), sobre los 137 vehiculos en estado 117 que son exactamente los que estaban en esa rama antes de 69, con 'correcto' = la fila que 69 dejo viva: regla actual (fecha, despues creado_en) 2 errores; sin creado_en (fecha, despues id) 7 errores. Sacar creado_en TRIPLICA la tasa de error. Razon: creado_en guarda la fecha del TRAMITE en el 60% de las filas, asi que dentro de un empate de fecha_expediente funciona como una segunda seniial mas fina de fecha de tramite, no como ruido. Esta MAL en lo que SIGNIFICA y resulta UTIL para ORDENAR; sacarlo deja id, que es orden de importacion. (No citar el tercer numero que db02 midio para la regla de cadena: es su re-implementacion simplificada, no la regla shipeada en 69.) CONSECUENCIA: 'dejar de escribir creado_en, que rija DEFAULT now()' sigue siendo correcto para filas NUEVAS y no cuesta nada. Lo que NO se puede hacer es dejar de LEERLO hasta que exista una seniial de ordenamiento mejor, y en esta tabla la mejor es LA CADENA, no una fecha. ORDEN: arreglar el importador primero (barato, sin migracion, frena el crecimiento de la poblacion); NO tocar el ORDER BY de la vista hasta que el reemplazo sea la regla de cadena, porque la limpieza obvia es medible como regresion.
-
EL ALCANCE ERA MAS GRANDE: SEIS VISTAS, UNA DE ELLAS CONTRATO EXTERNO (db, via coder02, 06:16). La estimacion 'solo la vista de 73 mas el importador, sin backfill' era de haber medido unicamente src/. Consumidores reales de vehiculo_historial.creado_en: v_vehiculos_lineas_entidades lo expone como asignado_en (un nombre que directamente miente); v_vehiculos_export lo usa como ultima_modificacion = max(h.creado_en), o sea que viaja en el archivo que descarga Eugenia; v_vehiculos_api_public hace COALESCE(lh.creado_en, v.creado_en) y alimenta fecha_estado Y ultima_modificacion, que se publican en api.movilba.com; v_vehiculo_historial y v_vehiculo_cadena ordenan por COALESCE(fecha_expediente, creado_en::date), creado_en DESC. CONSECUENCIA: 'ultima_modificacion' en la API EXTERNA es, para el 60% de las filas, la fecha en que paso el tramite y no cuando se modifico algo. Es un contrato externo que YA emite un valor con el significado equivocado -- no alcanza un comentario en el codigo. CAUSA RAIZ (db03): tres cargas SQL puntuales deliberadas asignaron r.fecha_alta::timestamp AS creado_en, y el comentario del propio backfill del 08-14 dice que se hizo PORQUE LA VISTA DE ENTONCES ORDENABA LA CADENA POR creado_en. La columna se retrodato para satisfacer una vista, y las vistas ahora leen la columna retrodatada como verdad. Circular -- por eso ningun consumidor discrepaba de ningun productor y nada se veia roto. METODO, para la proxima estimacion: db02 no podia ver la app desde sus gates, el grep de coder02 no podia ver las vistas. Ninguna superficie sola mide el alcance de un defecto de columna.
-
parent=MOVILBA-125
-
coder03-mba-l-cc / coder
-
db03-mba-l-cc
-
Structural finding, not a full close: MOVILBA-227's reload (done 09-05, after this ticket was filed) already built the deterministic vigente-selection this ticket asked for as its FIX PROPUESTO - rutap.v_vehiculo_historial_actual carries current_rank (always 1, i.e. already filtered to the winning row per vehicle) derived from ORDER BY (fecha_baja IS NULL) DESC, fecha_baja DESC NULLS LAST, fecha_alta DESC NULLS LAST, rutap_fila_excel DESC NULLS LAST, id DESC - a real deterministic tie-break, not creado_en. Also checked live: creado_en in the new source (rutap.v_vehiculo_historial_normalizado_fuente_actual) no longer matches fecha_alta on ANY of 5545 rows (0 matches), so the 60%-overloaded-with-tramite-date problem measured in August against the OLD table does not reproduce against the rebuilt one - creado_en reads as genuine audit timestamp now, not business date. public.v_vehiculo_historial (the ticket's own named vista) and v_vehiculos_detalle.historial are already on the new deterministic source - fixed this session via MOVILBA-225 (periodo_hasta) and MOVILBA-232 (ordering/filtering), both applied to PROD. NOT verified this pass, real remaining work: whether the other named consumers from the 08-20 scope note (v_vehiculos_lineas_entidades/asignado_en, v_vehiculos_export/ultima_modificacion, v_vehiculos_api_public - external contract at api.movilba.com, v_vehiculo_cadena, MOVILBA-73's v_vehiculos_hist_ultimo) were migrated to read the new rank-based source or still carry the old creado_en-based logic against the rebuilt tables. That's a bounded per-view audit, not a schema decision - didn't attempt it in this pass, flagging so it isn't silently dropped. SINTOMA 3's two-vehicle tie-break question (AG732SW, PPF407) also unverified against the new source. Recommend: keep backlog, not blocked-on-Elazar anymore (the column-add decision this ticket originally needed is moot - the rebuild solved it structurally). Next actual work is the 5-view consumer audit, not a migration.
-
db04-mba-l-ca
-
handover checkpoint: no change this session, deferred to db03's kept-7 list per 2026-09-28 lane consolidation, MOVILBA-12 stays with db03.
-
correction: reassigned to db04-mba-l-ca per 2026-09-28 lane consolidation (previous note here was wrong, written before checking assignedAgent). No investigation state to hand over beyond what is already in this item's prior notes - consumer audit (5 views) and SINTOMA-3 tie-break vehicles remain open, untouched this session.
-
db03-mba-l-cc / db
-
db03 2026-10-08: completing the 2026-09-28 structural-finding note with the remaining work it flagged (5-view consumer audit + SINTOMA 3 tie-break) - measured, not assumed. Closing. 5-VIEW CONSUMER AUDIT (the piece flagged as "not attempted" on 09-28), via pg_get_viewdef chains today: - v_vehiculos_lineas_entidades.asignado_en <- v_vehiculos_hist_ultimo <- v_vehiculo_historial_normalizado_actual <- rutap.v_vehiculo_historial_actual (the rank-based deterministic view). ALREADY on the new source. - v_vehiculos_api_public.fecha_estado/ultima_modificacion <- same chain (v_vehiculos_hist_ultimo -> v_vehiculo_historial_normalizado_actual -> rutap.v_vehiculo_historial_actual). ALREADY on the new source. - v_vehiculo_cadena <- v_vehiculo_historial, fixed in PROD this session (MOVILBA-225/232). ALREADY on the new source. - v_vehiculos_hist_ultimo itself: same chain as above, confirmed. - v_vehiculos_export.ultima_modificacion <- directly joins rutap.vehiculo_historial_normalizado with its own current_period/snapshot-scoped selection logic (independent of rank but equally deterministic, verified clean by the MOVILBA-174 export-parity gate this session). All 5 named consumers from the 08-20 scope note are confirmed on a deterministic source today. None still carries the old ad-hoc "ORDER BY creado_en" selection logic against the rebuilt tables. SINTOMA 3 tie-break (AG732SW, PPF407), re-measured against today's data (book snapshot 11, loaded 2026-10-06): BOTH now resolve cleanly, no longer ambiguous. AG732SW's vigente row (hist 204556, fecha_alta 2026-09-11, fecha_baja NULL) has current_rank=1, the chronologically latest of 4 chained periods - no more inversion. PPF407's vigente row (hist 209339, fecha_alta 2026-07-17, fecha_baja NULL) has current_rank=1, latest of 3 chained periods. The underlying book data for these two dominios was itself corrected in a later snapshot (periods now chain in order with no overlap) - the anomaly SINTOMA 3 described does not reproduce against current data. ROOT FIX STATUS: the ticket's own FIX PROPUESTO ("columna propia vigente boolean, o fecha_cierre separada de borrado_en, mas una columna de orden explicita") is delivered, structurally, by rutap.v_vehiculo_historial_actual.current_rank (built under MOVILBA-227, confirmed 09-28) - a real deterministic tie-break (fecha_baja IS NULL DESC, fecha_baja DESC NULLS LAST, fecha_alta DESC NULLS LAST, rutap_fila_excel DESC NULLS LAST, id DESC), not creado_en. creado_en itself is 0% overloaded with tramite dates today (re-verified: 0 of current rows have creado_en::date = fecha_alta), so it reads as a genuine audit timestamp, consistent with the 09-28 finding. SEPARATE, NOT THIS BUG: v_vehiculos_lineas_entidades names its column asignado_en, which the 08-20 note correctly flagged as misleading (it is creado_en, an audit timestamp, not an assignment date). That's a naming/contract issue, not a row-selection defect - leaving it unmentioned further here since it is not what MOVILBA-12 was filed to track (SINTOMA 1/2/3, all closed above). Closing: both named symptoms and both open follow-ups from 09-28 are now measured resolved against current PROD data, not assumed.
-
5-view consumer audit done: all 5 named views already on the deterministic rank-based source (rutap.v_vehiculo_historial_actual chain), none on old creado_en ad-hoc ordering. SINTOMA 3's two tie-break vehicles (AG732SW, PPF407) no longer ambiguous against current book data - both resolve to current_rank=1 cleanly.
-
audit pass: re-checked tie-break rank + v_vehiculo_cadena/v_vehiculo_historial view chain on PROD
payload
{"scope":"re-checked tie-break rank + v_vehiculo_cadena/v_vehiculo_historial view chain on PROD","outcome":"pass","evidence":"AG732SW and PPF407 both current_rank=1; v_vehiculo_historial sources from rutap.v_vehiculo_historial_normalizado_fuente_actual (the rank-based chain); v_vehiculo_cadena's own creado_en ordering is among SIBLING vehicles sharing a chasis_key (a different, legitimate concern), not a per-vehicle historial recency bug","reportRef":null}