basquetWi + New ticket
movilba MOVILBA-83 · child of MOVILBA-125 RUTAP full-history refactor Backlog

vehiculo_historial.borrado_en esta sobrecargado: guarda la Fecha Baja del libro, no un borrado - hoy solo borrado_por distingue quien lo escribio, y esa columna tiene FK a users

Done high dmdb04-mba-l-ca

vehiculo_historial.borrado_en NO significa borrado: guarda la Fecha Baja de RUTAP como dato. Medido en PROD 2026-08-20 06:08-06:10 -- 2309 filas con borrado_en NOT NULL, TODAS sobre vehiculos vivos, 1293 vehiculos, 57% de las 4045 filas que la ficha renderiza. Rango 2025-07-08 a 2026-08-12, TODO anterior a MOVILBA-69: 69 no creo ninguna. borrado_por es NULL en las 2309 sin excepcion. PRUEBA (ojo, la primera version era falsa): NO sirve el argumento del timestamp imposible -- filas con borrado_en anterior a creado_en = CERO, el importador retrodato creado_en tambien. La prueba VALIDA es externa: cruzando por (dominio, expediente) normalizado contra el libro, 1978 matchean y borrado_en es IGUAL a la Fecha Baja en 1908 = 96% (66 difieren, 4 sin Fecha Baja). Citar el 96%, nunca el orden de timestamps. LA VISTA ESTA BIEN HOY, por accidente de la sobrecarga: dropear la pata vh.borrado_en IS NULL el 08-13 era la unica forma de mostrar tramites cerrados, porque la fecha de cierre estaba cargada en la columna de borrado. NO RE-AGREGAR ESE FILTRO -- ocultaria 2309 tramites cerrados legitimos de 1293 vehiculos. LA EXPOSICION REAL es la inversa y es silenciosa: un soft-delete GENUINO de una fila de historial es INVISIBLE, se renderiza igual que un tramite cerrado; el unico discriminador es borrado_por, que la vista no selecciona y la ficha no muestra. Hoy limpio (2309 NULL / 0 no-NULL) asi que nada esta mal etiquetado; el primer borrado real lo rompe SIN MOVER NINGUN CONTEO, o sea que ninguna medicion de filas lo detecta. ARREGLO: 76 agrega fecha_baja para exactamente este dato. Backfill de borrado_en a fecha_baja + limpiar borrado_en. SON DOS POBLACIONES, NO UN UPDATE: las 2309 se mueven sin mirar la fuente (interno, reversible); las 131 que MOVILBA-69 ya limpio tienen su valor SOLO en el libro y necesitan el join contra RUTAP (recuperable al 100%: 137 de 137 filas vivas sobre vehiculos en estado 117 tienen Fecha Baja en el libro). BLOQUEADO POR LA BIFURCACION DE 42: el backfill no puede correr mientras exista uq_vehiculo_historial_activo (WHERE borrado_en IS NULL) -- al limpiar la columna las 2309 entran al alcance del indice y aborta en el primer duplicado. Ver tambien MOVILBA-73: su monitor usa borrado_en como liveness y no va a prod antes de este backfill. Memoria: reference_borrado_en_holds_rutap_fecha_baja_not_a_deletion.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 2026-08-20
  • wi-cli-venus commented · 2026-08-20
    REENCUADRADO 2026-08-20 06:08 por medicion de coder02 contra PROD (svc_nextjs, SELECT). La premisa original del ticket era ERRONEA en las dos puntas. NO son 131 filas y NO las introdujo MOVILBA-69. Medido: 2309 filas de vehiculo_historial con borrado_en NOT NULL, TODAS sobre vehiculos vivos, en 1293 vehiculos, o sea 57% de las 4045 filas que la vista expone hoy. El rango de fechas va de 2025-07-08 a 2026-08-12, todo ANTERIOR a 69. La prueba de que no son borrados: borrado_por es NULL en las 2309 SIN EXCEPCION, y creado_por es un importador (import-rutap-2026-08-14-prod 2272, import-movilba-19 33, import-movilba-24 2, system_import 2) que corrio el 08-14 escribiendo filas con borrado_en del 07-08 al 08-12 -- una fecha de borrado NO PUEDE preceder a la creacion de su propia fila. Conclusion: borrado_en NO lo escribio un borrado, lo escribio el importador COMO DATO. Es la Fecha Baja de RUTAP guardada en la columna de soft-delete. CONSECUENCIA, y es la inversa de lo que decia el ticket: la vista esta BIEN hoy, por accidente de esa sobrecarga -- dropear la pata vh.borrado_en IS NULL el 08-13 era la unica forma de mostrar tramites cerrados, porque la fecha de cierre estaba cargada en la columna de borrado. La exposicion real es peor y es silenciosa: un soft-delete GENUINO de una fila de historial es INVISIBLE, se renderiza igual que un tramite cerrado, y lo unico que los distingue es borrado_por, que la vista no selecciona y la ficha no muestra. Hoy el discriminador esta limpio (2309 NULL, cero no-NULL) asi que nada esta mal etiquetado; el primer borrado real lo rompe sin cambiar ningun conteo, o sea que ninguna medicion lo detecta. ARREGLO PROPUESTO (no parte de 76, ticket aparte): 76 ya agrega fecha_baja a esta tabla para exactamente este dato. Backfill de las 2309 de borrado_en a fecha_baja y limpiar borrado_en -- reversible, medible, y retira la sobrecarga en vez de documentarla. HASTA ENTONCES: nadie lee borrado_en de vehiculo_historial como liveness y ningun gate lo usa con el significado de borrado. NO re-agregar el filtro de la vista: volveria a ocultar los tramites cerrados que el 08-13 quiso mostrar.
  • wi-cli-venus statusChanged · 2026-08-20
    Premisa reencuadrada: no es un bug de display de 131 filas, es una sobrecarga de borrado_en sobre 2309 filas. Arreglo = backfill a fecha_baja (que 76 introduce).
  • wi-cli-venus titleChanged · 2026-08-20
    vehiculo_historial.borrado_en esta sobrecargado: 2309 filas guardan la Fecha Baja de RUTAP, no un borrado - un soft-delete real seria invisible
  • wi-cli-venus commented · 2026-08-20
    CORRECCION DE LA PRUEBA + POBLACION NUEVA (db02, PROD 06:09). (1) El argumento del timestamp imposible NO SE SOSTIENE: filas con borrado_en anterior a creado_en = CERO. El importador retrodato creado_en tambien (2025-07-08 a 2026-08-10), asi que ambas columnas son dato y ninguna precede a la otra. La conclusion sobrevive por OTRA medicion: cruzando por (dominio, expediente) normalizado, 1978 matchean y borrado_en es IGUAL a la Fecha Baja del libro en 1908 = 96% (66 difieren, 4 sin Fecha Baja en el libro). Citar el 96%, NUNCA el orden de timestamps. (2) MOVILBA-69 (ya en prod) limpio este dato en 131 filas al poner borrado_en=NULL, sin saberlo -- la sobrecarga se descubrio 20 min despues. 69 NO estuvo mal: esos 131 vehiculos tenian cero filas vivas, rompia ficha y export, lo encontro Eugenia. Recuperable al 100%: de las 137 filas vivas sobre vehiculos en estado 117, 137 de 137 tienen Fecha Baja en el libro. (3) EL BACKFILL SON DOS POBLACIONES Y NO UN SOLO UPDATE: las 2309 se mueven de borrado_en a fecha_baja sin mirar la fuente (interno, reversible); las 137 tienen su valor SOLO en el libro y necesitan el join contra RUTAP. Quien escriba la migracion no las trate como una sola.
  • wi-cli-venus blocked · 2026-08-20
    BLOQUEADO POR LA BIFURCACION DE MOVILBA-42 (coder02, 06:09). El backfill NO PUEDE CORRER mientras exista uq_vehiculo_historial_activo en su forma actual: el indice unico parcial es WHERE borrado_en IS NULL, o sea que hoy las 2309 filas cerradas estan FUERA de su alcance justamente por la sobrecarga. Al limpiar borrado_en entran todas al alcance del indice, y los 1293 vehiculos que hoy tienen una fila viva pasan a tener varias -- el backfill aborta en el primer duplicado. Consecuencia de orden: 42 se decide ANTES que 83, no en paralelo. Y es el argumento mas limpio hasta ahora a favor del lado append-only de 42: el indice de una-sola-fila-viva es LA RAZON por la que una fecha de cierre termino lavandose a traves de una columna de borrado.
  • wi-cli-venus descriptionChanged · 2026-08-20
    was: reference_v_vehiculo_historial_live_def (sin indexar) registra que el 2026-08-13 se DROPEO a proposito la pata WHERE vh.borrado_en IS NULL de v_vehiculo_historial, para mostrar tramites cerrados. La pata JOIN vehiculos v ... AND v.borrado_en IS NULL se conserva. Era seguro cuando se shipeo PORQUE PROD TENIA CERO filas soft-deleted en vehiculo_historial. MOVILBA-69 acaba de crear 131 (aplicado en prod la noche del 08-19/20). Efecto: borrado_en quedo sobrecargado con dos significados -- 'tramite cerrado' y 'fila borrada' -- y la vista no puede distinguirlos, asi que las 131 filas realmente borradas se muestran en la ficha del vehiculo como si fueran historial legitimo. Es la forma madre de la noche (un identificador, dos significados) en una columna de control. VERIFICAR PRIMERO en prod cuantas de las 131 son visibles hoy en la ficha antes de decidir el arreglo -- puede que el JOIN a vehiculos las tape si el vehiculo tambien esta borrado. Arreglo probable: separar los dos significados en columnas distintas, no re-agregar el filtro (eso volveria a ocultar los tramites cerrados que el 08-13 quiso mostrar). Detectado por db02-mba-l-cc 06:06 del 08-20.
  • wi-cli-venus parentChanged · 2026-08-20
    parent=MOVILBA-12
  • wi-cli-venus commented · 2026-08-20
    PRECONDICION QUE 83 HEREDA DE MOVILBA-42, medida el 2026-08-20 por db03-mba-l-ca y confirmada por db02-mba-l-cc en prod, read-only. **83 tiene que MOVER la fecha, nunca solamente limpiar la columna.** O sea: setear `fecha_baja` desde `borrado_en` y recien despues limpiar `borrado_en`, en la misma sentencia. Nunca limpiar `borrado_en` en una fila donde no se pueda setear `fecha_baja`. POR QUE, y es concreto: 42 va a crear un indice unico parcial con predicado `fecha_baja IS NULL AND borrado_en IS NULL`. Hay 8 filas (ids 8222, 8244, 8247, 8933, 8934, 8965, 8972, 9028 - dominios AD919PL, AE922FX, AE971FE, AE971FF) que tienen `borrado_en` cargado y `fecha_baja` NULL. Para las 8, `borrado_en` es igual a una Fecha Baja que RUTAP tiene para ese vehiculo, emparejada por fecha: son la misma sobrecarga que las otras 2301, no bajas reales. Son 2309 de 2309. - Si 83 mueve la fecha: esas 8 quedan excluidas del indice por la pata `fecha_baja` -> 1599 filas, 0 colisiones. El indice sobrevive. - Si 83 solo limpia `borrado_en`: pierden su unica marca de cierre, quedan abiertas por las dos patas, entran al indice -> 4 vehiculos con varias filas abiertas y 1 colision real (el par 8933/8934 de AD919PL, identico en toda la clave). **El CREATE INDEX ya existente las rechaza y 83 aborta en la primera sentencia.** Las dos variantes se ven igual desde afuera: "83 hecho". Por eso esto va como TEST DE ACEPTACION de 83, no como confianza en quien lo implemente: despues del backfill, `SELECT count(*) FROM vehiculo_historial WHERE fecha_baja IS NULL AND borrado_en IS NULL` tiene que seguir dando 1599 y cero vehiculos con mas de una fila. Si sube, el backfill limpio sin llevar. OJO CON LA CIFRA DE 1293: la proyeccion "1293 de 1736 vehiculos quedarian con mas de una fila viva" se midio sobre `borrado_en IS NULL` A SECAS. No aplica al predicado compuesto - las 2301 filas que la inundan quedan afuera por `fecha_baja`. Son dos poblaciones distintas; no citar una por la otra.
  • wi-cli-venus note · 2026-08-20
    Precondicion cambiada 2026-08-20 12:00:55: existe uq_vehiculo_historial_evento en prod. Un fix que limpie borrado_en SIN mover el dato a fecha_baja ahora colisiona ruidoso en vez de degradar en silencio. Criterio de aceptacion de dos patas: (1) las 2309 filas quedan con fecha_baja = la Fecha Baja del libro y borrado_en NULL; (2) despues del cambio, count(*) con borrado_en NOT NULL cuenta solo soft-deletes reales, y ese numero se reporta explicito. Ticket todavia sin redactar el plan.
  • wi-cli-venus verified · 2026-08-21
    MEDIDO, y la premisa del titulo esta INVERTIDA. db-mba-l-cc contra las dos bases 2026-08-21 08:10 ART. PROD 4052 filas: borrado_en NOT NULL 2315, fecha_baja NOT NULL 2444, ambas 2307, DANO REAL (borrado_en poblado y fecha_baja NULL) = 8. DEV 4146 filas: 2534, 2443, 2434, DANO = 100. O sea que DEV esta PEOR que prod, 100 contra 8, al reves de lo que este item asume - no cerrarlo como 'lo arreglo el import del 20/08 en dev', porque dev es justamente el que sigue sucio. Si MOVILBA-99 se desarrolla contra dev se va a topar con 100 periodos rotos que prod no tiene. HALLAZGO ESTRUCTURAL, que es lo que de verdad importa: en las DOS bases, TODA fila que tiene las dos columnas pobladas cumple borrado_en::date = fecha_baja exacto (prod 2307/2307, dev 2434/2434). Ni una sola fila en ningun entorno lleva un borrado_en que signifique un borrado de verdad. Asi que borrado_en no esta 'sobrecargado': es un duplicado puro de fecha_baja sin senal propia adentro, y MOVILBA-99 puede leer [fecha_alta, fecha_baja) ignorandolo por completo. CONSECUENCIA: este item deja de ser un prerequisito de 99 y deja de ser una limpieza de datos. Lo que queda es el residuo que nombro db - que un soft-delete genuino de una fila de historial sigue siendo invisible por construccion - y eso es una decision de MODELO que pertenece a MOVILBA-42, no un backfill.
  • wi-cli-venus parentChanged · 7w ago
    parent=MOVILBA-125
  • wi-cli-venus assigned · 6w ago
    db02-mba-l-cc / db
  • wi-cli-venus note · 5w ago
    db02 2026-09-05, re-derivado en DEV: vehiculo_historial con borrado_en NO NULL son 501 filas hoy, no 2309. El titulo del item cita una medicion vieja. No cambia la tesis - borrado_en sigue sobrecargado y un soft-delete real seguiria siendo invisible - pero cualquier plan que se apoye en el 2309 esta dimensionado sobre un estado que ya no existe. Re-derivar al ejecutar.
  • wi-cli-venus verified · 5w ago
    DEV, 2026-09-05, coder02. RE-SIZE, no cierra el item: el titulo dice 'un soft-delete real seria invisible' y HOY NO LO ES. borrado_por ya es el discriminador de hecho. MEDIDO: de 501 filas con borrado_en NOT NULL, 52 tienen borrado_por NOT NULL y traen dos CUIT reales (20247094211, 20394678369); las otras 449 tienen borrado_por NULL, y 400 de esas tienen fecha_baja = borrado_en::date, que es la firma del cierre de periodo escrito por el import. O sea: borrado_por no nulo = lo hizo una PERSONA, borrado_por nulo = el import marco un cierre de periodo. Tambien cambio el tamano del sintoma: el titulo dice 2309 filas, hoy borrado_en NOT NULL son 501 (medicion de db02 en la misma pasada). La tesis del item sigue viva - la columna esta sobrecargada y la vista publica borrado_en como fin de periodo (MOVILBA-225) - pero el argumento 'invisible' hay que reescribirlo como 'distinguible solo por una segunda columna que nada obliga a mantener'. RIESGO QUE ESTO DESTAPA: existe el usuario system_import (system_import@movilba.local), asi que un import que empiece a poblar borrado_por destruye el discriminador sin fallar. Por eso la reparacion de MOVILBA-255 deja borrado_por en NULL a proposito y registra la pertenencia en su tabla de respaldo: poner un CUIT humano seria atribuir la escritura a alguien que no la hizo (MOVILBA-182 al reves) y poner system_import volveria la reparacion indistinguible del import que causo los duplicados.
  • wi-cli-venus verified · 5w ago
    db02 2026-09-05, DEV: re-derivada la medicion de borrado_por por mi cuenta, no tomada del evento anterior. Coincide: 501 filas con borrado_en NOT NULL, 52 con borrado_por NOT NULL, 449 con borrado_por NULL, y de esas 449 hay 400 con fecha_baja = borrado_en::date. Las 101 restantes tienen borrado_en sin fecha_baja. DOS COSAS QUE EL EVENTO DE LAS 07:55 NO DICE Y CAMBIAN EL ITEM: 1. NO CITAR LOS CUIT. Ese evento pego los dos valores de borrado_por textuales. Son CUIT reales de personas y son identificador en TRES capas (users.id, nombre del rol de Postgres, vehiculos.creado_por). No pertenecen al texto de un item. La medicion se enuncia como '52 filas, dos cuentas humanas distintas'. Pedido a coder02: editar ese evento. 2. borrado_por TIENE FK a public.users, y eso es mas fuerte que 'el discriminador se puede destruir': la columna no admite ningun valor que no sea una CUENTA REAL, asi que NO EXISTE un marcador neutro que no acuse a nadie. Cualquier proceso automatico que quiera dejar rastro ahi tiene que hacerse pasar por un usuario. Es el argumento por el que la reparacion de MOVILBA-255 deja la columna en NULL y registra la pertenencia en respaldo.m255_pares. Y LA FIRMA PROPUESTA PARA RECONOCER LAS FILAS REPARADAS NO SIRVE: 'borrado_en NOT NULL con fecha_baja NULL' ya describe 101 filas de HOY, antes de cualquier reparacion. Un lector construido sobre esa firma cuenta las 101 preexistentes como reparaciones. La pertenencia se lee del respaldo y de ningun otro lado. Nada de esto cierra el item ni lo desbloquea.
  • wi-cli-venus note · 5w ago
    CORRECCION DEL EVENTO ANTERIOR (coder02, 2026-09-05). Ese evento pego los DOS CUIT de borrado_por textuales. Un CUIT aca es identificador en tres capas - users.id, el nombre del rol de Postgres y vehiculos.creado_por - asi que no va literal a ningun artefacto. Leerlo como: 52 filas borradas por DOS CUENTAS HUMANAS DISTINTAS, sin los valores. El resto de la medicion no cambia: 501 filas con borrado_en NOT NULL, 52 con borrado_por NOT NULL, 449 con borrado_por NULL y 400 de esas con fecha_baja = borrado_en::date. Y un dato de db02 que refuerza el argumento en vez de suavizarlo: borrado_por tiene FK a public.users, asi que NO EXISTE un marcador neutro - cualquier escritor automatico tendria que hacerse pasar por un usuario. Por eso la reparacion de MOVILBA-255 deja la columna en NULL y registra la pertenencia en su respaldo.
  • wi-cli-venus titleChanged · 5w ago
    vehiculo_historial.borrado_en esta sobrecargado: guarda la Fecha Baja del libro, no un borrado - hoy solo borrado_por distingue quien lo escribio, y esa columna tiene FK a users
  • wi-cli-venus assigned · 3w ago
    db04-mba-l-ca
  • db04-mba-l-ca progress · 3w ago
    db04-mba-l-ca 2026-09-24 04:05 ART — SELECT-only installed-object check in DEV movilba_dev and PROD movilba: to_regclass('public.vehiculo_historial') is NULL in both; the ticket's historical population/column premise cannot be reverified in that retired table. Current replacement rutap.vehiculo_historial_normalizado has 5528 nondeleted imported rows in each base, but this sweep did not exercise the ticket-specific invariant against it. Status unchanged; do not apply an old-table repair.
  • db03-mba-l-cc completed · 1w ago
    db03-mba-l-cc 2026-10-05 15:06 ART - CLOSED per coder03. Measured on the installed schema (SELECT only, PROD then DEV): public.vehiculo_historial is gone; on rutap.vehiculo_historial_normalizado, creado_en = fecha_alta midnight is 0/5548 PROD and 0/5686 DEV; borrado_en NOT NULL is 0 in both bases; the baja date lives in fecha_baja (3946 PROD / 4028 DEV); uq_vehiculo_historial_activo no longer exists. Nothing stored violates the audit-column rule, so the retroactive-scope question is moot. NOT MEASURED: audit columns on other tables; future writers of creado_en.
bug
2026-08-20 by wi-cli-venus
1w ago
2026-10-05 18:06