basquetWi + New ticket
movilba MOVILBA-119

Dos vocabularios enumerados viven FUERA de opciones (vehiculos_tipos_transporte.descripcion y instalacion_historial.evento_tipo): violacion de la regla permanente, es item de esquema y ningun cambio de WHERE lo arregla

Done normal dmdb03-mba-l-cc

VIOLACION DIRECTA DE LA REGLA PERMANENTE DE ELAZAR: todo valor enumerado vive en la tabla opciones y la columna de negocio guarda el ID ENTERO, nunca el texto. Estas dos no. vehiculos_tipos_transporte.descripcion - 6 valores: Colectivo, Taxi, Remis, Auto de fantasia, Auto clasico, Moto de delivery. Tabla propia, texto comparado directo. instalacion_historial.evento_tipo - character varying NOT NULL, 5 valores con sus conteos: LINEA_AGREGADA 5, ACTUALIZACION 2, CREACION 1, ELIMINACION 1, LINEA_REMOVIDA 1. COMO APARECIO. Salio del barrido de MOVILBA-115 (comparaciones por etiqueta en vez de por id) al leer los 6 sitios que todavia no estaban escritos. Seis de los diez sitios NO eran ese defecto, y al preguntarse por que, dos de ellos resultaron no ser lookups de opciones EN ABSOLUTO: v_ui_vehiculo_subtipo_colectivo compara vtt.descripcion = 'Colectivo' y v_instalacion_historial compara h.evento_tipo = 'ACTUALIZACION'. No hay catalogo detras de ninguna de las dos. ES UN HALLAZGO DE COBERTURA DE CATALOGO, NO DE COMPARACION POR ETIQUETA - y la distincion es lo que lo vuelve un item aparte en lugar de una nota al pie de 115. Ningun cambio de WHERE lo arregla: el defecto de 115 es que la app compara contra una etiqueta que el soft-delete reescribe, y se cierra comparando ids. Aca no hay id contra el cual comparar porque no hay fila de opciones. Es un item de ESQUEMA (migrar las dos vocabularios a opciones y pasar las columnas de negocio a id entero), no de vista. NO BLOQUEA MOVILBA-115 y no debe atarse a el. 115 cierra con 4 sitios; estos dos quedan correctos-para-lo-que-son hasta que exista el catalogo. VERIFICADO POR DOS CARRILES POR SEPARADO antes de filarlo, porque sacar sitios de un P1 es la direccion que duele si esta mal: coder02-mba-l-cc lo leyo y db02-mba-l-cc y db-mba-l-cc confirmaron cada exclusion contra el esquema en prod en vez de aceptarla. EL DISCRIMINADOR QUE SALIO DE ACA, que vale mas que el hallazgo: el CASE de soft-delete agrega ' (borrado)' a nombre_mostrable y NUNCA a valor_opcion. Asi que solo estan expuestas las comparaciones DERIVADAS DE nombre_mostrable. Por eso v_instalaciones x2 y v_ui_provincias, que comparan valor_opcion = 'AR-C', son el UNICO patron del barrido que ya estaba CORRECTO - convertirlas a id seria churn y, peor, pareceria un arreglo y ensenaria la leccion equivocada. APARTE, MISMA FAMILIA PERO NO ESTE ITEM: v_vehiculos_export compara r.tramite = 'Alta' contra el CTE de rutap.v_rutap_latest_norm - dato fuente de RUTAP, no lookup de catalogo. Rutearlo por opciones seria un arreglo equivocado que pasa sus propios gates. Pero es fragil por otra razon y esta exactamente donde opera la opcion D de MOVILBA-109: es una igualdad contra un literal sacado del libro, y si la redaccion o las mayusculas del libro cambian, ese filtro no matchea nada y fecha_alta / fecha_alta_cerrada se van a NULL en silencio para todas las filas. Un filtro que no puede matchear, alimentado por un archivo que no controlamos. Queda en el campo visual de quien escriba D, que reescribe esa misma expresion.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 2026-08-21
  • wi-cli-venus assigned · 6w ago
    db02-mba-l-cc / db
  • 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:07 ART — SELECT-only information_schema check: DEV movilba_dev and PROD movilba still store public.vehiculos_tipos_transporte.descripcion as text and public.instalacion_historial.evento_tipo as character varying, not integer option IDs. The schema conversion requested here is not installed in either base; no status change.
  • db04-mba-l-ca progress · 3w ago
    db04-mba-l-ca 2026-09-24 04:02 ART — Timestamp correction only: the immediately preceding sweep body on this item carried a future 04:04/04:07 time; the BWI event createdAt is authoritative. No change to its measured findings or status.
  • coder03-mba-l-cc assigned · 1w ago
    db03-mba-l-cc / db
  • db03-mba-l-cc progress · 1w ago
    db03-mba-l-cc 2026-10-05 15:29 ART - REMEASURED + PHASE 1 READY. (a) instalacion_historial.evento_tipo: STILL A VIOLATION in both bases: varchar(50) + CHECK chk_instalacion_evento_tipo with 6 values; 10 rows each (CREACION 1, ACTUALIZACION 2, ELIMINACION 1, LINEA_AGREGADA 5, LINEA_REMOVIDA 1); last write 2026-02-24; writer src/actions/instalaciones.ts:333-610, reader src/components/InstalacionHistorial.tsx:24. Phase 1 = docs/migrations/2026-10-05-movilba119-instalacion-historial-evento-tipo-id-DEV-Y-PROD.sql: opciones instalaciones/evento_tipo ids 333-338 (explicit, same in both bases, MOVILBA-625), nullable FK evento_tipo_id, backfill, PROD seq setval 338. Rehearsed under ROLLBACK: PROD via superuser and DEV, 10/10 rows resolved, 0 mismatches. Phase 2 (after the code switch): NOT NULL plus DROP evento_tipo/CHECK. Code half for the coder lane: write evento_tipo_id via the opciones id and read the label from v_opciones/the join instead of the eventoLabels map. (b) vehiculos_tipos_transporte.descripcion: NOT a text-in-business-column violation. It is a dedicated catalog table (1 live row, Colectivo, after MOVILBA-378), and its only consumer vehiculos_subtipos_transporte.vehiculo_tipo_id stores the integer id via FK. Folding it into opciones would be a refactor (FK retarget plus code), not a rule fix. Proposal: leave it, unless Elazar wants every dedicated catalog folded. Side finding: opciones validadoras/evento_tipo ids 325 ASIGNACION and 326 DESASIGNACION exist only in DEV (PROD has 323/324/327). This is catalog-row drift; validadoras are hidden, so the impact is nil; flagged, not touched.
  • audit-mba-l-cc audited · 1w ago
    audit pass: opciones catalog install for instalacion_historial.evento_tipo_id, phase 1, both legs
    payload
    {"scope":"opciones catalog install for instalacion_historial.evento_tipo_id, phase 1, both legs","outcome":"pass","evidence":"Additive only (nullable FK, no NOT NULL/drop yet - phase 2 deferred to post-cutover). Explicit ids 333-338 per MOVILBA-625 contract. Preflight refuses if ids/catalog rows/column already exist. Backfill verified in-transaction: 0 rows left null, 0 mismatched valor_opcion, PROD sequence bumped past 338 only in movilba. Default ROLLBACK, apply flag explicit. 10/10 resolved per DM claim, consistent with the verify block's own assertions.","reportRef":null}
  • db03-mba-l-cc progress · 1w ago
    db03-mba-l-cc 2026-10-05 15:32 ART - PHASE 1 APPLIED after audit PASS 18:32Z, PROD (superuser, movilba) then DEV (movilba_dev). Post: opciones instalaciones/evento_tipo has 6 rows (ids 333-338) in both bases; instalacion_historial.evento_tipo_id NULL 0/10 in both; PROD opciones_new_id_seq1 last_value 338. REMAINING: coder lane switches src/actions/instalaciones.ts (writes) and src/components/InstalacionHistorial.tsx (label from opciones) to evento_tipo_id; then db03 phase 2 (NOT NULL, drop evento_tipo and chk_instalacion_evento_tipo); then mba-introspect.
  • coder04-mba-l-ca progress · 1w ago
    Coder04 code diff ready for audit: all six installation-history inserts dual-write evento_tipo_id IDs 333-338 while retaining evento_tipo because phase 1 leaves its NOT NULL column in place; history read joins opciones by id plus instalaciones/evento_tipo and renders nombre_mostrable, removing the component-local label map. Phase 2 must update/recreate v_instalacion_historial's unchanged-event filter to use evento_tipo_id=334 before dropping evento_tipo/CHECK; no view/DDL/schema change made here. No gates run.
  • audit-mba-l-cc audited · 1w ago
    audit pass: app code: instalaciones.ts dual-write + history read
    payload
    {"scope":"app code: instalaciones.ts dual-write + history read","outcome":"pass","evidence":"typecheck clean, eslint clean on the file. eventoTipoId dual-write (ids 333-338 from the already-PASSed phase-1 catalog) alongside the retained legacy eventoTipo text column, matching phase-1's not-null constraint. History read joins opciones on id+grupo_nombre=instalaciones+campo_nombre=evento_tipo+borrado_en IS NULL, renders nombreMostrable. No automated test covers this file (grepped tools/tests/, none reference it) - gap noted, not blocking.","reportRef":null}
  • db03-mba-l-cc progress · 1w ago
    db03 2026-10-05 16:50 ART: phase 2 split. 2a = docs/migrations/2026-10-05-movilba119-fase2a-v-instalacion-historial-filtro-por-id-DEV-Y-PROD.sql (sha256 e69d9b62...): CREATE OR REPLACE v_instalacion_historial with the no-op filter on evento_tipo_id=334, same 11 columns. Gate: opciones 334 = instalaciones/evento_tipo ACTUALIZACION; every row has evento_tipo_id and (text='ACTUALIZACION')=(id=334). Verify: view row count unchanged (10 in both), filter switched. Rehearsed under ROLLBACK: PROD as superuser (movilba_owner lacks CREATE on public; owner + relacl {svc_nextjs r, audit_ro r} preserved), DEV as movilba_user; negative control expected_database=movilba against DEV -> 'target mismatch'. Pre-change body identical in both bases (md5 403f80af). Sent to audit. 2b (drop evento_tipo + chk_instalacion_evento_tipo + view projection, evento_tipo_id NOT NULL) is BLOCKED: v5.6.166 src/actions/instalaciones.ts still writes eventoTipo on 6 inserts (lines 344,363,502,521,552,626), so dropping the column breaks every instalaciones write; it also needs the pod on a build that writes evento_tipo_id. 2b needs: code drops eventoTipo writes -> ship to PROD+DEV+pod -> then DROP VIEW/CREATE with re-GRANT on PROD (column removal cannot go through CREATE OR REPLACE).
  • audit-mba-l-cc audited · 1w ago
    audit pass: phase 2a migration: v_instalacion_historial filter swap to evento_tipo_id=334
    payload
    {"scope":"phase 2a migration: v_instalacion_historial filter swap to evento_tipo_id=334","outcome":"pass","evidence":"File read in full, sha matches db03's report. Gate verifies opciones 334=instalaciones/evento_tipo ACTUALIZACION and every row's evento_tipo_id agrees with evento_tipo text before touching anything. CREATE OR REPLACE keeps the same 11 columns (no column added/removed) so PROD's relacl/owner survive the superuser replace. Post-verify checks row count unchanged and filter text actually contains evento_tipo_id = 334. DEV negative control (wrong expected_database) matches bwi's reported 'target mismatch'. Scope is filter-only, no DDL beyond the view - 2b (column drop) correctly held pending the eventoTipo-text-write removal coder04/coder03 already flagged.","reportRef":null}
  • db03-mba-l-cc progress · 1w ago
    db03 2026-10-05 16:58 ART: phase 2a APPLIED on PROD (superuser) then DEV, from sha256 e69d9b62 with audit PASS. v_instalacion_historial body md5 b9ea13f3 in both; 10 rows in both, unchanged. drizzle/schema.ts regenerated: the only content change is the view's filter (evento_tipo_id = 334); the pgView block moved position. README row added. 2b still blocked on the code removing the eventoTipo writes.
  • db03-mba-l-cc progress · 1w ago
    db03 2026-10-05 16:53 ART: phase 2a live on all three surfaces. DB change applied on PROD and DEV (view md5 b9ea13f3 in both). Migration, README row and drizzle/schema.ts are in commit fa505f78, which is on dev and main; PROD, DEV and the pod serve 5.6.167 (pod serviceId 23790, per coder03). Open: 2b, after coder04 removes the eventoTipo writes and coder03 ships.
  • coder04-mba-l-ca note · 1w ago
    2026-10-05 17:xx ART: Code-removal sequencing preflight: phase 2a is already audit-PASSed/applied (view md5 b9ea13f3 both DBs). Current drizzle/schema.ts:363 still marks evento_tipo NOT NULL; six current inserts dual-write eventoTipo + eventoTipoId. Removing eventoTipo before a DB expand step makes typed inserts fail compile and would violate the live NOT NULL column. Safe sequence needed: first ALTER COLUMN evento_tipo DROP NOT NULL PROD then DEV while preserving the column/check; ship id-only app writes/reads to PROD+DEV+pod; then phase 2b drops legacy column/view projection/check. No source changes made pending that transition.
  • audit-mba-l-cc audited · 1w ago
    audit pass: 2b-prep SQL ede9a10e: gate/verify/ALTER read in full
    payload
    {"scope":"2b-prep SQL ede9a10e: gate/verify/ALTER read in full","outcome":"pass","evidence":"sha256 matches cited ede9a10e; gate refuses wrong target, any NULL evento_tipo_id, evento_tipo already nullable; single ALTER drops evento_tipo NOT NULL + sets evento_tipo_id NOT NULL atomically, chk_instalacion_evento_tipo untouched; verify checks both attnotnull; default-ROLLBACK rehearsal with apply flag","reportRef":null}
  • db03-mba-l-cc progress · 1w ago
    db03 2026-10-05 17:21 ART: phase 2b-prep APPLIED PROD (superuser) then DEV from sha256 ede9a10e, audit PASS. Both bases: evento_tipo attnotnull=f, evento_tipo_id attnotnull=t; column and chk_instalacion_evento_tipo kept. drizzle/schema.ts regenerated: only eventoTipo loses .notNull() and eventoTipoId gains it. README row added. Next: coder04's id-only code, ship to PROD/DEV/pod, then 2b drops evento_tipo + CHECK + view projection.
  • coder04-mba-l-ca note · 1w ago
    2026-10-05 17:23 ART: Step 2 code candidate after phase 2b-prep v5.6.168 is present in main/dev refs and the nullable-text/NOT-NULL-id migration is applied on PROD+DEV. Removed eventoTipo text from all six instalacion_historial inserts in src/actions/instalaciones.ts; every insert writes eventoTipoId only. Source reader getInstalacionHistorial joins opciones on instalacionHistorial.eventoTipoId and emits opciones.nombre_mostrable; no runtime reader uses instalacion_historial.evento_tipo. The generated vInstalacionHistorial schema still lists its legacy column because the view/column remain until phase 2b; no DDL/view change included here. No gates run by coder; diff is one source file.
  • audit-mba-l-cc audited · 1w ago
    audit pass: instalaciones.ts step-2: full diff read, 6 eventoTipo literals removed, eventoTipoId retained
    payload
    {"scope":"instalaciones.ts step-2: full diff read, 6 eventoTipo literals removed, eventoTipoId retained","outcome":"pass","evidence":"grep: no stray eventoTipo text refs remain; typecheck clean; eslint clean on file; test:source 50/50; test:tools 104/104","reportRef":null}
  • audit-mba-l-cc audited · 1w ago
    audit pass: 2b DROP VIEW migration sha 36ff43d5: gate/drop/restore/verify read in full
    payload
    {"scope":"2b DROP VIEW migration sha 36ff43d5: gate/drop/restore/verify read in full","outcome":"pass","evidence":"hash matches; gate requires 2b-prep done (id NOT NULL) + text col present + no other view depends; captures owner/relacl before DROP VIEW, drops constraint+column, recreates view with evento_tipo_id, restores owner, revokes pg_default_acl's wider grant and re-grants only saved relacl entries; verify checks rows/owner/sorted relacl/column gone; first rehearsal caught the widened-ACL bug (positive control); src grep confirms no reader selects the view's eventoTipo column, only base-table eventoTipoId joined to opciones","reportRef":null}
  • db03-mba-l-cc progress · 1w ago
    db03 2026-10-05 17:52 ART: phase 2b APPLIED on PROD from sha256 36ff43d5 with audit PASS. evento_tipo and chk_instalacion_evento_tipo dropped; v_instalacion_historial recreated with evento_tipo_id (body md5 f17facb1), 10 rows, owner movilba_owner, relacl {movilba_owner=arwdDxtm, svc_nextjs=r, audit_ro=r} same as before. DEV leg waits for the pod to serve 5.6.170 (the pod reads movilba_dev and 168 still writes the text); then introspect (mba-introspect reads DEV) and SHIP.
  • audit-mba-l-cc audited · 1w ago
    audit fail: PROD outage: 2b DROP COLUMN broke inserts
    payload
    {"scope":"PROD outage: 2b DROP COLUMN broke inserts","outcome":"fail","evidence":"root cause: drizzle-orm's generated INSERT lists every schema.ts-declared column (dialect.js colEntries), DEFAULT for omitted keys - PROD's running build still declared evento_tipo because schema.ts regeneration/redeploy only happens AFTER introspection, which happens AFTER the DROP. The migration's own DO $gate$ correctly guards DB-state preconditions (2b-prep done, column present, no view dependents) but cannot and does not guard app-build/schema.ts version on the live server - that cross-system precondition was stated as a narrative comment for DEV (pod>=5.6.169) but had no equivalent check or comment for PROD, and no apply script enforces it either side. Gate scope is DB-state only; app-version sequencing needs a separate enforced precondition before any DROP COLUMN step going forward.","reportRef":null}
  • db03-mba-l-cc progress · 1w ago
    db03 2026-10-05 17:58 ART: 2b broke PROD instalaciones inserts (5.6.170 schema.ts still declares eventoTipo; Drizzle INSERT names every declared column). BROKEN fix on PROD ~17:53: ADD COLUMN evento_tipo varchar(50) nullable, no CHECK, view untouched. Proof: svc_nextjs INSERT (instalacion_id, evento_tipo DEFAULT, evento_tipo_id 333, creado_por) -> INSERT 0 1 under ROLLBACK. DEV leg: 2b applied, mba-introspect run, column re-added; DEV without evento_tipo for 7.3 s; no row written (10 rows, max creado_en 2026-02-24 in both bases). PROD and DEV now identical: view md5 f17facb1, evento_tipo nullable and unused, evento_tipo_id NOT NULL. schema.ts regenerated: eventoTipo, its index and CHECK leave instalacionHistorial; vInstalacionHistorial projects eventoTipoId; lineas/externalApiKeys blocks only moved. Step 4 = docs/migrations/2026-10-05-movilba119-fase2c-drop-evento-tipo-readd-DEV-Y-PROD.sql (sha f5199854, gate: column exists, all values NULL, no view uses it), rehearsed under ROLLBACK both bases + wrong-target negative control; applies after PROD+DEV+pod serve the new schema.ts.
  • audit-mba-l-cc audited · 1w ago
    audit pass: 2c DROP COLUMN sha f5199854; schema.ts diff; typecheck
    payload
    {"scope":"2c DROP COLUMN sha f5199854; schema.ts diff; typecheck","outcome":"pass","evidence":"hash matches; gate refuses already-dropped, any non-NULL value, or view dependency; plain DROP COLUMN, no CHECK/index to drop; schema.ts diff confirms eventoTipo removed from instalacionHistorial+view, replaced by eventoTipoId; typecheck clean. File states precondition explicitly: apply only once PROD+DEV+pod all serve this schema - must be confirmed out-of-band before running, same gap that caused the 2b outage","reportRef":null}
  • db03-mba-l-cc completed · 1w ago
    db03 2026-10-05 18:13 ART: done. Phase 2c applied on PROD then DEV from sha256 f5199854 with audit PASS, after coder03 verified PROD, dev01 and the pod on 5.6.171 (serviceId 24338); HEAD and lezama/main schema.ts have no evento_tipo. instalacion_historial now has only evento_tipo_id NOT NULL, FK to opciones 333-338; v_instalacion_historial filters on id 334 and keeps PROD's owner and grants. An app-shaped INSERT succeeds under ROLLBACK on both bases. mba-introspect shows no diff. README row updated to APLICADO (only that line changed, SHIP to coder03). Incident: 2b broke PROD inserts ~17:52-17:53 and was fixed by re-adding the column; it is recorded in the 2c header and in audit's FAIL event.
  • db03-mba-l-cc note · 1w ago
    db03 2026-10-05 18:15 ART: scope of the close. (a) instalacion_historial.evento_tipo is fully converted. (b) vehiculos_tipos_transporte.descripcion is unchanged, per the 2026-10-05 15:29 measurement: it is a dedicated catalog table (1 live row), and its consumer stores the integer id via FK, so it is not text in a business column. Open decision for Elazar: fold dedicated catalog tables into opciones or leave them. If he wants it folded, that is a new item.
tech-debt
2026-08-21 by wi-cli-venus
1w ago
2026-10-05 21:11