basquetWi + New ticket
movilba MOVILBA-384

El admin de carrocerias rechaza el duplicado case-insensitive con un 400 generico: falta el pre-chequeo normalizado y el mensaje de negocio - el 23505 YA estaba mapeado, mi descripcion original decia lo contrario

Done low cmcoder03-mba-l-cc

MEDIDO POR db02-mba-l-cc el 2026-09-08 justo despues de aplicar MOVILBA-380, leyendo el codigo del escritor. NO es un defecto de 380: es una superficie de la app que 380 deja expuesta. MOVILBA-380 instalo `ux_carrocerias_fabricante_modelo`, UNIQUE sobre (fabricante_id, upper(btrim(carroceria_modelo, <set>))). Es case-insensitive a proposito. EL ESCRITOR NO LO CONTEMPLA. `src/repositories/carrocerias.ts:176` create() y `:255` update(), detras de /api/admin/carrocerias y del admin UI. `src/services/carrocerias.ts` NO chequea duplicados antes de insertar, y su validate solo exige que carroceriaModelo no sea vacio (linea 253). Ninguna capa mapea el SQLSTATE 23505. SINTOMA: cargar desde el admin una carroceria que difiera SOLO en mayusculas de una existente ahora tira un error de base SIN MANEJAR. El usuario ve un fallo crudo en vez de "ya existe esa carroceria". LO QUE SI ESTA BIEN Y NO HAY QUE TOCAR: el CHECK de bordes no le puede abrir un 500 a nadie, porque create y update ya normalizan con `.trim()` de JS (lineas 178 y 243) y el trim de JS es MAS ancho que el conjunto de la base - saca NBSP y U+2000-200A/U+FEFF. Solo el UNIQUE queda sin mapear. ARREGLO, en el carril de codigo, sin tocar la base: chequear el duplicado normalizado ANTES de insertar y devolver un ApiException con mensaje de negocio, Y ADEMAS mapear 23505 como red de seguridad - el chequeo previo tiene una carrera y el mapeo la cubre. Las dos cosas, no una. Vale la pena medir de paso si otras superficies de admin tienen el mismo hueco con otros uniques. NO EJERCITADO: la pantalla no se abrio; esto sale de leer el codigo y de saber que el indice existe. Hay que reproducirlo en dev01 antes de cerrarlo. PROD no tiene el indice todavia.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 5w ago
  • wi-cli-venus note · 5w ago
    CORRECCION DE MI PROPIA DESCRIPCION. La midio coder-mba-l-ca el 2026-09-08 leyendo el codigo, y dos afirmaciones mias eran falsas. LO QUE YO ESCRIBI: "ninguna capa mapea el SQLSTATE 23505" y "el usuario ve un fallo crudo de base". LO MEDIDO: el 23505 SI esta mapeado. `handleApiError` desenvuelve las causas de Drizzle y lo mapea a DUPLICATE_ENTRY, que sale como 400 (src/lib/errors.ts:258 y src/lib/database-error-mapper.ts). O sea que el usuario NO ve un error crudo de base: ve un 400 generico de duplicado. QUE QUEDA REALMENTE COMO DEFECTO, que es mas chico y mas preciso: 1. No hay chequeo de duplicado normalizado ANTES de insertar. `src/services/carrocerias.ts:253` solo exige que carroceriaModelo no sea vacio. 2. El mensaje es generico y no nombra el caso: una carroceria que difiere SOLO en mayusculas de una existente es rechazada, pero sin decir cual es la que ya existe ni por que. El arreglo sigue siendo el mismo de las dos mitades y por la misma razon: pre-chequeo normalizado con un ApiException de negocio, y la red de seguridad sobre el 23505 reusando el extractor que ya existe, porque el pre-chequeo tiene una carrera. Lo que cambia es que la segunda mitad es REUSO, no construccion. Y agrego una condicion: el mapeo se discrimina por NOMBRE del indice, no por el SQLSTATE pelado. Un 23505 de otro unique de la misma tabla no puede renderizar "ya existe esa carroceria" - un mensaje equivocado dicho con confianza es peor que el error crudo. DE DONDE SALIO EL ERROR: yo mire el repositorio y el servicio, vi que ahi no habia mapeo, y concluí que no lo habia en ninguna capa. El mapeo estaba una capa mas arriba, en el manejador de errores compartido. **Ausencia en las capas que abri no es ausencia en el sistema** - la misma forma que ya me mordio en MOVILBA-383 con el censo de FKs. Owner: coder-mba-l-ca. Ship con regresion mockeada; la reproduccion en dev01 va DESPUES del fix y la coordino yo, porque hay un usuario real cargando datos en la misma pantalla.
  • wi-cli-venus titleChanged · 5w ago
    El admin de carrocerias rechaza el duplicado case-insensitive con un 400 generico: falta el pre-chequeo normalizado y el mensaje de negocio - el 23505 YA estaba mapeado, mi descripcion original decia lo contrario
  • wi-cli-venus assigned · 5w ago
    coder-mba-l-ca
  • wi-cli-venus note · 5w ago
    Implemented normalized total-index duplicate precheck for create/update (partial effective key, self exclusion) plus named ux_carrocerias_fabricante_modelo 23505 safety net using existing PG extractor. 12 local unit regressions pass; no DB/browser writes. Deploy v5.5.89 in progress. Live post-deploy verification is scheduled through coder02, not a shipping prerequisite. Other surfaces: fabricantes wraps PG error in new Error without cause, loses code; chasis same wrapper but no natural-key UNIQUE in checked schema, live census not asserted; opciones preserves PG error and receives generic400 for uq_opciones_grupo_campo_valor_active. No fixes outside384.
  • wi-cli-venus note · 5w ago
    Carrocerias deployed bff7a9d8 v5.5.89; deploy lint/typecheck and health/freshness PASS, audit-mba-l-cc PASS. Scope expanded by coder02 to fabricantes normalized precheck plus preserve original errors and map named unique indexes; follow-up pending priority360 deploy by coder04. Explicitly correct historical premise: old uq_fabricantes_fabricante_active already existed; new normalized index broadens reachable collisions, not first possible unique error. Live verification scheduling stays with coder02.
  • wi-cli-venus note · 5w ago
    Adjacent-admin measurement complete: MOVILBA-385 files opciones message quality only. db03 SELECT-only DEV10:18 confirms public.chasis only unique chasis_pkey(id), no natural-key UNIQUE; FK chasis_fabricante_id_fkey. Chasis wrapper can lose metadata but model-duplicate path not present; no chasis edits. Fabricantes follow-up18 local unit tests PASS including compiled SQL, named-index errors, original error/cause identity and shared HTTP400 for other23505/CHECK/FK. Existing fabricantes persistence remains literal; no new trimming policy.
  • wi-cli-venus note · 5w ago
    Fabricantes follow-up independently audit PASS (audit-mba-l-cc, 18/18 mocked unit tests). Committed cd009798 v5.5.91 after fast-forward to 360 commit 4dece879; deploy-script lint and full typecheck PASS. Remote build/push still in progress; live health/freshness not yet confirmed. Includes both normalized and pre-existing raw-name UNIQUE mappings, original SQLSTATE/cause preservation, normalized precheck, and constraint/error-path lesson.
  • wi-cli-venus note · 5w ago
    Follow-up cd009798 v5.5.91 deployed successfully: normal script exit0, lint/typecheck/health/freshness PASS; dev01-deploy lock released. Independent audit PASS 18/18. Live browser duplicate verification remains coordinated through coder02; no UI proof claimed.
  • wi-cli-venus assigned · 4w ago
    coder-mba-l-cc
  • wi-cli-venus assigned · 4w ago
    coder03-mba-l-cc / coder
  • coder03assistant-mba-l-ca completed · 3w ago
    coder03assistant-mba-l-ca | 2026-09-24 04:11:40 ART | dev 7d299b6a / main 721b9eb8 CarroceriasService prechecks normalized fabricante/modelo on create/update; repository predicate matches trimmed case-insensitive index, and 23505 mapping discriminates constraint name. Index ux_carrocerias_fabricante_modelo exists in DEV movilba_dev and PROD movilba. Browser duplicate submission not exercised; requested dual guard implemented.
bug
5w ago by wi-cli-venus
3w ago
2026-09-24 07:11