Saltar a contenido

Import Runtime Standard - Safe Batched Imports

Fecha: 2026-06-21

Estado: ESTANDAR OPERATIVO DOCUMENTAL / OBLIGATORIO ANTES DE IMPORTADORES PRODUCTIVOS / SIN EJECUCION

portal_visible = yes

Scope: tenant

tenant_id: alpuntodeventa

Owner: Gabi / Carlos Canu

1. Objetivo

Definir el estandar seguro para importar datos desde SGC hacia PostgreSQL, protegiendo al servidor origen Microsoft SQL Server 2012 legacy y evitando consultas largas, bloqueantes o sin limites.

El patron es reusable para:

  • SOURCE-001 Clientes
  • SOURCE-002 Productos
  • SOURCE-003 Ventas
  • futuras fuentes SGC leidas desde vistas

Este documento no autoriza ejecucion. Solo fija reglas para futuros scripts de importacion Python, gates de recarga, rehearsals, syncs o pipelines.

2. Alcance

Aplica a toda extraccion desde SGC hacia capas PostgreSQL del Business Observer:

  • SOURCE-001 Clientes, desde ecommerce.dbo.VCLIENTES.
  • SOURCE-002 Productos, desde autoridad vigente de productos.
  • SOURCE-003 Ventas, desde salida canonica Tabla 2 de la query autoridad.
  • cualquier fuente futura SGC accesible por vista o query autoridad.

Quedan fuera de alcance en este estandar:

  • ejecutar SQL real;
  • crear snapshots nuevos;
  • cargar PostgreSQL;
  • ejecutar COPY, DML, sync, scheduler, cron o pipelines;
  • llamar API WooCommerce;
  • leer o imprimir secretos.

3. Restricciones del origen SGC

El origen SGC Server debe tratarse como Microsoft SQL Server 2012 legacy.

Restricciones obligatorias:

  • acceso read-only;
  • lectura desde vistas o query autoridad documentada;
  • sin writes en SGC;
  • sin objetos persistentes en SGC;
  • sin cambios del lado SGC;
  • sin exigir indices nuevos;
  • sin features modernas no garantizadas;
  • sin consultas masivas sin limites;
  • sin NOLOCK por defecto salvo autorizacion documental explicita;
  • sin queries analiticas pesadas sobre vistas si no hay gate y evidencia;
  • sin cursores del lado SGC.

Regla madre: el importador protege primero al origen. Si la vista responde lento, inestable o con timeout, la corrida se reduce, pausa o aborta.

4. Patron recomendado

El patron oficial es:

extract -> snapshot -> validate -> load

Donde:

  • extract lee desde SGC en lotes chicos y medibles.
  • snapshot guarda el resultado fuera de Git.
  • validate calcula hash, conteos, columnas y metricas no sensibles.
  • load carga a PostgreSQL en una etapa separada, con gate propio.

La extraccion y la carga no deben mezclarse en una misma operacion irreversible. El cierre de extract debe poder validarse sin tocar PostgreSQL.

5. Estrategia por lotes

Valores iniciales recomendados:

Parametro Recomendacion
lote inicial conservador 500 filas
lote para vistas simples/chicas hasta 1000 filas
maximo recomendado sin nueva evidencia 5000 filas
concurrencia por fuente 1
pausa entre lotes 1 a 5 segundos
pausa si hay degradacion 10 a 60 segundos

Reglas:

  • cada corrida debe tener batch_id unico;
  • cada lote debe registrar numero de lote, rango, filas, duracion y estado;
  • si un lote supera el timeout, reducir el tamano al 50% y reintentar;
  • si vuelve a fallar, reducir nuevamente hasta un minimo operativo definido;
  • si el lote minimo falla, abortar sin carga;
  • nunca ejecutar varias fuentes pesadas en paralelo;
  • nunca ejecutar historicos completos en horario operativo sin gate propio.

Estados finales permitidos por lote:

  • pending
  • running
  • extracted
  • validated
  • retrying
  • failed
  • aborted

6. Paginacion compatible con SQL Server 2012

SQL Server 2012 soporta OFFSET/FETCH, pero no debe asumirse como opcion universal para vistas legacy. La opcion preferida es keyset pagination o rangos deterministicos cuando exista una clave confiable.

Opciones permitidas, en orden de preferencia:

  1. Keyset pagination por clave ordenable estable.
  2. Rangos por ID, Codigo, SKU, fecha o comprobante, segun fuente.
  3. TOP (N) con condicion incremental y ORDER BY deterministico.
  4. Snapshot full controlado solo si la fuente es chica o no tiene clave segura.

Evitar:

  • paginacion sin ORDER BY;
  • OFFSET/FETCH como supuesto universal sobre vistas pesadas;
  • ordenar por columnas calculadas costosas si existe alternativa;
  • paginas no deterministicas;
  • queries gigantes que lean toda la vista para descartar casi todo;
  • depender de cambios del lado SGC.

Si no existe clave confiable, el documento del gate debe marcar el riesgo y usar snapshot full en ventana segura, con lote conservador, timeout y abort claro.

7. Timeouts y reintentos

Parametros recomendados:

Control Valor inicial
timeout de conexion 15 segundos
timeout de query por lote 60 segundos
reintentos maximos por lote 3
backoff 10, 30, 60 segundos
criterio de abort mismo lote falla luego de 3 reintentos

Un retry es seguro solo si:

  • el lote no fue marcado como validado;
  • no se escribio en PostgreSQL en la misma etapa;
  • el snapshot parcial puede reemplazarse o retomarse con control;
  • el log no contiene datos sensibles.

Ante timeout:

  1. cerrar cursor/conexion si queda en estado incierto;
  2. registrar lote, rango, duracion y error resumido;
  3. pausar;
  4. reducir lote si corresponde;
  5. reintentar o abortar.

8. Throttling y proteccion de SGC

Reglas obligatorias:

  • concurrencia 1 por fuente salvo autorizacion documental;
  • no ejecutar SOURCE-001, SOURCE-002 y SOURCE-003 pesados en paralelo;
  • preferir ventanas fuera de horas criticas;
  • no hacer full reads masivos en horario operativo;
  • pausar entre lotes aunque la extraccion parezca rapida;
  • detener si el origen responde lento o inestable;
  • dejar evidencia de duracion por lote.

Ventanas recomendadas:

  • cargas full o historicas: fuera del horario comercial y con operador atento;
  • ventas incrementales: ventanas pequenas y medibles;
  • stock actual: lecturas livianas, no la query maestra completa;
  • productos full: manual o programado solo si el runtime previo fue verde.

9. Snapshot fuera de Git

Todo snapshot operativo debe vivir fuera de Git o en rutas ignoradas por Git.

Rutas recomendadas en Windows:

  • C:\APV\openclawai\snapshots\source-001\
  • C:\APV\openclawai\snapshots\source-002\
  • C:\APV\openclawai\snapshots\source-003\
  • C:\APV\openclawai\tmp\... para archivos intermedios descartables

Formato recomendado:

  • CSV para auditoria humana y snapshots controlados.
  • JSONL para carga operacional por filas.

Cada snapshot debe tener:

  • hash SHA256;
  • archivo .sha256;
  • conteo de filas;
  • conteo de columnas;
  • tamano de archivo;
  • batch_id;
  • source_query_version;
  • validacion de columnas contra autoridad SQL o mapping vigente;
  • confirmacion de que no fue versionado.

Prohibido:

  • commitear snapshots;
  • commitear CSV/JSONL operativos;
  • commitear dumps o backups;
  • incluir datos sensibles en logs o docs.

10. Carga a PostgreSQL

La carga siempre es etapa separada de la extraccion.

Orden recomendado:

  1. preflight de target;
  2. carga raw;
  3. promocion core;
  4. capas derivadas;
  5. marts;
  6. post-checks;
  7. evidencia documental.

Reglas:

  • validar target para no confundir prod, staging o sandbox;
  • raw primero, core despues, marts al final;
  • rollback batch-scoped antes de autorizar carga;
  • no borrar historicos sin autorizacion explicita;
  • no activar WooCommerce, sync, scheduler, cron ni pipelines por efecto colateral de una carga.

11. Idempotencia y reanudacion

Toda corrida debe registrar:

  • batch_id unico;
  • source_snapshot_sha256;
  • source_query_version;
  • rango o cursor usado;
  • lote actual;
  • estado final;
  • conteos por lote y total;
  • timestamp de inicio y cierre.

Reglas:

  • repetir una extraccion no debe duplicar datos;
  • una carga del mismo batch debe ser NO-GO si ya esta conciliada;
  • un retry no debe mezclar dos snapshots;
  • un abort debe dejar estado explicito y limpiable;
  • un rollback debe estar limitado al batch autorizado;
  • no hacer hard delete historico sin gate separado.

12. Logs seguros

Los logs pueden incluir:

  • batch_id;
  • fuente;
  • rango o cursor no sensible;
  • filas por lote;
  • duracion;
  • hash de snapshot;
  • tamano de archivo;
  • reintentos;
  • estado final.

Los logs no pueden incluir:

  • passwords;
  • connection strings;
  • tokens;
  • usuarios si no fueron autorizados como no sensibles;
  • dumps de filas completas;
  • CUIT, telefono, email, direccion u otros datos personales innecesarios;
  • valores comerciales sensibles fila por fila.

13. Full load vs incremental load

Criterios:

  • usar full load para fuentes chicas, estables o controladas;
  • usar incremental o ventana movil para fuentes grandes o vivas;
  • productos puede separar catalogo, stock actual y capa economica;
  • clientes puede iniciar con full load y luego upsert por clave si existe campo confiable de cambio;
  • ventas debe evitar traer historico completo en cada corrida;
  • stock actual puede tener refresh frecuente, pero con query liviana;
  • snapshot diario puede ser append-only cuando aplica.

Si no hay campo incremental confiable, no inventarlo. Usar ventanas, snapshots o full controlado segun riesgo.

14. Reglas por fuente

SOURCE-001 Clientes

  • leer desde ecommerce.dbo.VCLIENTES;
  • priorizar Codigo canonico como clave cliente;
  • preservar CLIENTE ACTIVO, CLIENTE SUSPENDIDO y CLIENTE DE BAJA;
  • incluir Telefono como base de WhatsApp si corresponde;
  • no usar whatsapp como clave unica;
  • full load inicial permitido solo con lote conservador;
  • incremental posterior solo si existe campo de actualizacion confiable;
  • si la vista no tiene clave incremental, marcar riesgo y usar snapshot full controlado en ventana segura.

SOURCE-002 Productos

  • tratar tenant_id + SKU como clave canonica;
  • separar responsabilidades: raw, core, catalog, inventory, economic y mart;
  • catalogo actual puede cargarse controladamente;
  • stock actual frecuente debe usar fuente o query liviana, no necesariamente la autoridad completa;
  • snapshot diario de inventario debe ser controlado y append-only cuando corresponda;
  • faltantes/quiebres deben salir de capa mart;
  • proveedor, logistica, costo, precios y margen deben mantenerse trazables;
  • WooCommerce-ready no implica llamar WooCommerce API;
  • no mezclar todas las responsabilidades en una sola tabla final.

SOURCE-003 Ventas

  • puede crecer mucho y debe tratarse como fuente viva;
  • preferir ventanas temporales e incremental por fecha/comprobante/linea si existe criterio confiable;
  • evitar historico completo en cada corrida;
  • usar snapshot diario o ventana movil para dias recientes;
  • validar totales por lote y por ventana;
  • preservar source_row_hash;
  • preservar line_key_v4 como riesgo AMARILLO ACEPTADO cuando aplique;
  • no usar V_VENTAS cruda como reemplazo de la logica autoridad de Tabla 2;
  • Tabla 2 debe ser la unica salida de sync futura salvo gate contrario.

15. SQL Server 2012: practicas permitidas y evitadas

Permitido y recomendado:

  • SELECT simple sobre vistas;
  • filtros por fecha, ID, SKU, codigo o comprobante si existen;
  • TOP (N) con orden deterministico;
  • conversiones simples compatibles;
  • queries pequenas y medibles;
  • conteos read-only;
  • parametros simples por ventana.

Evitar:

  • funciones modernas no disponibles o no garantizadas;
  • OFFSET/FETCH como supuesto universal;
  • FORMAT por compatibilidad y performance;
  • JSON nativo;
  • queries analiticas pesadas sobre vistas;
  • CTEs complejas sobre vistas pesadas sin necesidad;
  • cursores del lado SGC;
  • NOLOCK por defecto;
  • hints sin autorizacion;
  • writes;
  • temporales persistentes;
  • creacion de objetos en SGC.

16. GO / NO-GO antes de cron o scheduler

GO solo si:

  • importador probado manualmente;
  • lotes validados;
  • tiempos medidos;
  • rollback probado;
  • snapshot, hash y conteos OK;
  • logs seguros;
  • target correcto;
  • sin impacto evidente en SGC;
  • documentacion publicada;
  • sync/scheduler/cron tiene gate propio.

NO-GO si:

  • query tarda demasiado;
  • no hay clave de paginacion confiable y no hay plan alternativo;
  • el origen se degrada;
  • faltan credenciales seguras;
  • se requiere leer secretos sin autorizacion;
  • existe riesgo de duplicacion;
  • no existe rollback;
  • no hay evidencia de conteos/hash;
  • el target puede confundirse entre prod, staging o sandbox.

17. Metricas minimas

Cada corrida debe medir:

  • duracion total;
  • duracion por lote;
  • filas por lote;
  • filas totales;
  • reintentos;
  • errores;
  • hash snapshot;
  • tamano snapshot;
  • target cargado, si aplica;
  • conteos raw/core/mart, si aplica;
  • fecha/hora de ejecucion;
  • version de query autoridad.

18. Seguridad y secretos

Reglas:

  • .env puede leerse solo con autorizacion explicita;
  • los valores nunca se imprimen;
  • los valores nunca se documentan;
  • los valores nunca se commitean;
  • las variables pueden cargarse en memoria/proceso;
  • no usar setx ni persistencia de sistema salvo autorizacion separada;
  • no registrar connection strings reales.

Validacion segura de variables:

  • imprimir solo PRESENT o MISSING;
  • no imprimir host, usuario o password salvo que un gate declare explicitamente cuales campos son no sensibles;
  • no copiar secretos entre ambientes sin autorizacion separada.

19. Pseudoflujo Python conceptual

Este pseudoflujo es conceptual y no contiene credenciales reales:

def run_extract():
    config = load_secure_config()
    required = [
        "SOURCE_DSN",
        "SOURCE_USER",
        "SOURCE_PASSWORD",
        "SNAPSHOT_DIR",
    ]
    assert_present_or_abort(required)

    batch_id = create_batch_id()
    query_version = "SOURCE-XXX-AUTHORITY-vN"
    snapshot = open_snapshot_writer(batch_id)

    source = connect_read_only(config, connect_timeout=15, query_timeout=60)

    try:
        cursor_state = initial_cursor()
        while True:
            rows = fetch_next_batch(
                source,
                cursor_state=cursor_state,
                batch_size=500,
                deterministic_order=True,
            )
            if not rows:
                break

            snapshot.write_rows(rows)
            record_batch_metrics(batch_id, rows, cursor_state)
            cursor_state = advance_cursor(rows)
            sleep_between_batches(seconds=2)

        snapshot.close()
        sha256 = calculate_sha256(snapshot.path)
        validate_counts_columns_and_hash(snapshot.path, sha256, query_version)
        write_sha256_file(snapshot.path, sha256)

    except TimeoutError:
        abort_batch_safely(batch_id)
        raise
    finally:
        source.close()


def run_load_gate():
    assert_manual_gate_authorized()
    assert_target_fingerprint()
    assert_snapshot_hash()
    assert_rollback_available()
    load_raw_then_core_then_marts()
    run_post_checks()

20. Confirmacion de alcance

Durante la creacion de este estandar:

  • no se ejecuto SQL;
  • no se ejecuto carga;
  • no se ejecuto COPY;
  • no se ejecuto DML;
  • no se ejecuto sync;
  • no se ejecuto scheduler;
  • no se ejecuto cron;
  • no se ejecutaron pipelines;
  • no se llamo WooCommerce API;
  • no se escribio en PostgreSQL produccion;
  • no se escribio en PostgreSQL staging;
  • no se uso sandbox;
  • no se leyeron secretos;
  • no se crearon snapshots, dumps, backups, CSV ni JSONL.

21. Proximo gate recomendado

PDF-008I SOURCE-002 products controlled reload rehearsal

El gate PDF-008I debe usar este estandar como prerequisito obligatorio y mantener WooCommerce, sync, scheduler, cron y pipelines en NO-GO salvo autorizacion futura separada.