Saltar a contenido

SOURCE-003 Prepared CSV Python Generator 001

Fecha local: 2026-06-11 21:52:44 -03:00

Estado: REPRODUCIBLE ESTRUCTURAL ACEPTADO / UUID V5 DETERMINISTICO

portal_visible = yes

Scope: tenant

tenant_id: alpuntodeventa

Owner: Gabi / Carlos Canu

Fuente de verdad: docs/tenants/alpuntodeventa/business-observer/design/SOURCE-003-PREPARED-CSV-PYTHON-GENERATOR-001.md

1. Objetivo

Crear un generador Python reproducible para transformar el snapshot raw congelado de SOURCE-003 / Tabla 2 V2 en un CSV preparado de 83 columnas, sin tocar PostgreSQL, sin ejecutar SQL y sin cargar datos.

Flujo cubierto:

text SOURCE-003 raw snapshot -> prepared CSV de 83 columnas -> validaciones locales -> evidencia documental

2. Script creado

Script versionado:

text scripts/source_003_prepare_csv.py

Caracteristicas:

  • usa Python stdlib;
  • no usa dependencias externas;
  • no conecta a PostgreSQL;
  • no lee .env;
  • no lee secretos;
  • no ejecuta SQL;
  • genera el CSV preparado en el orden exacto del \copy candidate;
  • calcula line_sequence_v1, line_key_v4, source_row_hash_v1, descuento_item, metadata y id UUID v5 deterministico;
  • valida estructura, metadata, nulos criticos, duplicados, fecha y hashes;
  • calcula sha256 del output;
  • devuelve exit code distinto de cero si una validacion falla.

3. Inputs

Raw snapshot usado:

text C:\APV\openclawai\snapshots\source-003\SOURCE-003-TABLA2-V2-2026-06-09_20260610-210406-0300.csv

SHA256 raw esperado y observado:

text 07092c284b5b636b8a31cd616ef5b4fa5d0ce499b81c767437842b1f7edfcbc3

CSV preparado validado para comparacion:

text C:\APV\openclawai\snapshots\source-003\prepared\SOURCE-003-PILOT-LOAD-DEDICATED-DB-2026-06-09.csv

SHA256 preparado validado:

text 3f16a957a79fc84d4ca37930988287cb81f05166210d057fcf8b45007f184afe

4. Output generado

Output de prueba fuera de Git:

text C:\APV\openclawai\snapshots\source-003\prepared\generated\SOURCE-003-PILOT-LOAD-DEDICATED-DB-2026-06-09.generated.csv

Regla .gitignore observada:

text .gitignore:9:snapshots/*

SHA256 generado:

text 6fb44d9870a567e728df9bbdcc6b83279d84791bd732626c9e19ccf3a28dc903

5. Parametros

Comando ejecutado:

powershell python scripts/source_003_prepare_csv.py ` --raw-input snapshots/source-003/SOURCE-003-TABLA2-V2-2026-06-09_20260610-210406-0300.csv ` --output snapshots/source-003/prepared/generated/SOURCE-003-PILOT-LOAD-DEDICATED-DB-2026-06-09.generated.csv ` --sync-batch-id 1827f887-9499-4579-b4f3-234d54f41f7f ` --tenant-id alpuntodeventa ` --target-date 2026-06-09 ` --strict ` --compare-to snapshots/source-003/prepared/SOURCE-003-PILOT-LOAD-DEDICATED-DB-2026-06-09.csv

Metadata generada:

Campo Valor
tenant_id alpuntodeventa
source_system snapshot:SOURCE-003-SNAPSHOT-001
source_object SOURCE-003 / Tabla 2 V2
source_query_version SOURCE-003-VENTAS-VNEXT-TABLA2-AUTHORITY-V2
sync_batch_id 1827f887-9499-4579-b4f3-234d54f41f7f
extracted_at 2026-06-10T21:04:06-03:00
last_seen_at 2026-06-10T21:04:06-03:00
created_at 2026-06-10T21:04:06-03:00
updated_at 2026-06-10T21:04:06-03:00
record_status active

6. Validaciones locales

Resultado de ejecucion:

json { "result": "REPRODUCIBLE ESTRUCTURAL / SHA DIFERENTE", "rows": 1886, "columns": 83, "raw_sha256": "07092c284b5b636b8a31cd616ef5b4fa5d0ce499b81c767437842b1f7edfcbc3", "output_sha256": "6fb44d9870a567e728df9bbdcc6b83279d84791bd732626c9e19ccf3a28dc903", "compared_sha256": "3f16a957a79fc84d4ca37930988287cb81f05166210d057fcf8b45007f184afe", "postgresql_touched": false, "data_loaded": false }

Controles pasados:

Control Resultado
raw sha256 esperado PASS
header raw 68 columnas PASS
header output 83 columnas PASS
orden de columnas igual al \copy candidate PASS
filas de datos 1886
fecha unica 2026-06-09
tenant_id exacto PASS
source_system exacto PASS
source_object exacto PASS
source_query_version exacto PASS
sync_batch_id exacto PASS
record_status = active PASS
nulos criticos 0
duplicados (tenant_id, line_key) 0
source_row_hash vacios 0
Hora formato HHMMSS PASS
importe total 48087486.83
CMV total 37881269.3025
CSV generado versionado en Git NO

7. Comparacion contra CSV validado

Resultado:

text REPRODUCIBLE ESTRUCTURAL / SHA DIFERENTE

Comparacion celda por celda:

Dimension Resultado
filas 1886/1886
columnas 83/83
columnas iguales al CSV validado 82/83
columna diferente id
filas con id diferente 1886
diferencias fuera de id 0

Lectura:

  • line_key_v4 coincide contra el CSV validado.
  • source_row_hash_v1 coincide contra el CSV validado.
  • las 68 columnas reales mapeadas coinciden contra el CSV validado.
  • metadata, fechas y batch coinciden contra el CSV validado.
  • el SHA no coincide porque la columna id se genero con un UUID v5 deterministico documentado en el script, pero el namespace o formula exacta usada para el CSV preparado anterior no estaba documentada.

No se reemplazo el CSV preparado validado.

8. Auditoria semantica de id

Fecha local: 2026-06-11 22:00:14 -03:00

Decision:

text ACEPTAR UUID V5 DETERMINISTICO

Lectura tecnica:

  • id no es clave de negocio de SOURCE-003.
  • id es una surrogate key tecnica interna suministrada por el pipeline.
  • No existe formula historica documentada para reproducir exactamente el id del CSV preparado validado.
  • El DDL usa id como PRIMARY KEY (id), pero la identidad logica aprobada esta en UNIQUE (tenant_id, line_key).
  • line_key contiene line_key_v4, ya aceptada como identidad documental en estado AMARILLO ACEPTADO.
  • La deduplicacion y las validaciones funcionales dependen de (tenant_id, line_key), no de id.
  • El rollback piloto documentado filtra por tenant_id, sync_batch_id, source_system, source_object, source_query_version y fecha; no depende de id.
  • Los post-checks validan que id no sea nulo, pero no lo usan para trazabilidad, deduplicacion, conciliacion ni rollback.
  • La trazabilidad de cambios depende de source_row_hash, sync_batch_id, line_key, metadata de fuente y timestamps de observacion.

Formula estandar futura para id en este generador:

text id = uuid5( uuid.NAMESPACE_URL, json_compacto([ tenant_id, source_system, source_object, source_query_version, sync_batch_id, line_key ]) )

Esta formula queda formalizada para prepared CSV futuros generados por scripts/source_003_prepare_csv.py. Si una tarea futura necesita reproducibilidad byte a byte del CSV historico ya cargado, debera aportar la formula o namespace anterior como nueva evidencia; mientras tanto, no se considera bloqueante para analytics, BI, IA, ML ni rollback del piloto.

9. Confirmaciones de alcance

Restriccion Resultado
PostgreSQL tocado NO
SQL ejecutado NO
psql ejecutado NO
candidate load ejecutado NO
rollback ejecutado NO
datos cargados 0
sync diaria ejecutada NO
carga masiva ejecutada NO
produccion final tocada NO
VPS tocado NO
Docker tocado NO
OpenClaw tocado NO
NPM tocado NO
secretos impresos NO
push/deploy NO

10. Decision

text REPRODUCIBLE ESTRUCTURAL ACEPTADO

El generador reproduce localmente el prepared CSV en estructura, orden, metadata, hashes funcionales, line_key_v4, source_row_hash_v1, validaciones y 82/83 columnas. La unica diferencia observada frente al CSV validado es id, por falta de documentacion del namespace o formula exacta del UUID previo.

La diferencia de id no afecta claves de negocio, deduplicacion, trazabilidad funcional, rollback ni post-checks. A partir de esta decision, el generador queda autorizado como estandar tecnico futuro para prepared CSV de SOURCE-003 usando UUID v5 deterministico documentado.

No se reclasifica como REPRODUCIBLE EXACTO porque el SHA del CSV generado no coincide con el CSV preparado historico ya validado y cargado.

11. Proximo paso recomendado

Mantener el CSV preparado validado historico como evidencia de la carga piloto ya ejecutada y usar el generador como estandar tecnico para prepared CSV futuros.

Sync diaria, carga masiva y produccion final siguen bloqueadas.