v_db_users_footprint es CIEGA en vehiculo_historial (0 de 2315 con borrado_por) porque los triggers fn_soft_delete son BEFORE DELETE y los cierres de esa tabla se escriben por UPDATE directo
MECANISMO CERRADO, ya no es una incognita. Lo abrio db-mba-l-cc cerrando MOVILBA-114, lo contra-midio db02-mba-l-cc sobre las 33 tablas con borrado_por y lo explico db03-mba-l-ca leyendo los triggers. Todo prod, todo SELECT, 08-21 ~11:34-11:55. EL HECHO. La rama de vehiculo_historial de v_db_users_footprint_detalle agrupa por borrado_por con WHERE borrado_por IS NOT NULL. En esa tabla 2315 filas llevan borrado_en y CERO llevan borrado_por, asi que la rama aporta 0 filas y siempre lo hizo. Control positivo sobre la misma tabla: borrado_en devuelve 2315, o sea que hay poblacion y el filtro funciona. NO ES UN HUECO GENERAL - ES UN UNICO OUTLIER, y eso lo vuelve mas fuerte, no mas debil. De las 33 tablas con la columna, TODAS las demas atribuyen el 100% de sus soft-deletes: vehiculos 658/658, vehiculos_datos_colectivos 656/656, chasis 112/112, carrocerias 56/56, lineas 30/30, personas 17/17, linea_entidad_asignaciones 17/17, ramales 13/13, fabricantes 13/13, correos 8/8, telefonos 5/5, entidades 2/2, vehiculos_archive 2/2, vdc_archive 4/4, instalacion_lineas 1/1. Una sola tabla atribuye 0 de 2315. LA CAUSA. Los 26 triggers fn_soft_delete son BEFORE **DELETE**: disparan sobre una sentencia DELETE y setean borrado_en Y borrado_por juntos. Un UPDATE directo que setea borrado_en NUNCA los dispara y no deja autor. Las 2315 marcas de vehiculo_historial son los cierres que el indice unico FUERZA (2314 estructuralmente), escritos por migraciones y loaders con UPDATE directo para liberar el slot vivo de la proxima alta - no son borrados que haya hecho una persona. No hay autor porque NO HUBO ACTOR. Corolario: el hueco es un SINTOMA de que borrado_en carga dos significados en esta tabla (borrado logico Y cierre bajo indice unico). Toda tabla donde borrado_en significa solo soft-deleted tiene la columna de autor completa; la unica donde tambien significa cerrado-por-el-indice no tiene ninguna. Es el argumento mas limpio para mover el indice - medible, de un solo lado y sin otra explicacion posible (mas limpio que el de almacenamiento o el de semantica). Vinculo directo con MOVILBA-42. POR QUE IMPORTA. v_db_users_footprint decide SI UN USUARIO DE BD SE PUEDE ELIMINAR. La forma correcta del defecto es CIEGA EN UNA TABLA, no inutil: informa huella real de las otras 15 tablas pobladas y aporta cero, en silencio, desde la que tiene 2315 marcas. La vista no puede distinguir "no tiene huella" de "nunca registramos quien la dejo" y las dos se ven igual - sexta superficie de la misma forma del 08-21. NO BACKFILLEAR borrado_por, y la razon es mas fuerte que la regla de columnas de auditoria: NO HAY VALOR VERDADERO QUE ESCRIBIR. Inventarle un actor a una escritura que ningun actor hizo es fabricar dato de auditoria, peor que el hueco. (Contrastar con MOVILBA-117: estado_id SI es columna de negocio y ahi el backfill es legitimo.) EL ARREGLO, dos mitades: 1) que los cierres futuros dejen de escribirse por UPDATE directo, o que la vista deje de tratar esa tabla como fuente de atribucion; 2) que la vista DIGA que el dato historico falta en vehiculo_historial en vez de implicar huella cero. Un NULL informado como "sin registro" no es un cero. DOS ANOMALIAS MENORES que el barrido de las 33 tablas encontro, mismo mecanismo, ninguna nuestra: - opciones: 34 estampadas, 32 con autor -> 2 filas de catalogo cerradas por UPDATE directo. Importa porque el defecto de MOVILBA-115 gira sobre soft-deletes de catalogo; la opcion 118 TRANSFERENCIA es una de estas 34. - instalaciones: 0 estampadas, 1 CON autor -> una fila borrada por el trigger y despues des-borrada por un UPDATE directo que limpio borrado_en y dejo el autor colgado. Es el PRECEDENTE para los paquetes 111 y 112, que tambien limpian borrado_en: db02 verifico que no lo reproducen (la fila 4905 de 111 tiene borrado_por NULL, y las 131 de 112 tampoco tienen autor que dejar huerfano). Origen: MOVILBA-114.
Activity
-
v_db_users_footprint es CIEGA en vehiculo_historial (0 de 2315 con borrado_por) porque los triggers fn_soft_delete son BEFORE DELETE y los cierres de esa tabla se escriben por UPDATE directo
-
was: MEDIDO POR db-mba-l-cc en prod (11:34, SELECT): la rama de vehiculo_historial de v_db_users_footprint_detalle es GROUP BY borrado_por WHERE borrado_por IS NOT NULL. En esa tabla 2315 filas llevan borrado_en y CERO llevan borrado_por. Control positivo sobre la misma tabla: borrado_en devuelve 2315, o sea que la columna esta poblada y el filtro funciona - borrado_por simplemente NUNCA SE ESCRIBE. La rama aporta 0 filas y siempre lo hizo. POR QUE IMPORTA Y NO ES COSMETICO: v_db_users_footprint es la vista que se usa para decidir SI UN USUARIO DE BD SE PUEDE ELIMINAR. Hoy informa que nadie tiene huella en vehiculo_historial, mientras 2315 filas de esa tabla fueron estampadas. La atribucion no esta equivocada: esta AUSENTE. Todas esas marcas vinieron de migraciones o loaders que nunca setearon borrado_por. El riesgo concreto: alguien lee 'sin huella' y borra un usuario que si dejo marcas. La vista no puede distinguir 'no tiene huella' de 'nunca registramos quien la dejo', y las dos se ven igual - es la misma forma que veniamos persiguiendo todo el 08-21, sexta superficie (despues de un filtro, un gate, un desempate de ORDER BY, un conteo y un indice UNIQUE). NO BACKFILLEAR borrado_por. Bajo la regla de columnas de auditoria de Elazar (08-21) esa es una columna de auditoria, e inventarle valores retroactivamente es exactamente lo que la regla prohibe. El arreglo correcto tiene dos mitades: 1. que los soft-deletes FUTUROS lo escriban - fn_soft_delete() ya setea borrado_por cuando dispara (verificado por db03-mba-l-ca), asi que el hueco viene de escrituras que NO pasan por el trigger: migraciones y loaders. 2. que la vista DIGA que el dato historico falta, en vez de implicar huella cero. Un NULL informado como 'sin registro' no es lo mismo que un cero. Relacionado: MOVILBA-114 (de donde salio).
-
was: MECANISMO CERRADO, ya no es una incognita. Lo abrio db-mba-l-cc cerrando MOVILBA-114, lo contra-midio db02-mba-l-cc sobre las 33 tablas con borrado_por y lo explico db03-mba-l-ca leyendo los triggers. Todo prod, todo SELECT, 08-21 ~11:34-11:55. EL HECHO. La rama de vehiculo_historial de v_db_users_footprint_detalle agrupa por borrado_por con WHERE borrado_por IS NOT NULL. En esa tabla 2315 filas llevan borrado_en y CERO llevan borrado_por, asi que la rama aporta 0 filas y siempre lo hizo. Control positivo sobre la misma tabla: borrado_en devuelve 2315, o sea que hay poblacion y el filtro funciona. NO ES UN HUECO GENERAL - ES UN UNICO OUTLIER, y eso lo vuelve mas fuerte, no mas debil. De las 33 tablas con la columna, TODAS las demas atribuyen el 100% de sus soft-deletes: vehiculos 658/658, vehiculos_datos_colectivos 656/656, chasis 112/112, carrocerias 56/56, lineas 30/30, personas 17/17, linea_entidad_asignaciones 17/17, ramales 13/13, fabricantes 13/13, correos 8/8, telefonos 5/5, entidades 2/2, vehiculos_archive 2/2, vdc_archive 4/4, instalacion_lineas 1/1. Una sola tabla atribuye 0 de 2315. LA CAUSA. Los 26 triggers fn_soft_delete son BEFORE **DELETE**: disparan sobre una sentencia DELETE y setean borrado_en Y borrado_por juntos. Un directo NUNCA los dispara y no deja autor. Las 2315 marcas de vehiculo_historial son los cierres que el indice unico FUERZA (2314 estructuralmente), escritos por migraciones y loaders con UPDATE directo para liberar el slot vivo de la proxima alta - no son borrados que haya hecho una persona. No hay autor porque NO HUBO ACTOR. Corolario: el hueco es un SINTOMA de que borrado_en carga dos significados en esta tabla (borrado logico Y cierre bajo indice unico). Toda tabla donde borrado_en significa solo 'soft-deleted' tiene la columna de autor completa; la unica donde tambien significa 'cerrado por el indice' no tiene ninguna. Es el argumento mas limpio para mover el indice - medible, de un solo lado y sin otra explicacion posible (mas limpio que el de almacenamiento o el de semantica). Vinculo directo con MOVILBA-42. POR QUE IMPORTA. v_db_users_footprint decide SI UN USUARIO DE BD SE PUEDE ELIMINAR. La forma correcta del defecto es CIEGA EN UNA TABLA, no inutil: informa huella real de las otras 15 tablas pobladas y aporta cero, en silencio, desde la que tiene 2315 marcas. La vista no puede distinguir 'no tiene huella' de 'nunca registramos quien la dejo' y las dos se ven igual - sexta superficie de la misma forma del 08-21. NO BACKFILLEAR borrado_por, y la razon es mas fuerte que la regla: NO HAY VALOR VERDADERO QUE ESCRIBIR. Inventarle un actor a una escritura que ningun actor hizo es fabricar dato de auditoria, peor que el hueco. (Contrastar con MOVILBA-117: estado_id SI es columna de negocio y ahi el backfill es legitimo.) EL ARREGLO, dos mitades: 1) que los cierres futuros dejen de escribirse por UPDATE directo, o que la vista deje de tratar esa tabla como fuente de atribucion; 2) que la vista DIGA que el dato historico falta en vehiculo_historial en vez de implicar huella cero. Un NULL informado como 'sin registro' no es un cero. DOS ANOMALIAS MENORES que el barrido de las 33 tablas encontro, mismo mecanismo, ninguna nuestra: - opciones: 34 estampadas, 32 con autor -> 2 filas de catalogo cerradas por UPDATE directo. Importa porque el defecto de MOVILBA-115 gira sobre soft-deletes de catalogo; la opcion 118 TRANSFERENCIA es una de estas 34. - instalaciones: 0 estampadas, 1 CON autor -> una fila borrada por el trigger y despues des-borrada por un UPDATE directo que limpio borrado_en y dejo el autor colgado. Es el PRECEDENTE para los paquetes 111 y 112, que tambien limpian borrado_en: db02 verifico que no lo reproducen (fila 4905 de 111 tiene borrado_por NULL, y las 131 de 112 tampoco tienen autor que dejar huerfano). Origen: MOVILBA-114.
-
Resolved 2026-08-26 without backfilling borrado_por (per this item's own finding: no true actor exists for those 2315 rows). Added the missing vehiculo_historial.creado_por UNION branch to v_db_users_footprint_detalle instead - creado_por IS well populated (every app insert stamps it), it was simply never wired into the footprint view alongside every other _historial/_archive table's pattern. Applied+verified DEV+PROD: docs/migrations/2026-08-26-movilba118-footprint-vehiculo-historial-creado-por-{DEV,PROD}.sql. 9 users now attributed via that branch, zero regressions (no user's total footprint decreased). Independently verified by audit-mba-l-cc. The borrado_en/two-meanings root cause and MOVILBA-42 link stand as documented above, unchanged by this fix.