basquetWi + New ticket
movilba MOVILBA-494

Portar a PROD el guard de catalogos sin resolver: vista + funcion + trigger que solo existen en DEV y no tienen migracion trackeada en ninguna rama

Done normal unassigned

DECISION DELEGADA POR ELAZAR (CLI 2026-09-18, verbatim: 'not mine to make, you and other agents analize and decide'). Analizada y decidida por db02 con evidencia; coder03 y audit notificados para objetar con evidencia. QUE FALTA. No es una vista suelta: PROD no tiene NINGUNO de los tres objetos que DEV si tiene. (1) vista rutap.v_snapshot_catalog_preflight, (2) funcion rutap.vh_norm_reject_unresolved_catalogs, (3) el TRIGGER de esa funcion sobre rutap.vehiculo_historial_normalizado (tgenabled='O' en DEV). Medido: to_regclass/to_regproc devuelven NULL en PROD para (1) y (2), pg_trigger devuelve cero filas para (3). QUE HACE EL GUARD. RAISE 23514 sobre toda fila con origen='import' cuyo normalizacion_estado <> 'resuelto'. La vista NO se ejecuta: aparece solo en el texto del HINT, o sea es diagnostico y no dependencia de la funcion. Consecuencia hoy: PROD acepta en silencio una fila de import con catalogo sin resolver, DEV la rechaza. Es la misma forma que MOVILBA-493 - a PROD le faltan las protecciones, no los datos. ENTRA LIMPIO, MEDIDO ANTES DE DECIDIR. rutap.vehiculo_historial_normalizado agrupado por origen+normalizacion_estado: PROD 5514 import/'resuelto', 100%, cero filas en cualquier otro estado. DEV 5514 import + 95 app, todas 'resuelto'. O sea el trigger no rechazaria ni una fila existente en PROD; solo actua sobre importaciones futuras. No hay que limpiar nada antes. DIRECCION. Se porta DEV -> PROD. Sin ambiguedad: el objeto que falta es el que protege, y la base que no lo tiene es justamente la que tiene que igualar al libro. HALLAZGO QUE SALE DE BUSCAR EL ORIGEN, y es el que agrega trabajo: NINGUNO DE LOS DOS OBJETOS TIENE MIGRACION TRACKEADA, EN NINGUNA RAMA. git grep en dev los encuentra solo en docs/reference/movilba-479-dev-prod-schema-census.md (un censo, no una fuente) y en drizzle/schema.ts (introspeccion generada). Viven unicamente en la base de DEV. Entonces el primer paso NO es escribir la migracion de memoria: es capturar el cuerpo instalado con pg_get_viewdef / pg_get_functiondef y pg_get_triggerdef desde DEV y meter ESE texto en la migracion. Ojo con la trampa ya fichada: PG15 y PG17 imprimen el mismo cuerpo distinto, asi que el diff DEV/PROD posterior se normaliza con tools/movilba-479-normalize-viewdef.py y no a ojo. LO QUE NO ARREGLA, dicho para que no se lea como que si: el guard mira normalizacion_estado, no el resultado de cada resolver individual. El resolver muerto de carroceria (MOVILBA-492) proyecta NULL en 5514 de 5514 filas y esas filas estan marcadas 'resuelto' igual. Portar este guard NO cierra 492 ni lo detecta. PENDIENTE: coder03 escribe la migracion (tres objetos, mismo archivo DEV+PROD, idempotente: verifica si esta, crea si falta - como 493). db02 la ensaya en las dos bases y la aplica. Es DDL de PROD pero la decision de fondo ya la delego Elazar; el archivo lleva control negativo forzado, o sea hay que VER al trigger rechazar una fila no resuelta antes de aceptarlo.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 4w ago
  • wi-cli-venus note · 4w ago
    Ensayo de b7e1a222 por db02: DEV pasa entero, PROD ABORTA. Tres hallazgos medidos. (1) LA VISTA SI SE PUEDE CREAR EN PROD - el 'solo-en-DEV' del censo 479 es falso. to_regclass('rutap.unidad_propulsora_resolver') y ('rutap.chasis_resolver') devuelven el nombre en PROD, y to_regproc('rutap.normalizar_clave_chasis') tambien. No se dedujo: se CREO la vista en PROD con el cuerpo capturado bajo BEGIN/ROLLBACK, CREATE VIEW sin error, y select count(*) sobre ella devuelve 0 filas (coherente con 5514/5514 resuelto). ORIGEN DEL ERROR: esas dos tablas son exactamente las que el censo de catalogos de db03 no pudo leer en PROD POR PERMISO DENEGADO con el rol de aplicacion, y quedaron anotadas como ausentes. Un read sin privilegio se lee igual que una ausencia; esta vez la confusion viajo dentro de un censo hasta convertirse en una decision de scope (sacar la vista del port). No hace falta item aparte para la vista: entra con los otros dos objetos. (2) PROD NO TIENE EL ROL movilba_user. El archivo aborta en la linea 153 con 'role "movilba_user" does not exist'. Defecto solo-en-ejecucion: leerlo no lo muestra porque el nombre es correcto en DEV. Medido: pg_roles en PROD no lo tiene, y las 14 relaciones y las 9 funciones del esquema rutap son TODAS de 'elazar'. (3) EL OWNER NO SE ESCRIBE, SE DERIVA. Un literal movilba_user ata el archivo a DEV igual que un id literal ataba la purga de ELECTRICO-CABA a una base. Regla que sobrevive a los dos entornos: el objeto nuevo toma el owner que ya tienen los objetos de rutap EN ESA MISMA BASE, resuelto por consulta, y se ABORTA si en esa base hay mas de un owner, porque entonces no hay respuesta unica y hace falta una decision escrita. Las aserciones de provolatile/prosecdef/proconfig IS NULL se quedan: esas son propiedades del objeto, no del entorno. DEV, para que conste que la pata 'verifica' no es una linea verde: sin_cambio x2, trigger identico a la captura y habilitado, owner/volatilidad/security/proconfig iguales, fixture revertido por subtransaccion y la fila re-leida en su estado original, 0 filas import sin resolver. Sin objecion al resto del diseno de coder03. Pendiente: coder03 corrige, db02 vuelve a ensayar.
  • wi-cli-venus note · 4w ago
    APLICADO EN PROD, los TRES objetos, 2026-09-18 (db02). Orden de Elazar en CLI: 'i need this done now'. QUE SE CORRIGIO ANTES DE APLICAR. (a) El bloqueante 'la vista no se puede crear en PROD' era FALSO: las tres dependencias existen (to_regclass/to_regproc devuelven nombre) y la vista se creo en PROD con el cuerpo capturado bajo BEGIN/ROLLBACK antes de decidir nada. El censo 479 las daba DEV-only a partir de una lectura que el rol de aplicacion NO TENIA PERMISO de hacer. (b) El archivo abortaba con 'role movilba_user does not exist': se reemplazo el literal por una DERIVACION - el owner sale de los objetos que ya viven en el esquema rutap EN ESA MISMA BASE, y aborta si hay mas de uno. Resuelve movilba_user en DEV y elazar en PROD, sin fork. (c) Elazar rechazo crear el rol movilba_user en PROD solo para satisfacer el literal: seria un rol vacio inventado por un archivo. APLICADO: funcion rutap.vh_norm_reject_unresolved_catalogs (owner elazar), su trigger sobre rutap.vehiculo_historial_normalizado (BEFORE INSERT OR UPDATE OF origen, normalizacion_estado, conflictos; tgenabled='O', definicion comparada como TEXTO contra pg_get_triggerdef de DEV), y la vista rutap.v_snapshot_catalog_preflight (relkind='v', owner elazar, se LEE y devuelve 0 filas sin resolver). Denominador 5514 filas, 0 que el guard rechazaria antes y despues. El control de dos mitades corrio en PROD: el guard acepta con 'resuelto' y rechaza sin el, exigiendo su propio texto de error y no un 23514 pelado, revertido por subtransaccion con la fila re-leida en su estado original. Verificacion post-commit por consulta independiente al catalogo, no leyendo el reporte del archivo. Archivos (db02 los escribio/corrigio, coder03 los commitea): docs/migrations/2026-09-18-movilba-494-guard-catalogos-sin-resolver-DEV-Y-PROD.sql (corregido sobre b7e1a222) y docs/migrations/2026-09-18-movilba-494b-vista-preflight-DEV-Y-PROD.sql (nuevo). NO CIERRA MOVILBA-492: el guard mira normalizacion_estado, no el resultado de cada resolver. El resolver de carroceria proyecta NULL en 5514 de 5514 y esas filas estan marcadas 'resuelto' igual. DERIVADO: MOVILBA-497 (el owner 'elazar' es un rol personal con 122 objetos en PROD).
  • wi-cli-venus completed · 4w ago
    Guard de catalogos sin resolver APLICADO en PROD: rutap.vh_norm_reject_unresolved_catalogs, su trigger y rutap.v_snapshot_catalog_preflight. PROD ya no acepta en silencio una fila de import con un catalogo sin resolver. Owner derivado del esquema, no literal. NO cierra MOVILBA-492. Cerrado por coder03, que lo reporto aplicado en chat.
  • wi-cli-venus completed · 4w ago
    APLICADO en PROD 2026-09-18, los tres objetos. Verificado ahora contra el catalogo de PROD: vista rutap.v_snapshot_catalog_preflight presente, funcion rutap.vh_norm_reject_unresolved_catalogs presente, y 1 trigger de esa funcion sobre rutap.vehiculo_historial_normalizado. Cuerpos capturados con pg_get_viewdef/functiondef/triggerdef desde DEV, no escritos de memoria (no tenian migracion trackeada en ninguna rama). Dos defectos solo-en-ejecucion que ninguna lectura mostraba: el archivo hacia OWNER TO movilba_user, rol que NO EXISTE en PROD - se reemplazo por derivar el owner de los objetos que ya viven en el esquema y ABORTAR si hay mas de uno; y el 'la vista no existe en PROD' que justificaba dejarla afuera resulto ser una lectura sin permiso anotada como ausencia en el censo 479, desmentida CREANDO la vista en PROD bajo ROLLBACK.
task
4w ago by wi-cli-venus
4w ago
2026-09-18 15:00