Dos indices unicos identicos en linea_entidad_asignaciones: la app esta cableada a UN nombre y el inventario bendice EL OTRO - dropear el equivocado degrada un mensaje de error a staff
MEDIDO POR db-mba-l-cc en prod (11:12, SELECT sobre pg_indexes): uq_linea_entidad_asig_activa - UNIQUE btree (linea_id) WHERE borrado_en IS NULL uq_linea_entidad_activa - UNIQUE btree (linea_id) WHERE borrado_en IS NULL Misma tabla, misma columna, mismo predicado, dos nombres. NO es el caso de dominacion de predicados de uq_vehiculo_historial_evento/activo (donde uno es subconjunto del otro y queda inerte): estos son EXACTAMENTE duplicados. Uno de los dos es puro costo de escritura y de almacenamiento, con cero restriccion agregada. Casi seguro dos migraciones creando la misma cosa con nombres distintos. ARREGLO: DROP de uno. Es DDL, o sea carril coder, y requiere GO de Elazar si toca prod. ANTES DE DROPEAR, DOS CHEQUEOS que este item exige y que no se pueden saltear: 1. Confirmar que son identicos EN PROD Y EN DEV, con el indexdef completo de los dos, no solo el nombre. Dos indices que se ven iguales en un entorno pueden diferir en el otro. 2. Verificar cual de los dos respalda alguna FK o algun ON CONFLICT antes de elegir cual se va - un indice UNIQUE tambien respalda ON CONFLICT, y dropear el que una sentencia nombra rompe en TIEMPO DE EJECUCION con 42P10, que ninguna auditoria de vistas saca (la leccion es de db02-mba-l-cc en MOVILBA-114). NO ES URGENTE: no hay incorreccion, solo costo duplicado. Prioridad 2.
Activity
-
Dos indices unicos identicos en linea_entidad_asignaciones: la app esta cableada a UN nombre y el inventario bendice EL OTRO - dropear el equivocado degrada un mensaje de error a staff
-
NO ES SOLO COSTO DE ESCRITURA. Hallazgo de db02-mba-l-cc, verificado por coder-mba-l-cc contra el repo: CUAL SE DROPEA NO ES ARBITRARIO - LA APP ESTA CABLEADA A UN NOMBRE. src/utils/database-error-mapper.ts:136 uq_linea_entidad_activa -> 'La linea ya tiene una entidad asignada activa' src/repositories/parque-movil.ts:240 cita uq_linea_entidad_activa src/lib/openapi/components.ts:515 cita uq_linea_entidad_activa (contrato OpenAPI) docs/reference/db-inventory.md:238 lista el OTRO, uq_linea_entidad_asig_activa, con veredicto 'keep' El codigo depende de un nombre y el inventario bendice el otro. DECIDE EL CODIGO: se dropea uq_linea_entidad_asig_activa y se conserva uq_linea_entidad_activa, que es el que el mapper, el repositorio y el contrato OpenAPI nombran. Y hay que CORREGIR db-inventory.md:238, que hoy manda al reves - si alguien sigue el inventario, el 23505 deja de matchear y staff recibe un error generico de base en vez de la frase amable, sin ningun otro sintoma. HAY UNA CONSECUENCIA VIVA HOY, ANTES DE CUALQUIER DROP: con dos indices unicos identicos, el nombre que Postgres reporta en el 23505 es el del indice que detecta la violacion - un detalle de implementacion del orden de chequeo, no un contrato. El mapper matchea solo uno de los dos nombres. O sea que el mensaje amable esta condicionado a cual de los duplicados dispara, y nada en el codigo garantiza que sea el que el mapper conoce. NADIE PROBO cual dispara. Probarlo requiere un INSERT en conflicto deliberado - una escritura, sin GO ni en dev. Es un test de dos minutos EN DEV: insertar una asignacion en conflicto, leer el nombre en el error, confrontarlo con el mapper. Convierte esto de argumento en hecho y hay que correrlo ANTES de elegir. DETALLE OPERATIVO: ninguno de los dos esta respaldado por constraint (pg_constraint.conindid vacio en ambos), asi que alcanza DROP INDEX, sin ALTER TABLE ... DROP CONSTRAINT. YA ESTABA FICHADO Y SE PERDIO: CHANGELOG.md:505 dice 'uq_linea_entidad_activa duplicado pendiente de drop', detectado en un regen de drizzle y nunca ejecutado. Procedencia visible en las migraciones: prod-migration-591-592-598.sql:107 crea uq_linea_entidad_asig_activa y 2026-07-31-678-linea-entidad-unique-ipmdvr-notnull.sql:23 crea uq_linea_entidad_activa. Dos migraciones con meses de diferencia creando la misma restriccion con nombre propio. drizzle/schema.ts:492-493 reproduce fielmente la duplicacion y ningun gate la marco - igual que el indice inerte: no habia nada anomalo que ver, asi que nadie miro. ROMPE LA PLANTILLA DEL HARNESS, decidir a proposito y decirlo en el encabezado del paquete: en prod esto quiere DROP INDEX CONCURRENTLY, que NO PUEDE correr dentro de un bloque transaccional - no entra en el BEGIN/COMMIT del harness y no se puede ensayar con ROLLBACK forzado. Misma clase no-transaccional que setval, que ya mordio al paquete 94 esta manana. Un DROP INDEX pelado si es transaccional y ensayable, pero toma AccessExclusiveLock sobre la tabla mientras dura. No dejar que herede la plantilla en silencio.
-
db02-mba-l-cc / db
-
db03-mba-l-cc
-
DEV+PROD 2026-09-18: two identical partial unique idx (linea_id) WHERE borrado_en IS NULL. Mapper (database-error-mapper.ts:136) keys on uq_linea_entidad_activa; PG reports lowest-OID index on 23505 and uq_linea_entidad_asig_activa has the lower OID in both bases (DEV 9549369<11236471, PROD 100477<181759) -> friendly message dead today. Fix file (drop asig_activa, keep activa) docs/migrations/2026-09-18-movilba-116-drop-uq-linea-entidad-asig-activa-DEV-Y-PROD.sql: DEV ensayo pass, fail control seen, sent to audit. PROD ensayo/apply pending db02 + coder03 GO. Not exercised: app-path insert.
-
APPLIED DEV+PROD 2026-09-18 by db02 (superuser), committed dev 8daab27f. Post-apply query (db02, both bases identical): public.linea_entidad_asignaciones has exactly ONE unique partial index (linea_id) WHERE borrado_en IS NULL = uq_linea_entidad_activa; uq_linea_entidad_asig_activa gone. In-tx probe (4 runs, ensayo+apply, both bases): 23505 named asig_activa before DROP, activa after. drizzle/schema.ts index line removed by hand (introspect.sh output was corrupted by the in-flight tools/introspect-dev.mjs change: truncated expressions, broken defaults - discarded); db-inventory.md row removed; prod-migration-591-592-598.sql marked do-not-rerun (a18a042d). Not exercised: real app-path insert showing the friendly message; DEV/PROD sequence unchanged in DEV (110).