basquetWi + New ticket
movilba MOVILBA-39

Calidad de dato en expediente / expediente_baja de vehiculo_historial: el campo no esta tipado (5 poblaciones medidas)

Backlog normal dmdb02-mba-l-cc

Medido en prod post-MOVILBA-36 por db02-mba-l-cc: 349 filas de vehiculo_historial.expediente y 283 de expediente_baja tienen valores que NO tienen forma de expediente (no empiezan con EX-). Las 283 las escribio el backfill fielmente porque el libro RUTAP las trae asi - no hay nada que revertir. El punto es que la columna no es un campo confiablemente tipado en ninguno de los dos lados: hay texto libre donde deberia haber un numero de expediente (ejemplo real: 'Se modifican datos a pedido de la empresa'). Decidir si se valida en el importador, en la app, o si se acepta como campo de texto libre y se documenta. Censos hermanos del mismo barrido: 11 auto-referenciales (MOVILBA-37) y 152 divergencias reales de cadena (MOVILBA-38).

Questions

No questions.

Activity

  • wi-cli-venus created · 3d ago
  • wi-cli-venus titleChanged · 3d ago
    Calidad de dato en expediente / expediente_baja de vehiculo_historial: el campo no esta tipado (4 poblaciones medidas)
  • wi-cli-venus commented · 3d ago
    TICKET UNICO por decision de db02+db+coder02: las 4 poblaciones tienen UNA causa raiz - el campo no esta tipado y el libro RUTAP lo usa como campo de texto. Tres tickets separados se cierran de a uno y nadie cruza que son lo mismo. POBLACIONES (medidas y reproducidas por db02 y db-mba-l-cc): (1) CAUSA RAIZ: 349 valores en expediente y 283 en expediente_baja sin forma de expediente (no arrancan con EX-); (2) 152 divergencias reales de cadena, expte_baja de N != expediente de N+1 - NO 238, 86 eran espaciado interno; (3) 11 auto-referenciales normalizando / 10 crudo, de los cuales 7 son un unico tramite de flota (EX-2025-40163585, 2025-07-08 -> 2025-09-19) repetido en siete dominios; (4) 2 filas de historial duplicadas (7394/7400, AD956UK: mismo dominio, misma fecha_expediente, mismo cierre). REGLA DE IMPLEMENTACION OBLIGATORIA, es donde esto se rompe solo: comparar NORMALIZADO (NBSP->espacio, espacios colapsados, upper) y escribir CRUDO. 928 expedientes tienen espacios internos multiples que son dato fiel del libro; quien normalice al escribir los reescribe en silencio y el resultado sigue pareciendo correcto. db02-mba-l-cc tiene las consultas de las 4 poblaciones si se quieren pegar aca.
  • wi-cli-venus commented · 3d ago
    QUINTA POBLACION (db-mba-l-cc, medida): 206 filas en expediente y 70 en expediente_baja empiezan con 'Ex-' EN MINUSCULA (Ex-2025-55711507 = 70 filas, Ex-2025-29898868 = 42, Ex-2025-29916884 = 27). Contando '^EX-' case-sensitive da 555/353; case-insensitive da 349/283 - la diferencia son exactamente esas. NO van en el bucket de 'sin tipar': son expedientes VALIDOS y bien formados. El riesgo es que cualquier filtro o join con LIKE 'EX-%' las pierde en silencio (misma clase de bug que las 207 filas Si/SI del censo RUTAP, otra columna). BLAST RADIUS VERIFICADO, no sospechado: grep de src/ scripts/ drizzle/ buscando comparaciones contra 'EX-' da 6 hits y TODOS son placeholder de input o UI ('EX-2025-12345678'), ninguno en direccion de parseo. HOY no rompe nada - es riesgo latente para el proximo que escriba un filtro por prefijo. Que nadie salga a arreglar lo que no esta roto.
  • wi-cli-venus commented · 3d ago
    DECISION DE FONDO (db-mba-l-cc): las 349 sin forma de expediente NO son texto libre homogeneo. 242 son la observacion 'Se modifican datos a pedido de la empresa' y 74 son RESOLUCIONES (Res. SECT 56/2026 = 39 filas, Res. SECT 18/2026 = 35). Una resolucion es un instrumento administrativo REAL, no basura. Entonces el ticket NO es 'limpiar valores': es definir si la columna admite resoluciones - y en ese caso ningun consumidor puede asumir el prefijo EX- - o si hay que distinguir instrumento y numero en campos separados. Si alguien lee este ticket como 'limpiar', borra dato bueno.
  • wi-cli-venus commented · 3d ago
    CENSO FINAL, CINCO POBLACIONES (db02 descompuso las 349 hasta el fondo; suman EXACTO 242+98+9=349). Reemplaza los conteos parciales de arriba: (1) 242 = observacion 'Se modifican datos a pedido de la empresa' en el campo expediente - causa raiz: la columna es texto libre; (2) 98 RESOLUCIONES SECT, no 74 - Res. SECT 56/2026=39, 18/2026=35, 214/2025=21, 207/2025=3 (faltaban las dos de 2025): instrumento administrativo REAL que el modelo no distingue del expediente; (3) 9 expedientes con EN DASH U+2013 en vez de guion ASCII (EX-2026-07797873- -GCABA-DGGSM), 9 en expediente y 9 en expediente_baja, 0 em dash - HALLAZGO NUEVO y la peor clase: expediente real y bien formado que no matchea NI 'EX-%' NI 'Ex-%' ni ningun regex con guion ASCII, porque el separador no es un guion; un filtro por forma los declara texto libre y un JOIN por numero no los encuentra nunca (mismo mecanismo que NBSP y CRLF: caracter unicode que se ve igual y no lo es); (4) 206/70 con 'Ex-' minuscula, invisibles a LIKE 'EX-%' case-sensitive - aritmetica confirmada por los dos: 555/353 case-sensitive, 349/283 case-insensitive, 0 con 'ex-'; (5) 11 auto-referenciales (7 = un unico tramite de flota) + 152 divergencias de cadena + 2 filas duplicadas 7394/7400. Detalle por poblacion en los hijos MOVILBA-37 y -38. Memoria: reference_expediente_is_untyped_free_text (db02). Consultas de las cinco disponibles en db02-mba-l-cc.
  • wi-cli-venus commented · 3d ago
    CAUSA RAIZ, redaccion final (db02): el campo carga TRES instrumentos distintos (expediente EX-, resolucion SECT, observacion) con TRES grafias del mismo instrumento (EX-, Ex-, EX-con-en-dash U+2013). Limpiar valores NO lo arregla: hay que decidir si la columna admite resoluciones, y si las admite, ningun consumidor puede filtrar por LIKE 'EX-%'. SET DE REPRODUCCION (corre tal cual contra prod; coder02 re-corrio la 2 y la 3 y da identico: 9/9/0 y 206/555/349). -- 1) descomposicion de las 349 sin forma de expediente (suma exacta 242+98+9=349) with t as (select expediente v from public.vehiculo_historial where expediente is not null and expediente !~* '^EX-') select left(v,46) valor, count(*) from t group by 1 order by 2 desc; -- 2) QUINTA POBLACION: en dash U+2013 en vez de guion ASCII -> 9 | 9 | 0 select count(*) filter (where expediente like '%'||chr(8211)||'%') ea_endash, count(*) filter (where expediente_baja like '%'||chr(8211)||'%') eb_endash, count(*) filter (where expediente like '%'||chr(8212)||'%') ea_emdash from public.vehiculo_historial; -- 3) case: validos invisibles a LIKE 'EX-%' case-sensitive -> 206 | 70 | 555 | 349 select count(*) filter (where expediente ~ '^Ex-') ea_mixed, count(*) filter (where expediente_baja ~ '^Ex-') eb_mixed, count(*) filter (where expediente is not null and expediente !~ '^EX-') sin_forma_cs, count(*) filter (where expediente is not null and upper(expediente) !~ '^EX-') sin_forma_ci from public.vehiculo_historial; -- 4) auto-referenciales (11 normalizando / 10 crudo) select vh.id, v.dominio, vh.fecha_expediente, vh.borrado_en::date cierre, left(vh.expediente_baja,42) from public.vehiculo_historial vh join public.vehiculos v on v.id=vh.vehiculo_id where vh.borrado_en is not null and vh.expediente_baja is not null and upper(regexp_replace(replace(vh.expediente,chr(160),' '),'\s+','','g')) = upper(regexp_replace(replace(vh.expediente_baja,chr(160),' '),'\s+','','g')) order by vh.fecha_expediente, vh.id; -- 5) cadena: 204 sin sucesor / 1937 igual normalizado / 1851 igual crudo / 152 divergen with s as ( select vh.expediente_baja eb, (select vh2.expediente from public.vehiculo_historial vh2 where vh2.vehiculo_id=vh.vehiculo_id and vh2.fecha_expediente=vh.borrado_en::date order by vh2.id limit 1) suc from public.vehiculo_historial vh where vh.borrado_en is not null and vh.expediente_baja is not null) select count(*) total, count(*) filter (where suc is null) sin_sucesor, count(*) filter (where suc is not null and btrim(eb)=btrim(suc)) igual_crudo, count(*) filter (where suc is not null and upper(regexp_replace(replace(eb,chr(160),' '),'\s+','','g')) = upper(regexp_replace(replace(suc,chr(160),' '),'\s+','','g'))) igual_norm, count(*) filter (where suc is not null and upper(regexp_replace(replace(eb,chr(160),' '),'\s+','','g')) <> upper(regexp_replace(replace(suc,chr(160),' '),'\s+','','g'))) divergen from s;
  • wi-cli-venus titleChanged · 3d ago
    Calidad de dato en expediente / expediente_baja de vehiculo_historial: el campo no esta tipado (5 poblaciones medidas)
  • wi-cli-venus commented · 3d ago
    ORIGEN DEL EN DASH ACLARADO (db02, medido): NO lo introduce el importador, VIENE EN EL LIBRO. rutap.v_rutap_latest tiene 9 filas con U+2013 en expte_alta y 9 en expte_baja, exactamente las 9 de prod: prod refleja fielmente el origen, no hay nada corrupto del lado nuestro y NO hay nada que revertir. El libro tambien trae 262 filas con 'Ex-' minuscula en expte_alta (en prod se ven 206 porque no todas cerraron periodo). El gap del importador se sigue por ticket propio.
bug
3d ago by wi-cli-venus
3d ago