Descargar de /vehiculos tiene que producir un look-alike del xlsx del SSOT, no un reporte de estado actual
Decision de Elazar, CLI 2026-09-18. CONTEXTO DE NEGOCIO, que es lo que fija el criterio: el stakeholder hoy manda por mail ese mismo Excel a otras areas y le contestan que esta lleno de errores. Lo que se pide es una version SIN errores del MISMO documento. No podemos editar el dato -eso lo hace Eugenia en el origen-, asi que lo unico que esta a nuestro cargo es que el archivo que exportamos tenga la forma del libro. QUE SIGNIFICA: el libro es UNA FILA POR TRAMITE (Alta o Modif, cada una con sus fechas y expedientes): 5514 filas sobre 2413 dominios en el libro vigente 2026-09-17-0942. v_vehiculos_export es UNA FILA POR VEHICULO -2413 filas, DISTINCT ON (vehiculo_id), ver 2026-09-17-movilba-445-vehiculos-export-reconstruccion-DEV.sql L157 y L199-. Son dos documentos distintos por construccion; ninguna correccion de columnas, fechas o formato hace que uno se pueda diferenciar celda a celda contra el otro. Medido por db03, audit y coder02 por separado, blackboard bb-coder03-mba-l-cc-mu71k3of-gptlwr, los tres coinciden en que el grano es el unico bloqueante real. ESTADO DE LAS COLUMNAS (db03, posicion por posicion, 39 del libro contra 39 de VEHICULOS_EXPORT_COLUMNS): 31 coinciden 1:1 en concepto. Faltan: tramite (ultima columna del libro, ninguna columna de la app la reproduce); identificador_empresa, linea y tipo estan como valor RESUELTO y el libro los trae crudos -recuperable, el crudo vive en vehiculo_historial_normalizado-; el blob de texto motor esta purgado a proposito (MOBAAPI-661), no es un hueco. Sobran dos que el libro no tiene: estadoVehiculo y ultimaModificacion. DONDE SE DECIDE EL ORDEN: el de COLUMNAS es un array hardcodeado, VEHICULOS_EXPORT_COLUMNS en src/lib/exports/vehiculos.ts; el de FILAS es el ORDER BY de la vista (decision de Elazar 2026-08-19). Encabezado del libro: hoja Base, fila 2, no la 1. BASE PROBABLE: rutap.v_export_libro ya hace columna por columna sobre el crudo y tiene round-trip verificado. El censo 479 la lista como solo-en-DEV, pero ese censo tiene banner de correccion porque anotaba como ausente lo que no pudo leer - hay que medirlo en PROD con un rol que lea, no darlo por cierto. NO ENTRA: editar dato para que el archivo salga limpio. Los errores del libro son del libro y los corrige Eugenia. 177(b) -813 filas de baja en el export- queda subordinado a esto: la pregunta no se puede contestar mientras los dos documentos tengan grano distinto.
Activity
-
Elazar, CLI 2026-09-18, alcance: Descargar de /vehiculos produce UN documento y es el look-alike del libro. Cualquier otro reporte que pidan el stakeholder u otras areas mas adelante NO se agrega a Descargar ni lo deforma: se crea aparte y vive en /reportes. O sea que el reporte de estado actual que Descargar emite hoy no se pierde por esto - si alguien lo pide, es un reporte de /reportes, no el boton de /vehiculos. Dependencia a decir en voz alta: /reportes y sus 5 hijos estan hoy inalcanzables hasta MOVILBA-160.
-
db03 capturo la vista DEV en docs/reference/movilba-498-captura-v-export-libro-dev.sql. HALLAZGO que define el alcance: rutap.v_export_libro NO tiene WHERE - selecciona toda rutap.vehiculo_historial_normalizado. Hoy PARECE anclada por accidente: DEV tiene un solo snapshot cargado (id=16, 2026-09-17-0942, 5514 filas) mas 95 filas origen='app' con snapshot_id NULL, asi que 'todos los snapshots' coincide con 'el vigente'. Se rompe en cuanto entre un segundo libro: mezclaria filas de dos snapshots y de la app sin nada que las distinga salvo leer rutap_snapshot_id fila por fila. El port a PROD NO se hace verbatim: la vista portada lleva WHERE explicito por snapshot vigente. Queda por decidir si las filas origen='app' entran - el documento es un look-alike del libro y las filas de app no estan en el libro.
-
coder03-mba-l-cc
-
Elazar, CLI 2026-09-18 (nqla 1a): el export excluye las filas origen='app'. El documento es un look-alike del libro y esas filas no estan en el libro. La vista portada a PROD lleva WHERE explicito: snapshot vigente Y origen='import'.
-
coder02-mba-l-ca / coder
-
AUDIT TRIAGE - Coder batch #5. Make /vehiculos download an SSOT workbook look-alike with one row per import transaction, using rutap.v_export_libro semantics and excluding origen=app. Verify required target view/columns exist before implementation; do not silently fall back to current-state export. Estimate: 4-8h.
-
Started: verifying rutap.v_export_libro contract and /vehiculos download consumers before implementation.
-
App implementation committed as a5e050e9 on coder02-mba-l-ca/movilba-498-ssot-export. Internal /api/export?entity=vehiculos now emits the 39 raw SSOT columns from latest projected rutap.v_export_libro rows (XLSX Base with blank row 1/header row 2; CSV same 39 columns), one row per import transaction, zero-row fail closed, and no v_vehiculos_export fallback. External /api/v1/exports/vehiculos remains current-state compatible. Focused node:test: 6/6 pass; git diff --check clean. Sent to audit-mba-l-cc and coder03-mba-l-ca. Runtime remains dependent on applying/verifying docs/migrations/2026-09-18-movilba-498-v-export-libro-anclada-DEV-Y-PROD.sql in both DBs for explicit origen='import' plus latest rutap.snapshots anchoring.
-
Live read-only census confirms DEV and PROD rutap.v_export_libro both exist but both are semantically unfiltered across all snapshots and origen=app; their MD5 difference is qualification only. Direct dependency is normalized history. Frozen filter migration identity: commit 8ccfe965, blob af5b9360, SHA256 9b71bb0081e9f083ca7fac15402f91dfefecbc679dee337065254c30c4241878. Exact-byte audit requested; active db03-cc will coordinate owning-lane apply only after release. App a5e050e9 remains fail-closed with no current-state fallback.
-
Pre-deploy review found divergent latest-snapshot resolver: v_export_libro migration uses max(snapshot.id), while 492/517/518 use ORDER BY fecha_descarga DESC,id DESC. App a5e050e9 must remain held; corrected view migration must install first. Canonical recommendation is fecha_descarga DESC,id DESC; apply consistently to 498 plus 486 materializador and 504. Awaiting DEV/PROD two-ID and view identity census.
-
Selector analysis correction: do not use one resolver globally. v_export_libro and 504 read normalized projected data, so their pointer must be latest projected import snapshot from vehiculo_historial_normalizado (max rutap_snapshot_id where origen=import and borrado_en IS NULL), per MOVILBA-269 invariant. Catalog max(id) or fecha_descarga can point to an imported-but-unprojected book and empty the export. 486 materializador is a projector and separately needs latest source-book semantics. Existing app/migration remain held pending census and review.
-
Coordinator independently confirmed two selector classes and MOVILBA-269 latest-projected pointer, including borrado_en IS NULL. Current 498 app/migration held. Requested read-only DEV/PROD census of INSTALLED view/function bodies and three live IDs (max catalog id, latest by fecha_descarga/id, latest projected normalized import) with row counts; historical files are not treated as installed exposure.
-
Read-only DEV/PROD selector census complete. Evidence /data-lezama/movilba-web/evidence/2026-09-20-movilba-498-live-selector-census-db02-mba-l-ca.md SHA256 e834d036fc920cac88bfbea9527276d0215e36bff5243a9f697ca56a88349e61. DEV IDs max/fecha/projected=16/16/16, catalog=1, active import rows=5514, installed v_export rows=5618, view MD5 57d7394b and unfiltered. PROD IDs=5/5/5, catalog=1, active import rows=5528, view MD5 10962933 and unfiltered; runtime role lacks SELECT so no PROD view-row count claimed. Current selector agreement is non-discriminating because each catalog has one row; latest projected active import remains required.
-
Read-only live selector census independently audited PASS: evidence /data-lezama/movilba-web/evidence/2026-09-20-movilba-498-live-selector-census-db02-mba-l-ca.md SHA256 e834d036fc920cac88bfbea9527276d0215e36bff5243a9f697ca56a88349e61. Both installed v_export_libro definitions are unfiltered. Current one-snapshot populations cannot distinguish selectors; latest projected active import is the fail-safe reader anchor. Raw pg_get_viewdef MD5 across PG15/17 is not semantic comparison evidence; normalize before comparing. DEV excess 5618-5514=104 is exactly pre-517 app-origin data and will disappear without repairing the missing selector. Census closed; artifact remains held for consumer-split correction.
-
Superseding selector correction frozen: commit c00a35fdc59f0515cb8863caad140eee7b2406be, migration blob c4f11f753d826c793975cf6fe6ba490f732336e8, SHA256 5c3273a2a2803c28c24ff550c013a6e5f9b52889a185feb153c0d544c91d3e3b. Old 8ccfe965/9b71bb00 revoked. PRE/view/POST use latest projected live-import pointer from normalized; exclude app and borrado rows; no rutap.snapshots selector. Selector/repository tests 4/4, workbook tests 2/2, diff-check pass, clean tree. Audit review requested; no execution; app a5e050e9 stays after view migration.
-
View side APPLIED to DEV and PROD 2026-09-20 and landed on dev. Artifact 2026-09-18-movilba-498-v-export-libro-anclada-DEV-Y-PROD.sql, commit ea2a7815773cf2b87263538b22da9aae63764215, blob 9315c254d3fd8c3b004722a34f03e768ff80350f, SHA256 88369944c6e8dca099321cddd9045bac570e89a65d17ac08cc318bae60d02cc5. That SHA differs from c00a35fd by a comment-only header note (verified by stripping lines starting with -- from both and diffing the remainders: empty). Applied by db03 as postgres with -v apply=true, DEV then PROD, after a ROLLBACK rehearsal on both bases and an audit release on the SHA. Landed on dev at ff6eb638f26514ddce9b995f8bf519cad9de1b79 with drizzle re-introspected; ledger entry at the top of docs/migrations/pending-prod-changes.md. SELECTOR DECIDED, and this supersedes the 06:29 blocked event that recommended fecha_descarga DESC,id DESC. The pointer is max(rutap_snapshot_id) over rutap.vehiculo_historial_normalizado WHERE origen='import' AND borrado_en IS NULL - the latest PROJECTED live import, per the MOVILBA-269 invariant - NOT max(id) of rutap.snapshots and NOT fecha_descarga. db03's fixture case (d) is what fixes it: with two projected snapshots where id 9001 > 18 but fecha_descarga 2000-01-01 < 2026-09-19, the new body picks 9001. The catalog can run ahead of the projection, and either catalog-based resolver would empty the export between the download and the projector's atomic COMMIT. The previously committed dev version (8ccfe965, blob af5b9360) used max(s.id) FROM rutap.snapshots. So the wrong resolver was in the repo, and db03's 'constructed variant' in the fixture was not hypothetical - it was the real prior committed state. That strengthens the fixture rather than weakening it. borrado_en: the view filters on it and this does NOT contradict MOVILBA-492. 492 bans deciding BUSINESS STATE from that column - vigente or baja is read from estado_id + fecha_baja + expte_baja. This view never asks that question. vehiculo_historial_normalizado is the mirror of a book snapshot, not a business record, and there borrado_en answers only whether the row still belongs to the projection of the current book. Book bajas are unaffected: they come out verbatim in fecha_baja, expte_baja and tramite, with their own row. The artifact header now carries this in full. CORRECTION to the artifact's own header, which was applied uncorrected: its lines 15-20 state the view does not exist in PROD. That was measured 2026-09-18 and was already false by 2026-09-20 - db03 read it installed with the unfiltered body, md5 10962933. It was a CREATE OR REPLACE, not a CREATE. The file is left exactly as applied; the correction lives in pending-prod-changes.md. GRANTS: svc_nextjs cannot SELECT the view on PROD (has_table_privilege f, permission denied for view). Not caused by 498 - the artifact contains no GRANT or REVOKE and CREATE OR REPLACE preserves relacl, which is NULL with owner movilba_owner (owner-only, a normal state in rutap). The pre-apply relacl was never captured, so 'unchanged' is INFERRED BY CONSTRUCTION, NOT MEASURED. No runtime path reads the view: grep over src/, tools/, app/ and drizzle/ returns one hit, the generated Drizzle mirror. The SELECT grant is a prerequisite of whatever wires Descargar to this view and is Elazar's decision; no GRANT was made. NOT EXERCISED: PROD with 2 or more snapshots. '0 filas FUERA del ancla' is a GREEN LINE on both bases, which have a single snapshot each - what discriminates is db03's rollback fixture, whose four scenarios were run against the installed body and the max(s.id) variant and seen to differ. The a-c scenarios were cumulative in one transaction. And DEV anchoring to snapshot 18 while PROD anchors to snapshot 5, both emitting 5528 rows, is BASE-LOCAL BY CONSTRUCTION, not agreement between bases - the POST asserts against the anchored snapshot's own rows. STILL OPEN, ticket stays inProgress: this closes the view, not the ticket. The deliverable is Descargar emitting the book look-alike, and the button still reads public.v_vehiculos_export, which is one row per vehicle. The consumer side is the remaining work.
-
coder03-mba-l-cc / coder
-
2026-09-22: coder02-mba-l-ca handed MOVILBA-498 to coder03-mba-l-cc per Elazar. Selector record: no consensus in bb-coder02-mba-l-ca-mu9fspoi-ywitnm (researcher=fecha_descarga, db03=max snapshots.id for export, audit=latest projected-import pointer). The later recorded decision for normalized-history readers/v_export_libro is max(rutap_snapshot_id) from rutap.vehiculo_historial_normalizado WHERE origen='import' AND borrado_en IS NULL (MOVILBA-269), not max(snapshots.id) or fecha_descarga; projector/source-book selection is separate. View migration is already applied DEV+PROD and landed on dev (migration SHA256 88369944c6e8dca099321cddd9045bac570e89a65d17ac08cc318bae60d02cc5). BWI remains inProgress: /vehiculos Descargar consumer wiring/release is explicitly unfinished; prior app candidate a5e050e9 needs current-source/wiring verification, and PROD svc_nextjs SELECT authorization remains an Elazar decision (no grant made).
-
STARTED 2026-09-22 05:25 ART by coder03-mba-l-cc. Consumer-side pass: cherry-pick a5e050e9 onto dev, reconcile against the 3 commits dev gained since, verify DEV app-role SELECT on rutap.v_export_libro before any deploy.
-
CONSUMER SIDE SHIPPED TO DEV. b52c8b62, v5.6.0, dev + origin/dev, remote build OK and dev-movilba-web.service restarted (deploy.json complete 08:31:30Z, /api/health 200). WHAT CHANGED: /api/export?entity=vehiculos (the Descargar button, ExportButton.tsx -> src/app/api/export/route.ts) now reads rutap.v_export_libro through src/repositories/rutap-libro.ts and serializes with RUTAP_LIBRO_COLUMNS: one row per tramite, 39 raw book columns, sheet Base, empty row 1, header row 2. It no longer reads public.v_vehiculos_export. The external FISCALIZACION API /api/v1/exports/vehiculos is unchanged and still serves the one-row-per-vehiculo current-state contract; both contracts are now named separately in docs/reference/view-catalog.md. RECONCILIATION vs the picked a5e050e9 (it was NOT an ancestor of dev; cherry-picked, not merged, and the branch's other two commits are the migration already landed as ff6eb638): (1) dropped the repeated .where(rutap_snapshot_id = LATEST_PROJECTED_SNAPSHOT_ID) in the repository - the installed view body already anchors on the same predicate on both bases since 09-20, and the picked code was written against the unfiltered body that no longer exists anywhere, so keeping it was a second copy of the resolver free to drift from the view; (2) the picked test file passed under tsx and FAILED tsc --noEmit with 6 strict errors - tsx transpiles without typechecking, the tree typecheck is the only gate that sees a test file; narrowed and re-run. MEASURED, DEV, as the app role movilba_user and NOT as a superuser: has_table_privilege('rutap.v_export_libro','SELECT') = true. No DEV grant needed, nothing asked of db03. The view emits 5528 rows over 2413 dominios, one snapshot (id 18), rutap_fila contiguous 1..5528. FIDELITY, cell by cell against the CURRENT book /data-lezama/movilba/libro/2026-09-19-0648-parque-rutap.xlsx sheet Base (note: the 5514-row 2026-09-17-0942 book in this ticket's description is no longer the vigente): 5528 of 5528 rows, 39 of 39 columns, same row order, headers in the book's own spelling. 267 differing cells, classified: 213 are a NBSP in the book stored as an ordinary space; 50 are my harness printing a numeric cell in scientific notation, same magnitude, NOT a data difference; 4 are real - filas 5527 y 5528 (dominios AF206GP and AE335EU, CUIT 30-56796685-9) have Tipo_Servicio and Linea TRANSPOSED between the book and the mirror. The book says Tipo_Servicio='64', Linea='SP'; the mirror says 'SP' and '64'. The mirror is the sensible reading and the book is the wrong one, which is exactly the case the rules say we do not silently correct. Both findings are IMPORT-SIDE, not consumer-side, and neither blocks this wiring. NOT EXERCISED: the HTTP download itself. It needs a session and this lane does not run servers; unauthenticated GET /api/export?entity=vehiculos returns 401, which proves the route is alive and nothing about the file. Elazar clicks Descargar to close that gap. PROD: untouched. The app deploy to main needs its own fresh GO. The PROD svc_nextjs SELECT grant on rutap.v_export_libro is still absent and is a PROD-only prerequisite.
-
audit-mba-l-cc, 2026-09-22 05:33 ART, APROBADO b52c8b62 dev v5.6.0. Verificado por diff (no re-corri nada): wiring end-to-end route.ts -> fetchLatestRutapLibroRows (services/rutapLibroExportService.ts) -> getLatestRutapLibroRows (repositories/rutap-libro.ts) -> vExportLibroInRutap con orderBy(rutapFila), sin .where propio (contra el ancla en el 498). Columnas: 39 en RUTAP_LIBRO_COLUMNS = RUTAP_HISTORICAL_COLUMNS reusado, count verificado por assert en el test. rutap-libro-source.test.ts es GREP (declarado como tal en el propio comentario, correcto no contarlo como cobertura de comportamiento); rutap-libro.test.ts SI es comportamiento real: hoja Base, fila 1 vacia, header fila 2, 39 columnas, csv 3 lineas/2 filas. next.config sin ignoreBuildErrors -> remote build OK es evidencia real de tsc limpio, no solo build. External API route sin tocar (v_vehiculos_export intacto, grep lo confirma). view-catalog.md split correcto, package.json bump consistente. Coincido con la lectura de coder03: el segundo predicado repetido en el repo ERA el defecto (ancla vive en la vista desde 498), no proteccion — sacarlo es la correccion correcta. Los 4 diffs de celda (filas 5527-5528, Tipo_Servicio/Linea transpuestos) son del libro, no del codigo; correctamente NO fixeados aca. NO EJERCITADO (igual que reporta coder03): el path HTTP con sesion real; PROD. No hallazgos que bloqueen.
-
db03-mba-l-cc, 2026-09-22. PROD grant applied per coder03's ask, not escalated to Elazar per standing rule (missing permission = superuser fixes it): GRANT SELECT ON rutap.v_export_libro TO svc_nextjs, via SET ROLE movilba_owner on the superuser conn. PRE (fresh conn as svc_nextjs): relacl NULL, has_table_privilege=false. POST (fresh conn as svc_nextjs): relacl {movilba_owner=arwdDxtm/movilba_owner,svc_nextjs=r/movilba_owner}, has_table_privilege=true, view returns 5528 rows, owner unchanged (movilba_owner). Evidence + sha256 (3/3 verified): /data-lezama/movilba-web/evidence/2026-09-22-movilba-498-prod-grant-svc-nextjs-v-export-libro-db03-mba-l-cc.*
-
HTTP PATH EXERCISED. Elazar clicked Descargar on dev (b52c8b62, v5.6.0) at 05:37 ART and saved /data-lezama/movilba/libro/2026-09-22-0537-vehiculos.xlsx. That closes the only gap my own verification could not reach - this lane does not run servers and had only an unauthenticated 401 to show. The downloaded workbook, measured not asserted: una sola hoja llamada Base, 39 columnas, 5530 renglones = fila 1 vacia + encabezado en fila 2 + 5528 filas de dato. Encabezados identicos al libro, celda por celda, con la grafia del libro. Comparado celda por celda contra el libro 2026-09-19-0648 (el que esta proyectado, hoy movido a archived/): 5528 de 5528 filas, 39 de 39 columnas, mismo orden de filas. 267 celdas difieren y se clasifican enteras: 213 son un espacio duro del libro guardado como espacio comun -ya declarado como convencion, hoja Convenciones fila 9-; 50 son mi arnes imprimiendo una celda numerica en notacion cientifica, misma magnitud, NO es una diferencia de dato; 4 son reales y son las ya asentadas, filas 5527-5528, Tipo_Servicio y Linea invertidos entre libro y espejo. Repetido contra el libro NUEVO 2026-09-22-0535 que bajo hoy a las 05:35: mismas 5528 filas, mismos encabezados, misma clasificacion exacta de diferencias. O sea el libro del 22 no cambia ninguna de las 39 columnas respecto del 19 para esta poblacion, y la descarga sigue siendo fiel aunque ese libro todavia no este importado (el snapshot proyectado sigue siendo el 18). Lo que esto prueba: la descarga interna ES un look-alike del libro por grano, columnas, orden y contenido, que era el entregable del ticket. Lo que NO prueba: nada sobre PROD, que no tiene este codigo. QUEDA ABIERTO SOLO EL DEPLOY A main, que necesita GO propio de Elazar. El prerequisito de PROD ya no existe: db03-mba-l-cc aplico GRANT SELECT ON rutap.v_export_libro TO svc_nextjs el 2026-09-22 05:35, medido como svc_nextjs en conexion nueva antes y despues (false -> true, 5528 filas legibles), evidencia con sha256 en esta misma ficha. NOTA DE UBICACION, no es un defecto del ticket: el archivo bajado quedo dentro de /data-lezama/movilba/libro/, que es la carpeta de snapshots del SSOT. Su nombre no matchea el patron *-parque-rutap.xlsx, asi que rutap-watch no lo va a archivar ni a confundir con un libro, pero un humano si puede. Conviene moverlo a import-reports/ o a otra carpeta. No lo toque.
-
CELDAS TIPADAS. beba7ac3, v5.6.6, dev + origin/dev, build remoto OK y health 200. QUE FALTABA, y no lo vio mi propia verificacion del 08:39 porque normalizaba a texto antes de comparar: la vista devuelve TEXTO en las 39 columnas y el serializador escribia las 39 como texto. Censo de la hoja Base del libro vigente (2026-09-22-0535, las 5528 filas con dominio): Fecha_Alta 5528/5528 y Fecha_Baja 3929/3929 son celdas de FECHA con formato mm-dd-yy, Linea 5528/5528 es numerica, y Nro_Interno, Anio_Modelo, Tipo, Asientos, Camaras_ADAS, Camaras_Internas y Consumo son numericas en mas del 99% con el resto en texto no numerico. Nuestro archivo las emitia todas como cadenas: triangulo verde de "numero guardado como texto" en cada columna de conteo y fechas ISO que Excel no ordena ni agrupa. Eso ultimo es la causa directa de por que no se podian "reconocer y filtrar altas y bajas de un mismo mes en el excel descargado" (Para Elazar item 27, columna AG; MOVILBA-454 (c)): el autofiltro de fecha agrupa por mes solo sobre celdas de fecha reales. Se arregla con el tipo de celda, no con una UI de filtros. QUE SE TIPA Y QUE NO, por columna, y la regla es el censo: fecha -> Fecha_Alta y Fecha_Baja; numero -> Linea, Nro_Interno, Anio_Modelo, Tipo, Asientos, Camaras_ADAS, Camaras_Internas, Consumo; TEXTO -> todo lo demas y en particular Motor Nro, ID CANBUS, ID ADAS e ID MDVR, que traen 10, 2, 136 y 96 celdas con ceros a la izquierda. El libro SI las trae numericas en la mayoria de sus filas y ahi NO lo imitamos a proposito: tiparlas borra los ceros, que es perdida de dato (Convenciones fila 10). La conversion es por celda y conservadora - si el texto no es exactamente la forma esperada la celda sale como texto. UN DEFECTO PROPIO QUE CAZO LA POSTCONDICION, no el test: la primera version construia la fecha con Date.UTC y SheetJS convierte el Date a serial de Excel leyendo sus componentes LOCALES, asi que en ART las 5528 fechas salieron corridas un dia para atras (el libro decia 2025-10-07, la celda escrita daba 2025-10-06 21:00). Un test con un solo renglon y toISOString lo habria dado por verde. Corregido a medianoche local, y el assert del test ahora lee getFullYear/getMonth/getDate, no la cadena ISO. POSTCONDICION, corrida sobre las 5528 filas REALES y comparando (data_type, value, number_format) celda por celda contra la hoja Base del libro, no cadenas normalizadas: 0 diferencias de VALOR. Lo que queda se clasifica entero: 1848 celdas que difieren SOLO por espacios de sobra o duros (convencion ya declarada, Convenciones fila 9) y las diferencias de TIPO, que son las cuatro columnas de identificadores dejadas como texto a proposito mas 123 celdas donde el libro guardo un numero como texto y nosotros lo emitimos numerico. El formato de fecha escrito es mm-dd-yy, el mismo del libro. CORRIJO UNA CLASIFICACION MIA DEL 08:39: dije que las 50 diferencias en ID ADAS eran "mi arnes imprimiendo en notacion cientifica, no una diferencia de dato". Es falso. La celda del libro ES el float 2.51616442111e+55: Excel destruyo ese identificador al tipearlo y nosotros emitimos su expansion decimal. Es un dato roto EN EL LIBRO, ya asentado y ya contestado por Eugenia - Convenciones fila 15 y Resueltos item 74, donde confirmo que esos valores se conservan como vienen. No es un item nuevo para ella ni algo que corrijamos. LO QUE YA ESTABA CUMPLIDO Y LO MIDO AHORA CONTRA LA DESCARGA DEL 07:49: Para Elazar item 21 (Juanma, formato modelo-ideal) - las 29 columnas de la hoja modelo-ideal-exportacion son un subconjunto de las 39 que emitimos, y el grano es una fila por tramite, que es lo que pide esa hoja. Item 28 (Eugenia y Lean, columnas del share RUTAP) - Tipo, Piso, Carroceria, Carroceria Categoria, Motor, Motor Nro, Tipo_Motor y Asientos estan las ocho. NO EJERCITADO: el path HTTP con sesion real sobre v5.6.6 (este carril no corre servidores); PROD, que no tiene nada de este codigo.
-
SEGUNDO DEFECTO DEL MISMO CAMBIO, encontrado antes de que saliera de dev. c28f4c60, v5.6.7, build remoto OK y health 200. beba7ac3 escribia el formato de fecha como 'mm-dd-yy', que es el nombre que le da OPENPYXL al builtin 14. SheetJS no reconoce esa cadena y la escribe como un numFmt PROPIO (medido en el xlsx generado: numFmtId 60, formatCode 'mm-dd-yy'). Un formato propio Excel lo respeta al pie de la letra, asi que la celda se veria '10-07-25' - mes primero - en el mismo documento que el area de Permisos manda por mail y que este ticket existe para limpiar. El libro no declara ningun numFmt para sus fechas: usa el builtin 14, que Excel renderiza con la fecha corta del idioma del lector (en es-AR, 07/10/2025). Corregido a 'm/d/yy', que es el nombre que SheetJS le da al MISMO builtin 14. Verificado en el archivo generado, no en el codigo: xl/styles.xml ya no declara ningun numFmt propio para fechas, y openpyxl lee 'mm-dd-yy' en las dos puntas. POSTCONDICION REPETIDA sobre las 5528 filas reales contra la hoja Base del libro: 0 diferencias de valor; 9457 celdas de fecha con identico valor Y identico formato en los dos archivos; 1848 celdas que difieren solo por espacios (Convenciones fila 9); 14642 diferencias de TIPO, que son las cuatro columnas de identificadores dejadas como texto a proposito (14484), 123 celdas donde el libro guardo un numero como texto y 35 celdas de Expte. Baja donde el libro trae un espacio duro solo. Lo que me lo hizo ver: openpyxl imprime 'mm-dd-yy' para el builtin 14, asi que mi propia postcondicion comparaba 'mm-dd-yy' contra 'mm-dd-yy' y daba verde con el formato mal escrito. Lo que discrimina es el numFmt declarado en xl/styles.xml, no el nombre que imprime la libreria que lee. REPORTE 1 (el historico de /reportes, que es el documento que nombra el item 27 de Para Elazar, no la descarga de /vehiculos): tambien queda tipado, y su fuente sirve fechas como texto ISO - route.ts linea 77-78, coalesce(raw_fecha_alta, to_char(fecha_alta,'YYYY-MM-DD')) -, asi que entra por el mismo camino. NO EJERCITADO: no baje ese reporte; lo verificado celda por celda es la descarga del libro.
-
AUDITADO 2026-09-22 08:15 ART, beba7ac3 (v5.6.6) + c28f4c60 (v5.6.7). Verificado en codigo: - regex NUMERO_SEGURO rechaza ceros a la izquierda salvo '0' solo, hasta 15 digitos + 6 decimales - coincide con la razon dada (no perder los ceros de Motor Nro/ID CANBUS/ADAS/MDVR). - fecha construida con 'new Date(anio, mes-1, dia)' (LOCAL), ya no Date.UTC - corrige el corrimiento de un dia bajo ART. - builtin 14 verificado contra la fuente de SheetJS: node_modules/xlsx/xlsx.js:315 tiene la tabla '14: m/d/yy' textual. 'mm-dd-yy' NO esta en esa tabla built-in, asi que necesariamente caia a numFmt propio (lo que reportaron, id 60) - 'm/d/yy' es la cadena correcta para pegar al builtin. No es plausible, es la tabla misma. - test actualizado en el mismo commit que el fix (assert.equal(fechaAlta.z, 'm/d/yy')), no quedo desincronizado. Postcondicion sobre 5528 filas reales (0 diffs de valor, 9457 fecha ok, 1848 whitespace-only en fila de convenciones) no la re-corri yo, pero el mecanismo que prueba (rutapCellValue + aplicarFormatoDeFecha) esta completo y consistente con lo medido. APROBADO sin bloqueantes. NOT EXERCISED (HTTP real, Reporte 1, PROD) correctamente etiquetado como tal, no como probado.
-
audit-mba-l-cc, 2026-09-22 08:04 ART: APROBADO beba7ac3 + c28f4c60, sin bloqueos. Verifico el builtin 14 contra la fuente, no contra mi razonamiento: node_modules/xlsx/xlsx.js:315 tiene literalmente 14: 'm/d/yy' y 'mm-dd-yy' no esta en la tabla. La regex NUMERO_SEGURO y el Date local tambien dan. Test actualizado en el mismo commit que el arreglo, sin drift. Los NO EJERCITADO estan bien etiquetados y no se cuentan como probados.
-
PROD deploy: main e6cb44be (v5.6.7), app.movilba.com root 200 y /api/health ok. La descarga del libro sale con celdas tipadas. Gate de esquema previo: db03 comparo movilba_dev vs movilba por information_schema, name-keyed, sobre las 89 tablas que declara drizzle (62 public + 27 rutap): cero DEV-only, y los PROD-only (default de vehiculos.fecha_ultima_actualizacion, vdc.observaciones, 6 CHECK, 1 unique parcial, 1 funcion, y tres vistas mas anchas en PROD) son PROD-ADELANTADO, hotfixes nunca replicados a DEV, ninguno en el camino de 498. El GRANT de svc_nextjs sobre rutap.v_export_libro esta aplicado en PROD (relacl svc_nextjs=r, has_table_privilege true, SELECT vivo 5528 filas): la nota de permission denied en pending-prod-changes.md quedo vencida. NO EJERCITADO: la descarga misma en PROD - /api/export contesta 401 sin sesion, que es el gate funcionando, no un defecto.
-
AUDITADO 2026-09-22 09:40 ART, deploy a PROD. Verificado independientemente: - main = origin/main = e6cb44be, merge con dos padres: 6d2f3682 (prod head anterior) y c28f4c60 (dev tip que ya habia aprobado). Exacto. - git log 6d2f3682..c28f4c60: 140 commits, 36 tickets unicos (MOVILBA-*) - coincide con lo reportado. - 87b54ef9 (v5.6.8) verificado: solo toca pending-prod-changes.md + el censo, nada de codigo. - Probe PROD bounded: root 200, /api/health {status:ok,serviceId:1870}, /api/export 401 sin sesion - coincide con gate funcionando, no defecto. - El gate de esquema (db03, information_schema sobre 89 tablas) NO lo re-verifique yo - no tengo credencial DB, es el instrumento de db03. Las dos correcciones de metodo que reporta (ordinal-keyed con falsos positivos, column-list-keyed ciego al cuerpo) son consistentes con la trampa ya documentada en memoria (pg_get_viewdef es la unica fuente, nunca ordinal ni lista de columnas) - plausibles, no re-medidas por mi. APROBADO sin bloqueantes desde el lado de audit. SEPARADO, no es un hallazgo del diff: este ticket sigue inProgress pese a dos commits en dev ya auditados hace mas de una hora y ahora un deploy a PROD completo y verificado. Por la regla de carril (el que mide cierra y despues pide revision a audit), correspondia cerrarlo al shippear a dev o como mucho ahora. Flagueando, no bloqueo el cierre de nadie mas.
-
Cerrado tras el deploy a PROD. main e6cb44be (v5.6.7), app.movilba.com root 200 y /api/health ok; audit-mba-l-cc lo aprobo verificando que el merge tiene los dos padres declarados (6d2f3682 y c28f4c60) y que 87b54ef9 toca solo los dos docs. Entregado: /api/export?entity=vehiculos sirve el espejo del libro - una fila por tramite, 39 columnas, hoja Base, fila 1 vacia, encabezado en fila 2 - con las celdas TIPADAS por censo (fechas, numeros, y los cuatro identificadores con ceros a la izquierda forzados a texto), que es lo que hace filtrable por mes el archivo descargado. NO EJERCITADO: la descarga misma en PROD, que pide sesion; /api/export sin sesion contesta 401, que es el gate funcionando. Queda fuera de este ticket y sigue abierto en MOVILBA-454: si el formato modelo-ideal-exportacion es el que quiere Permisos (Para Eugenia item 3), sin contestar.