Una columna con id de catalogo y sin FK es invisible al censo de referencias: el borrado de las 53 carrocerias dejo 9965 filas colgadas en vehiculos_archive, que la app lee
MEDIDO 2026-09-08 db02-mba-l-cc, DEV, SELECT only. DEFECTO VIVO CAUSADO POR EL APPLY DE MOVILBA-377 A LAS 07:47, y la autoria es mia. QUE PASO: el borrado fisico de 53 filas de public.carrocerias dejo colgadas 9965 filas de public.vehiculos_archive (51 ids distintos) y 1300 de public.parque_rutap_temp (49 ids distintos). Ninguna de las dos tablas tiene FK a carrocerias, asi que el DELETE no se freno y el control POST -que consultaba las DOS FK declaradas- dio 0 huerfanas y paso. ATRIBUCION SIN AMBIGUEDAD: los 51 ids huerfanos estan TODOS dentro de los 53 que borre; CERO caen fuera. Antes del apply existian los ids 1 a 74, asi que ninguna de las dos tablas podia tener un huerfano. Lo produjo integramente el apply. POR QUE NO LO VIO EL CONTROL, que es la leccion y no el numero: el preflight midio referencias por pg_constraint, o sea por las FK DECLARADAS, y el control POST volvio a preguntar por las mismas dos. Un control que re-usa el censo que fallo no puede atrapar el caso que ese censo no ve. Una columna entera con un id de catalogo y sin FK es invisible a las dos mediciones. CONSUMIDOR REAL: public.vehiculos_archive lo lee la app en src/actions/audit.ts:31, mapeo vehiculos -> { table: 'vehiculos_archive', idColumn: 'id', rbacResource: 'vehiculos' }. Es el camino de lectura del historial de auditoria de vehiculos, con RBAC. public.parque_rutap_temp no tiene consumidor en src/. IDS MAS AFECTADOS en vehiculos_archive: 56 con 1570 filas, 52 con 992, 38 con 918, 51 con 646, 21 con 590, 26 con 520, 37 con 480, 47 con 362, 42 con 349, 40 con 341, 49 con 312, 58 con 309. Y BLOQUEA LO QUE VENIA DESPUES: la misma medicion sobre las filas que todavia no se borraron dice que la id 72 IGUAZU tiene 50 filas en vehiculos_archive y 5 en parque_rutap_temp, y la id 18 YUCHAI tiene 7 en vehiculos_archive. O sea que 'IGUAZU no se usa' es falso fuera de las FK declaradas, y el artefacto 377c no se puede aplicar como esta: su preflight tiene el mismo punto ciego. COMO SE ACOTO LA BUSQUEDA, para que se pueda juzgar si es exhaustiva: (1) toda columna de todo schema con nombre que matchea 'carroceri' cruzada contra pg_class, 34 columnas, exactamente 2 con FK; cinco mas son carroceria_id integer sin FK -las dos de arriba mas tres tablas bkp con 141 filas y CERO huerfanas-. (2) las 47 columnas jsonb/json fuera de pg_catalog: en public.audit_log.details y public.vehiculo_historial.cambios la carroceria viaja como TEXTO ('HEPRICAR', 'TODO BUS'), nunca como id, y cero filas llevan un id de los 53; public.app_logs.data no tiene ninguna clave carroceria_id. (3) las 13 matviews de catalogo leen public.opciones, no carrocerias, asi que no pueden guardar un id viejo. NO SE PROPONE ARREGLO. La decision de si vehiculos_archive tiene que conservar una carroceria resoluble es de Elazar. Cero escrituras en esta medicion. NO EJERCITADO: PROD; si vehiculos_archive tiene el mismo problema con chasis_id, motor_id o vehiculo_subtipo_transporte_id, que es la misma clase y no se midio.
Activity
-
DUPLICADO de MOVILBA-383, que es el que queda. Los dos se abrieron sobre el mismo hallazgo con minutos de diferencia: yo lo file como 382 al terminar la medicion y coder02-mba-l-cc lo file como 383 al relevarlo. 383 lleva ademas el cierre de Elazar y su razonamiento, asi que es el registro bueno. Lo unico que 382 tiene de mas y que ya esta dicho en el hilo: los ids 13 (100 filas en vehiculos_archive), 33 (807 y 98 en parque_rutap_temp), 70 (1) y 72 (50 y 5), y el total posterior a los tres applies, 10923 filas sobre 55 ids inexistentes. Cero escrituras de reparacion. Se cancela para que no quede un P0 abierto que parece un bloqueante vivo.