carrocerias.carroceria_piso_id y carroceria_aire_acondicionado_id no tienen FK y el de aire lee DOS catalogos distintos a la vez
PREGUNTA DE ELAZAR (CLI 2026-09-18): 'I dont belive opciones is stored in carroceria, i believe it has another catalog, you check and let me know.' Tiene razon, y al verificarlo aparecio un defecto. LA RESPUESTA A LA PREGUNTA: la carroceria NO vive en opciones. public.carrocerias es su propia tabla de catalogo (modelo + fabricante_id). De opciones salen solo DOS ATRIBUTOS de la carroceria: el piso y el aire acondicionado, via carrocerias.carroceria_piso_id y carrocerias.carroceria_aire_acondicionado_id. DEFECTO 1 - ESAS DOS COLUMNAS NO TIENEN FK. Medido: pg_constraint contype='f' con conrelid='public.carrocerias' devuelve UNA sola fila en las dos bases, carrocerias_fabricante_id_fkey. Las dos columnas de atributo son enteros sueltos, sin constraint, y estan POBLADAS: PROD 70 de 74 filas, DEV 16 de 17. Nada impide que entre un id que no existe o que pertenezca a otro grupo del catalogo. DEFECTO 2, Y ES EL GRAVE - LA COLUMNA DE AIRE LEE DOS CATALOGOS DISTINTOS A LA VEZ. Medido en PROD agrupando por el id almacenado: 69 carrocerias apuntan a opciones id 24 = grupo 'general' / campo 'respuesta_binaria' / valor 'SI' (viva), y 1 carroceria apunta a opciones id 126 = grupo 'carroceria' / campo 'aire_acondicionado' / valor 'SI' (MARCADA como borrada). Mismo significado, dos ids, dos grupos distintos, y la unica fila que usa el catalogo 'correcto' por nombre de grupo apunta a una opcion soft-deleteada. En DEV las 16 apuntan todas a la 24. Es exactamente la trampa 'una columna con DOS catalogos' ya fichada en memoria, con instancia medida. El piso esta sano: PROD 69 al id 28 (carroceria/piso/BAJO) y 1 al id 160 (carroceria/piso/3 LARGO), las dos vivas y del grupo correcto; DEV 16 al id 28. PENDIENTE, en este orden: (1) decidir cual de los dos catalogos es el bueno para aire_acondicionado -el grupo 'carroceria'/'aire_acondicionado' tiene sus dos filas (126 SI, 127 NO) MARCADAS, o sea el catalogo que lleva el nombre correcto es el que esta muerto; (2) repuntar la fila disidente al ganador; (3) recien entonces poner las dos FK. Poner la FK primero no se puede: con dos grupos conviviendo, una FK a opciones aceptaria los dos igual, asi que la FK sola no arregla nada - hace falta ademas que el id sea del grupo correcto, y eso una FK a opciones no lo expresa. Emparentado con MOVILBA-490 (convertir resoluciones por valor en FKs de verdad). Medido por db02 2026-09-18, SELECT-only, DEV y PROD. No se escribio nada.
Activity
-
coder03-mba-l-cc
-
coder02-mba-l-cc
-
Elazar GO in CLI 2026-09-19 for the PROD leg, fresh and specific. Relayed to db02-mba-l-cc: apply exactly md5 49ae22ab3abacdf148b17a80b6648283 (blob f6f3596e), hub lock first, gates reported individually, MOVILBA-514 not in the same transaction.
-
APLICADO EN PROD 2026-09-19 por db02-mba-l-cc, GO fresco de Elazar (CLI) relevado por coder03-mba-l-cc, especifico para la pata PROD. Lock de hub movilba-495-carrocerias-aire tomado antes y liberado despues; nada mas toco PROD en el medio. md5 REALMENTE CORRIDO: 49ae22ab3abacdf148b17a80b6648283 (copia fresca del blob committeado f6f3596e, hasheada antes y despues, nunca desde el checkout compartido). exit 0, COMMIT. Cero diferencias contra el ensayo post-497. GATES, uno por uno y no un veredicto resumido: - PRE: carrocerias total 17 = en 24: 16, NULL: 1, en 126|127: 0, en OTRO id: 0. Mi conteo independiente previo daba lo mismo (16 | 0 | 17). - PRE triggers no internos de carrocerias: trg_soft_delete_carrocerias (BEFORE DELETE, asi que el UPDATE de 16 filas no dispara nada). - PRE etiquetas: 24 = "Sí", 126 = "Con Aire Acondicionado". - (a2) baseline d9a321bb739f01193562c321a14063dc, IGUAL despues: ninguna otra columna de carrocerias cambio. - UPDATE 2 (desmarcado de 126 Y 127, el grupo entero), UPDATE 16 (repunte), ALTER TABLE (FK validada). - POST (a)-(d): 24 -> 0, 126 -> 16, NULL 1, otro 0. - (d1) VISTO FALLAR: la FK rechaza un id inexistente. - (d2) declarado: la FK ACEPTO el id 24 de otro grupo. VERIFICACION INDEPENDIENTE POST-COMMIT (consulta que el archivo no contiene): en 24 = 0, en 126 = 16, NULL 1, total 17; opciones 126 y 127 las dos VIVAS; carrocerias pasa de 1 a 2 FKs. DEV y PROD quedan iguales en la columna repuntada (16/17 y 16/17) y el md5 de todas las demas columnas es identico en las dos bases (d9a321bb...). Lectura real como svc_nextjs sobre carrocerias: 17 filas, la app sigue leyendo. LO QUE NO CIERRA ESTE TICKET, escrito aca para que siga existiendo: 1. EL GRUPO NO ESTA ENFORZADO POR EL MOTOR. La FK apunta a opciones entera, asi que acepta cualquier fila de esa tabla - (d2) lo demuestra aceptando el id 24, que es de otro grupo. Queda como MOVILBA-514. 2. La FK es NO ACTION: mientras carrocerias referencie 126/127, un borrado FISICO de esas opciones (tipo poda 504) va a fallar. Es intencional y esta declarado. 3. Cambio VISIBLE al usuario: la etiqueta exportada pasa de "Sí" a "Con Aire Acondicionado" para las filas cuyo origen es carroceria. 4. Son 16 filas, NO 69. El 69 es texto viejo del ticket; medido da 16 y es igual en DEV y PROD. 5. Estos bytes v2 no se ejecutaron en ningun lado salvo ensayos bajo ROLLBACK, y NO PUEDEN correr en DEV: DEV corrio v1 (6e7f12d0) y el PRE de v2 exige 126/127 marcadas, que ya no lo estan. El delta v1->v2 es solo gates de lectura (inventario de triggers en PRE, POST (a2)) mas header: mismos UPDATE, mismo DDL. 6. rutap.vehiculo_historial_normalizado.aire_acondicionado_id sigue en 24 - fuera de alcance, va con 514. MOVILBA-514 NO se toco en esta transaccion.
-
Aplicado en PROD 2026-09-19 (md5 49ae22ab3abacdf148b17a80b6648283, commit f6f3596e, GO fresco de Elazar via coder03); DEV ya tenia el efecto por v1. Gana el grupo carroceria/aire_acondicionado: opciones 126 y 127 desmarcadas (el grupo entero) y las 16 filas de carrocerias repuntadas de 24 a 126, mas la FK a opciones. Verificado aparte del archivo: en 24 = 0, en 126 = 16, NULL 1, total 17, y el md5 de todas las demas columnas es identico a DEV. NO CIERRA: el grupo NO esta enforzado por el motor - la FK acepta el id 24 de otro grupo (MOVILBA-514); la FK es NO ACTION y bloquea una poda fisica futura de 126/127; la etiqueta exportada cambia de "Sí" a "Con Aire Acondicionado"; son 16 filas y no las 69 del texto viejo; rutap.vehiculo_historial_normalizado.aire_acondicionado_id sigue en 24. Detalle y gates uno por uno en el evento verified.