← Índice 50 Anexos
Anexos · Transversal · datos · A43

Anexo 43 · Plantillas oficiales Excel/CSV + dataset demo

Anexo 43/50 Transversal · datos Transversal · NDA

ANEXO 43

Plantillas oficiales Excel / CSV y dataset demo MVP FARO

Modelo oficial de archivos, columnas, validaciones, ejemplos, errores y datos de prueba

Este anexo corresponde a la Fase 12 — Construcción e implementación, etapa “Plantillas oficiales de datos y dataset demo”. Es el documento que baja a tierra el Contrato de Datos MVP del Anexo 41 y las decisiones técnicas del Anexo 42.

El Anexo 43 responde:

¿Qué archivos exactos necesita FARO para funcionar en el MVP, con qué columnas, qué formato, qué validaciones, qué errores posibles y qué dataset demo se usará para probar toda la cadena dato → acción → Score?

---

1. Objetivo del Anexo 43

El objetivo es definir el estándar oficial de carga de datos FARO para el MVP.

Debe establecer:

1. Qué plantillas Excel / CSV existen.
2. Qué columnas tiene cada plantilla.
3. Qué campos son obligatorios.
4. Qué tipo de dato acepta cada columna.
5. Qué validaciones aplica FARO.
6. Qué errores bloquean la carga.
7. Qué errores permiten carga parcial.
8. Cómo se nombran los archivos.
9. Cómo se versionan las plantillas.
10. Cómo se arma el dataset demo MVP.
11. Cómo se prueba el flujo completo.

La idea es simple:

FARO no puede depender de Excels improvisados. Necesita plantillas oficiales, controladas y trazables.

---

2. Tesis del Anexo 43

La tesis es:

La calidad del diagnóstico FARO empieza antes del algoritmo: empieza en cómo entra el dato.

Si los archivos entran mal:

clientes duplicados,
productos escritos distinto,
fechas mezcladas,
monedas sin aclarar,
costos vacíos,
vendedores sin código,
sucursales mal nombradas,
descuentos negativos,
stock sin unidad,

entonces FARO puede tener la mejor arquitectura del mundo y aun así producir basura elegante.

Regla dura:

Dato malo → KPI débil → alerta débil → diagnóstico débil → acción equivocada → Score poco confiable.

Por eso este anexo es fundacional.

---

3. Principio rector

Cada plantilla FARO debe ser simple para el usuario, pero estricta para el sistema.

No se le puede pedir al cliente que cargue 90 columnas desde el día uno. Pero tampoco se puede aceptar cualquier cosa.

El equilibrio correcto:

MVP:
pocas plantillas,
columnas mínimas,
validaciones fuertes,
errores claros.

Pro:
más columnas,
más módulos,
más validaciones.

Enterprise:
integraciones automáticas,
mapeadores flexibles,
reglas por cliente.

Neural:
datasets históricos,
features,
benchmarks,
aprendizaje.

---

4. Plantillas oficiales MVP

Para el MVP, FARO debería tener estas plantillas base:

CódigoPlantillaObjetivoPrioridad
FARO-PL-001Empresas / sucursales / áreasCrear estructura organizativaAlta
FARO-PL-002ProductosCrear maestro de productosAlta
FARO-PL-003ClientesCrear maestro de clientesAlta
FARO-PL-004Empleados / vendedoresCrear responsables y vendedoresAlta
FARO-PL-005ProveedoresCrear maestro de proveedoresMedia
FARO-PL-006VentasCalcular ventas, margen y descuentosAlta
FARO-PL-007StockCalcular stock crítico, cobertura, inmovilizadoAlta
FARO-PL-008Cuentas por cobrarCalcular cobranza, mora y riesgo clienteAlta
FARO-PL-009ComprasAnalizar reposición, proveedores y costosMedia
FARO-PL-010Gastos / pagosAnalizar egresos y presión financieraMedia
FARO-PL-011Bancos / cajaAnalizar caja y movimientos financierosMedia
FARO-PL-012Acciones inicialesCargar tareas ya existentesMedia
FARO-PL-013EvidenciasCargar respaldo documental inicialBaja/MVP+
FARO-PL-014Objetivos / umbralesDefinir metas por KPIMedia
FARO-PL-015Dataset demoProbar el caso completo FAROAlta

---

5. Formatos aceptados

Formatos MVP

.xlsx
.csv

Recomendación

Excel oficial para usuario común.
CSV para carga técnica o automatización.

Reglas generales

CampoRegla
Encoding CSVUTF-8
Separador CSVcoma o punto y coma, definido por plantilla
FechasYYYY-MM-DD
MonedaCódigo ISO o texto controlado: ARS, USD, CLP, etc.
DecimalesPunto decimal preferido internamente
MilesNo usar separador de miles en CSV
ColumnasNo cambiar nombres oficiales
Hojas ExcelUna hoja por entidad o plantilla
Fórmulas ExcelEvitar en carga; preferir valores finales
ColoresNo tienen valor para FARO
Celdas combinadasProhibidas
Filas vacíasIgnoradas si están al final; error si están en medio con datos parciales

---

6. Convención de nombres de archivo

Formato recomendado:

FARO_[empresa]_[plantilla]_[periodo]_[version].xlsx

Ejemplos:

FARO_GRUPO_ANDINA_PRODUCTOS_2026-05_v1.xlsx
FARO_GRUPO_ANDINA_VENTAS_2026-05_v1.xlsx
FARO_GRUPO_ANDINA_STOCK_2026-05-31_v1.xlsx
FARO_GRUPO_ANDINA_COBRANZA_2026-05_v1.xlsx

Para CSV:

faro_grupo_andina_ventas_2026_05_v1.csv

Regla:

El nombre del archivo no reemplaza los datos internos. El período, empresa y versión también deben estar dentro del archivo o metadata de carga.

---

7. Estructura de cada plantilla

Cada plantilla debe tener:

1. Hoja README
2. Hoja DATA
3. Hoja DICCIONARIO
4. Hoja VALIDACIONES
5. Hoja EJEMPLOS

7.1 README

Debe explicar:

qué plantilla es,
para qué sirve,
quién debe completarla,
frecuencia,
campos obligatorios,
errores comunes,
versión.

7.2 DATA

Es la hoja que FARO procesa.

7.3 DICCIONARIO

Describe cada columna.

7.4 VALIDACIONES

Lista reglas y valores permitidos.

7.5 EJEMPLOS

Incluye 5 a 10 filas modelo.

---

8. Campos técnicos comunes

Todas las plantillas deberían aceptar algunos campos comunes.

CampoTipoObligatorioDescripción
company_codetextoCódigo de empresa
branch_codetextoSegún plantillaCódigo de sucursal
source_systemtextoNoERP, Excel, POS, manual
periodtextoSegún plantillaYYYY-MM o YYYY-Wxx
loaded_bytextoNoUsuario responsable
external_idtextoNoID del sistema origen
notestextoNoObservaciones

---

9. Plantilla FARO-PL-001 — Empresas, sucursales y áreas

Objetivo

Crear la estructura organizativa base.

Hoja: branches

ColumnaTipoObligatorioEjemploValidación
company_codetextoGAONo vacío
company_nametextoGrupo Andina ObrasNo vacío
branch_codetextoMZAÚnico por empresa
branch_nametextoMendozaNo vacío
provincetextoNoMendozaTexto
countrytextoArgentinaTexto
activebooleanTRUETRUE/FALSE

Hoja: areas

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
area_codetextoCOMERCIAL
area_nametextoComercial
parent_area_codetextoNoDIRECCION
activebooleanTRUE

Áreas mínimas MVP:

DIRECCION
COMERCIAL
FINANZAS
STOCK
COMPRAS
RRHH
OPERACIONES
DATA

---

10. Plantilla FARO-PL-002 — Productos

Objetivo

Crear el maestro de productos para ventas, stock, compras y margen.

Columnas oficiales

ColumnaTipoObligatorioEjemploValidación
company_codetextoGAODebe existir
product_codetextoCEM-AVE-50Único
product_nametextoCemento Avellaneda 50kgNo vacío
product_familytextoCementoCatálogo controlado
product_subfamilytextoNoBolsa 50kgTexto
unittextobolsaCatálogo
supplier_codetextoNoPROV-001Si existe, validar
cost_amountnúmeroRecomendado6500>= 0
currencytextoARSARS/USD/etc.
is_criticalbooleanTRUETRUE/FALSE
activebooleanTRUETRUE/FALSE
aliasestextoNoCem Avell 50;Avellaneda bolsaSeparado por ;

Familias iniciales sugeridas

Cemento
Hierro
Cal
Áridos
Sanitarios
Grifería
Pisos
Revestimientos
Pegamentos
Instalaciones agua
Instalaciones gas
Electricidad
Herramientas
Pinturas
Otros

Regla clave

Un producto sin código no debería entrar a facts. Puede quedar en staging pendiente de normalización.

---

11. Plantilla FARO-PL-003 — Clientes

Objetivo

Crear maestro de clientes para ventas, cobranza, mora, riesgo y rentabilidad.

Columnas oficiales

ColumnaTipoObligatorioEjemploValidación
company_codetextoGAODebe existir
customer_codetextoCLI-001Único
customer_nametextoConstructora Los ÁlamosNo vacío
tax_idtextoNo30-12345678-9Recomendado
customer_typetextoEmpresaCatálogo
segmenttextoNoObra / MayoristaCatálogo
branch_codetextoNoMZADebe existir
credit_limitnúmeroNo15000000>= 0
payment_terms_daysenteroNo30>= 0
activebooleanTRUETRUE/FALSE
aliasestextoNoLos Alamos;Constructora LASeparado por ;

Tipos de cliente sugeridos

Consumidor final
Empresa
Constructora
Desarrolladora
Maestro mayor de obra
Arquitecto
Mayorista
Cuenta corriente
Gobierno
Otro

Regla clave

Clientes duplicados distorsionan cobranza y riesgo.

FARO debe detectar posibles duplicados por:

tax_id,
nombre parecido,
alias,
teléfono/email futuro,
misma razón social con escritura distinta.

---

12. Plantilla FARO-PL-004 — Empleados / vendedores / responsables

Objetivo

Crear personas vinculadas a ventas, acciones, RACI y workflow.

Columnas oficiales

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
employee_codetextoEMP-001
full_nametextoJuan Pérez
role_codetextoVENDEDOR
area_codetextoCOMERCIAL
branch_codetextoNoMZA
supervisor_codetextoNoEMP-010
is_sellerbooleanTRUE
is_responsiblebooleanTRUE
activebooleanTRUE

Roles iniciales

DIRECTOR
GERENTE_GENERAL
GERENTE_COMERCIAL
VENDEDOR
FINANZAS
STOCK_RESPONSABLE
COMPRAS
RRHH
OPERACIONES
DATA_OWNER
ADMIN_FARO

Regla clave

Toda acción FARO debe poder asignarse a un responsable o rol responsable.

---

13. Plantilla FARO-PL-005 — Proveedores

Objetivo

Crear proveedores para compras, stock, riesgo proveedor y reposición.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
supplier_codetextoPROV-001
supplier_nametextoCementos Cuyo
supplier_typetextoNoFabricante
product_familytextoNoCemento
payment_terms_daysenteroNo30
lead_time_daysenteroNo7
activebooleanTRUE

Uso FARO

Esta plantilla alimenta:

stock crítico,
plazo proveedor,
compras urgentes,
proveedor crítico,
tensión compras reactivas,
simulación de reposición.

---

14. Plantilla FARO-PL-006 — Ventas

Objetivo

Calcular ventas, margen, descuentos, vendedores, clientes, productos, sucursales y tensiones comerciales.

Columnas oficiales

ColumnaTipoObligatorioEjemploValidación
company_codetextoGAODebe existir
branch_codetextoMZADebe existir
sale_idtextoVTA-000001Único
sale_datefecha2026-05-12YYYY-MM-DD
customer_codetextoCLI-001Debe existir o ir a staging
product_codetextoCEM-AVE-50Debe existir o ir a staging
seller_codetextoNoEMP-003Si existe, validar
quantitynúmero20> 0
unittextobolsaCatálogo
gross_amountnúmero180000>= 0
discount_amountnúmeroNo12000>= 0
net_amountnúmero168000>= 0
cost_amountnúmeroRecomendado130000>= 0
currencytextoARSCatálogo
payment_conditiontextoNoCuenta corrienteCatálogo
invoice_statustextoNoFacturadaCatálogo
notestextoNoVenta obra centroTexto

Campos calculados por FARO

discount_rate = discount_amount / gross_amount
gross_margin_amount = net_amount - cost_amount
gross_margin_rate = gross_margin_amount / net_amount

Código conceptual

def calculate_sale_metrics(row):
    gross_amount = row.get("gross_amount") or 0
    discount_amount = row.get("discount_amount") or 0
    net_amount = row.get("net_amount") or 0
    cost_amount = row.get("cost_amount")

    discount_rate = None
    if gross_amount > 0:
        discount_rate = discount_amount / gross_amount

    gross_margin_amount = None
    gross_margin_rate = None

    if cost_amount is not None:
        gross_margin_amount = net_amount - cost_amount
        if net_amount > 0:
            gross_margin_rate = gross_margin_amount / net_amount

    return {
        "discount_rate": discount_rate,
        "gross_margin_amount": gross_margin_amount,
        "gross_margin_rate": gross_margin_rate
    }

Validaciones críticas

ReglaTipo
sale_id duplicadoBloqueante
sale_date inválidaBloqueante
net_amount negativoBloqueante
product_code inexistenteCarga parcial / pendiente
customer_code inexistenteCarga parcial / pendiente
cost_amount vacíoAdvertencia crítica para margen
discount_amount > gross_amountBloqueante

---

15. Plantilla FARO-PL-007 — Stock

Objetivo

Calcular stock crítico, cobertura, rotación, inmovilizado y riesgo de quiebre.

Columnas oficiales

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
branch_codetextoMZA
stock_datefecha2026-05-31
product_codetextoCEM-AVE-50
quantity_on_handnúmero320
quantity_reservednúmeroNo40
quantity_availablenúmeroNo280
min_stocknúmeroNo150
max_stocknúmeroNo600
average_daily_salesnúmeroNo45
lead_time_daysenteroNo7
unit_costnúmeroNo6500
currencytextoARS
last_movement_datefechaNo2026-05-25

Campos calculados

quantity_available = quantity_on_hand - quantity_reserved
days_coverage = quantity_available / average_daily_sales
stock_value = quantity_on_hand × unit_cost
critical_stock = days_coverage < lead_time_days

Código conceptual

def calculate_stock_metrics(row):
    available = row.get("quantity_available")

    if available is None:
        available = row.get("quantity_on_hand", 0) - row.get("quantity_reserved", 0)

    avg_sales = row.get("average_daily_sales") or 0
    lead_time = row.get("lead_time_days") or 0

    days_coverage = None
    if avg_sales > 0:
        days_coverage = available / avg_sales

    critical = False
    if days_coverage is not None and lead_time > 0:
        critical = days_coverage < lead_time

    return {
        "quantity_available": available,
        "days_coverage": days_coverage,
        "critical_stock": critical
    }

---

16. Plantilla FARO-PL-008 — Cuentas por cobrar

Objetivo

Medir cobranza, mora, riesgo cliente, caja futura y tensión financiera.

Columnas oficiales

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
branch_codetextoNoMZA
customer_codetextoCLI-001
document_idtextoFAC-000123
issue_datefecha2026-04-10
due_datefecha2026-05-10
original_amountnúmero2500000
paid_amountnúmeroNo1000000
outstanding_amountnúmero1500000
currencytextoARS
statustextoVencida
collector_codetextoNoEMP-020
payment_promise_datefechaNo2026-06-05
notestextoNoPrometió pago parcial

Campos calculados

days_overdue = today - due_date
collection_risk = según días vencidos + monto + cliente

Estados permitidos

Pendiente
Parcial
Vencida
Cancelada
En gestión
Incobrable

Validaciones

ReglaTipo
due_date menor a issue_dateBloqueante
outstanding_amount negativoBloqueante
customer_code inexistentePendiente
documento duplicadoBloqueante
status no permitidoBloqueante

---

17. Plantilla FARO-PL-009 — Compras

Objetivo

Analizar compras, proveedores, costos, reposición y plazos.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
branch_codetextoNoMZA
purchase_idtextoOC-00045
purchase_datefecha2026-05-18
supplier_codetextoPROV-001
product_codetextoCEM-AVE-50
quantitynúmero500
unit_costnúmero6200
total_amountnúmero3100000
expected_delivery_datefechaNo2026-05-25
actual_delivery_datefechaNo2026-05-27
statustextoRecibida

Estados permitidos:

Solicitada
Aprobada
Emitida
Parcial
Recibida
Demorada
Cancelada

---

18. Plantilla FARO-PL-010 — Gastos / pagos

Objetivo

Analizar egresos, gastos por área, pagos comprometidos y presión financiera.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
branch_codetextoNoMZA
expense_idtextoGTO-001
expense_datefecha2026-05-20
due_datefechaNo2026-05-30
area_codetextoFINANZAS
categorytextoFlete
supplier_codetextoNoPROV-002
amountnúmero450000
currencytextoARS
document_typetextoNoFactura
payment_statustextoPendiente
legal_documentbooleanNoTRUE
notestextoNoFlete sucursal San Juan

Importante

Esta plantilla permite registrar gastos con o sin documento legal, distinguiendo:

gasto real,
gasto documentado,
gasto no documentado,
área,
sucursal,
categoría.

Esto es fundamental para la realidad operativa de muchas empresas.

---

19. Plantilla FARO-PL-011 — Bancos / caja

Objetivo

Medir caja disponible, movimientos, conciliación y presión financiera.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
account_codetextoBCO-001
account_nametextoBanco Nación CC
movement_idtextoMOV-001
movement_datefecha2026-05-22
descriptiontextoTransferencia cliente
debit_amountnúmeroNo0
credit_amountnúmeroNo3500000
balance_afternúmeroNo18500000
currencytextoARS
related_customer_codetextoNoCLI-001
related_supplier_codetextoNoPROV-001
categorytextoNoCobranza

Regla:

Banco no es contabilidad. FARO puede usarlo para caja y conciliación, pero no debe asumir clasificación perfecta sin reglas.

---

20. Plantilla FARO-PL-012 — Acciones iniciales

Objetivo

Permitir cargar acciones ya existentes al iniciar FARO.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
action_external_idtextoACT-EXT-001
titletextoAuditar descuentos altos
descriptiontextoNoRevisar operaciones mayores al 8%
area_codetextoCOMERCIAL
responsible_codetextoEMP-010
priority_leveltextoP2
statustextoin_progress
due_datefecha2026-06-05
origintextoNoComité comercial
required_evidencetextoNoinforme;listado_operaciones
notestextoNoAcción previa a FARO

Prioridades permitidas:

P1
P2
P3
P4
P5

---

21. Plantilla FARO-PL-013 — Evidencias

Objetivo

Cargar referencias a evidencias iniciales.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
evidence_external_idtextoEVD-001
related_entity_typetextoaction
related_entity_idtextoACT-EXT-001
evidence_typetextoreport
titletextoInforme auditoría descuentos
file_nametextoNoauditoria_descuentos.pdf
file_urltextoNostorage://...
uploaded_bytextoNoEMP-010
uploaded_atfechaNo2026-05-28
validation_statustextopending
sensitivebooleanFALSE

---

22. Plantilla FARO-PL-014 — Objetivos / umbrales

Objetivo

Definir metas y umbrales por KPI, área, sucursal o empresa.

ColumnaTipoObligatorioEjemplo
company_codetextoGAO
kpi_codetextoKPI_GROSS_MARGIN
branch_codetextoNoMZA
area_codetextoNoCOMERCIAL
target_valuenúmero0.28
warning_minnúmeroNo0.24
critical_minnúmeroNo0.20
warning_maxnúmeroNo0.35
critical_maxnúmeroNo0.40
periodtexto2026-05
activebooleanTRUE

Ejemplo:

Margen objetivo: 28%
Advertencia: <24%
Crítico: <20%

---

23. Validaciones generales de FARO

Las validaciones se clasifican en 4 niveles.

NivelTipoQué hace FARO
Error bloqueanteNo permite procesar archivoEstructura inválida
Error por filaProcesa archivo pero deja fila pendienteProducto no reconocido
Advertencia críticaProcesa, pero baja confianzaCosto faltante
Advertencia menorProcesa y registra observaciónCampo opcional vacío

---

24. Errores bloqueantes

Ejemplos:

archivo vacío,
columna obligatoria inexistente,
fecha inválida,
monto negativo donde no corresponde,
sale_id duplicado,
document_id duplicado,
company_code inexistente,
formato de archivo inválido,
plantilla con versión no soportada.

Código conceptual:

def validate_required_columns(columns, required_columns):
    missing = set(required_columns) - set(columns)

    if missing:
        return {
            "valid": False,
            "error_type": "missing_required_columns",
            "missing_columns": list(missing)
        }

    return {"valid": True}

---

25. Errores por fila

Ejemplos:

producto no existe,
cliente no existe,
vendedor no existe,
proveedor no existe,
sucursal no reconocida,
familia de producto inválida,
estado no permitido.

Acción FARO:

la fila queda en staging,
se marca pending_normalization,
no pasa a fact hasta corregirse.

---

26. Advertencias críticas

Ejemplos:

costo faltante,
margen no calculable,
cliente sin límite de crédito,
stock sin venta promedio,
producto sin proveedor,
fecha de vencimiento faltante,
cuenta por cobrar sin cobrador.

Estas advertencias no siempre bloquean, pero reducen confianza.

---

27. Fórmula de calidad de archivo

FARO puede calcular un score de calidad por archivo.

Calidad archivo =
estructura válida × 25%
+ campos obligatorios completos × 25%
+ normalización exitosa × 20%
+ consistencia de datos × 15%
+ trazabilidad × 10%
+ advertencias bajas × 5%

Código:

def score_calidad_archivo(
    estructura_valida,
    campos_completos,
    normalizacion_exitosa,
    consistencia,
    trazabilidad,
    advertencias_bajas
):
    return round(
        estructura_valida * 0.25 +
        campos_completos * 0.25 +
        normalizacion_exitosa * 0.20 +
        consistencia * 0.15 +
        trazabilidad * 0.10 +
        advertencias_bajas * 0.05,
        2
    )

Lectura:

ScoreLectura
0.90-1.00Archivo excelente
0.75-0.89Archivo confiable
0.60-0.74Archivo usable con observaciones
0.40-0.59Archivo débil
<0.40No usar para decisiones fuertes

---

28. Flujo de carga oficial

Usuario descarga plantilla oficial
        ↓
Completa hoja DATA
        ↓
Carga archivo en FARO
        ↓
FARO valida estructura
        ↓
FARO guarda RAW
        ↓
FARO procesa staging
        ↓
FARO valida filas
        ↓
FARO normaliza contra maestros
        ↓
FARO genera facts
        ↓
FARO calcula KPIs
        ↓
FARO detecta señales / alertas / tensiones
        ↓
FARO actualiza Score / Reporte

Regla:

RAW se guarda siempre, incluso si la carga falla.

---

29. Tablas SQL para gestión de plantillas

29.1 Registro de plantillas

CREATE TABLE data_templates (
    template_id TEXT PRIMARY KEY,
    template_code TEXT NOT NULL UNIQUE,
    template_name TEXT NOT NULL,
    description TEXT,
    module_code TEXT,
    version TEXT DEFAULT '1.0',
    accepted_formats JSONB,
    required_columns JSONB,
    optional_columns JSONB,
    active BOOLEAN DEFAULT true,
    created_at TIMESTAMP DEFAULT now(),
    updated_at TIMESTAMP DEFAULT now()
);

29.2 Cargas de archivos

CREATE TABLE data_import_batches (
    import_batch_id TEXT PRIMARY KEY,
    company_id TEXT NOT NULL,
    template_code TEXT NOT NULL,
    template_version TEXT,
    original_filename TEXT,
    file_url TEXT,
    file_hash TEXT,
    uploaded_by TEXT,
    uploaded_at TIMESTAMP DEFAULT now(),
    status TEXT DEFAULT 'uploaded',
    total_rows INTEGER DEFAULT 0,
    valid_rows INTEGER DEFAULT 0,
    error_rows INTEGER DEFAULT 0,
    warning_rows INTEGER DEFAULT 0,
    quality_score NUMERIC
);

29.3 Errores de importación

CREATE TABLE data_import_errors (
    error_id TEXT PRIMARY KEY,
    import_batch_id TEXT NOT NULL,
    row_number INTEGER,
    column_name TEXT,
    error_type TEXT NOT NULL,
    error_message TEXT,
    raw_value TEXT,
    severity TEXT,
    created_at TIMESTAMP DEFAULT now()
);

29.4 Diccionario de columnas

CREATE TABLE template_columns (
    column_id TEXT PRIMARY KEY,
    template_code TEXT NOT NULL,
    column_name TEXT NOT NULL,
    data_type TEXT NOT NULL,
    required BOOLEAN DEFAULT false,
    allowed_values JSONB,
    validation_rule TEXT,
    example_value TEXT,
    description TEXT,
    created_at TIMESTAMP DEFAULT now()
);

---

30. Dataset demo MVP

El dataset demo debe contar una historia.

No debe ser aleatorio.

Empresa demo

Nombre:
Grupo Andina Obras

Tipo:
Empresa comercial de insumos para construcción

Sucursales:
Mendoza
San Juan
Central

Áreas:
Dirección
Comercial
Finanzas
Stock
Compras
RRHH
Operaciones
Data

---

31. Objetivo del dataset demo

El dataset demo debe permitir probar:

carga Excel,
RAW,
staging,
normalización,
maestros,
facts,
KPIs,
señales,
alertas,
tensiones,
diagnóstico,
recomendaciones,
acciones,
workflow,
evidencia,
FARO Score,
reporte ejecutivo.

Y debe demostrar el caso central:

La empresa crece, pero no necesariamente mejora.

---

32. Caso demo principal

Situación

Ventas suben: +18%
Margen baja: 28% → 21%
Descuento sube: 6% → 12%
Días de cobranza suben: 32 → 43
Stock crítico en productos tractores
Acciones vencidas
Costos faltantes en algunos productos

FARO debe detectar

Tensión:
Crecimiento no rentable

Alertas:
Margen bajo
Descuento alto
Cobranza lenta
Stock crítico
Acciones vencidas
Calidad de datos media

FARO debe recomendar

Auditar descuentos altos
Priorizar cobranza de clientes críticos
Simular comisión por margen y cobro
Validar stock crítico
Completar costos faltantes

FARO Score demo

Score inicial:
66

Score proyectado luego de acciones:
74

---

33. Volumen del dataset demo

EntidadCantidad sugerida
Empresas1
Sucursales3
Áreas8
Productos50
Familias10-15
Clientes80
Proveedores15
Empleados20
Vendedores8
Ventas1.000
Registros de stock150
Cuentas por cobrar120
Compras80
Gastos100
Acciones20
Evidencias10
KPIs calculados25-40
Alertas15
Tensiones5-10

---

34. Distribución demo de productos

FamiliaCantidadEjemplo
Cemento5Cemento Avellaneda 50kg
Hierro6Hierro 8mm
Sanitarios6Inodoro largo
Grifería6Monocomando cocina
Pisos8Porcelanato 60x60
Revestimientos5Cerámica baño
Pegamentos4Adhesivo porcelanato
Instalaciones agua4Caño termofusión
Instalaciones gas3Caño epoxi
Otros3Herramientas menores

Productos críticos demo:

Cemento Avellaneda 50kg
Hierro 8mm
Hierro 10mm
Pegamento porcelanato
Caño termofusión 3/4

---

35. Distribución demo de clientes

SegmentoCantidadComportamiento esperado
Constructoras15Alta compra, cuenta corriente
Desarrolladoras5Compras grandes, canjes posibles
Maestros de obra20Compra recurrente
Arquitectos10Referidos y recomendaciones
Mayoristas10Bajo margen, volumen
Consumidor final20Ticket menor

Clientes conflictivos demo:

Constructora Los Álamos:
alta compra, mora creciente.

Desarrolladora Sur:
propone canje.

Obra Norte:
alto descuento y cobranza lenta.

Mayorista Ruta 7:
volumen alto, margen bajo.

---

36. Distribución demo de ventas

El dataset debe tener dos períodos comparables.

Período A:
2026-04

Período B:
2026-05

Comportamiento deseado

IndicadorAbrilMayoVariación
Ventas netas100118+18%
Margen bruto28%21%-7 puntos
Descuento promedio6%12%+6 puntos
Días de cobranza3243+11 días
Stock crítico6%14%+8 puntos
Acciones vencidas15+4

---

37. Generador conceptual de ventas demo

import random
from datetime import date, timedelta

def generate_demo_sales(products, customers, sellers, branches, period_start, days, rows):
    sales = []

    for i in range(rows):
        product = random.choice(products)
        customer = random.choice(customers)
        seller = random.choice(sellers)
        branch = random.choice(branches)

        sale_date = period_start + timedelta(days=random.randint(0, days - 1))
        quantity = random.randint(1, 80)

        base_price = product["price"]
        gross_amount = quantity * base_price

        discount_rate = random.choice([0.04, 0.06, 0.08, 0.12, 0.15])
        discount_amount = gross_amount * discount_rate
        net_amount = gross_amount - discount_amount

        cost_rate = random.choice([0.70, 0.74, 0.78, 0.82])
        cost_amount = net_amount * cost_rate

        sales.append({
            "sale_id": f"VTA-{i+1:06d}",
            "sale_date": sale_date.isoformat(),
            "branch_code": branch["branch_code"],
            "customer_code": customer["customer_code"],
            "product_code": product["product_code"],
            "seller_code": seller["employee_code"],
            "quantity": quantity,
            "gross_amount": round(gross_amount, 2),
            "discount_amount": round(discount_amount, 2),
            "net_amount": round(net_amount, 2),
            "cost_amount": round(cost_amount, 2),
            "currency": "ARS"
        })

    return sales

---

38. Dataset demo con errores intencionales

El dataset debe incluir errores para probar validaciones.

ErrorCantidad sugeridaResultado esperado
Producto inexistente10 filasPending normalization
Cliente duplicado5 casosAdvertencia duplicado
Costo faltante30 ventasBaja confianza margen
Fecha inválida3 filasError bloqueante por fila
Descuento mayor al bruto2 filasError bloqueante
Stock negativo3 filasError bloqueante
Vendedor inexistente5 filasPending normalization
Cliente sin CUIT10 clientesAdvertencia
Cuenta vencida sin due_date2 filasError
Producto crítico sin lead_time5 productosAdvertencia stock

Esto es importante: el sistema debe probarse con problemas reales, no con un Excel perfecto de fantasía.

---

39. Dataset demo de acciones

Acciones iniciales:

AcciónResponsablePrioridadEstado
Auditar descuentos mayores al 8%Gerente ComercialP2in_progress
Priorizar cobranza clientes críticosFinanzasP1overdue
Validar stock físico cementoStockP2assigned
Completar costos faltantesData OwnerP2in_progress
Simular nueva comisiónRRHH/ComercialP3created
Evaluar canje Desarrolladora SurDirección/FinanzasP2waiting_evidence
Revisar proveedor de hierroComprasP3assigned
Emitir reporte semanalGerencia GeneralP2completed

---

40. Dataset demo de evidencias

EvidenciaAcción asociadaEstado
Informe parcial descuentosAuditar descuentospending
Ranking deuda vencidaPriorizar cobranzaapproved
Foto conteo cementoValidar stockuploaded
Archivo costos actualizadosCompletar costosneeds_correction
Simulación comisión inicialSimular comisiónpending
Propuesta canjeEvaluar canjeuploaded

---

41. Validaciones de negocio para el demo

FARO debe detectar:

Ventas

ventas suben más de 10%,
margen baja más de 3 puntos,
descuento sube más de 2 puntos.

Cobranza

días de cobranza suben más de 5 días,
deuda vencida supera umbral,
cliente crítico concentra mora.

Stock

días de cobertura menor al plazo proveedor,
producto crítico bajo mínimo,
stock inmovilizado alto.

Ejecución

acciones P1 vencidas,
acciones sin evidencia,
responsables sobrecargados.

---

42. Salidas esperadas del dataset demo

Al cargar el dataset, FARO debería generar:

KPIs:
ventas netas,
margen bruto,
descuento promedio,
días de cobranza,
stock crítico,
acciones vencidas.

Alertas:
margen bajo,
descuento alto,
cobranza lenta,
stock crítico,
acción P1 vencida.

Tensiones:
crecimiento no rentable,
caja débil,
stock crítico con demanda activa,
dirección sin ejecución,
datos insuficientes para margen.

Diagnóstico:
la empresa crece, pero deteriora margen, caja y ejecución.

Recomendaciones:
auditar descuentos,
priorizar cobranza,
validar stock crítico,
completar costos,
simular comisión.

FARO Score:
66 inicial.

Reporte:
resumen ejecutivo semanal.

---

43. Plantilla de salida de errores para usuario

Cuando falle una carga, FARO debe explicar claro.

Ejemplo:

Archivo: FARO_GRUPO_ANDINA_VENTAS_2026-05_v1.xlsx

Estado:
Procesado con observaciones.

Total filas:
1.000

Filas válidas:
940

Filas pendientes:
50

Filas con error bloqueante:
10

Problemas principales:
1. 30 ventas sin costo_amount.
2. 10 productos no reconocidos.
3. 5 clientes no reconocidos.
4. 3 fechas inválidas.
5. 2 descuentos mayores al importe bruto.

Acción recomendada:
Corregir productos no reconocidos y costos faltantes antes de usar diagnóstico de margen.

---

44. Estados de carga

EstadoSignificado
uploadedArchivo recibido
validatingValidando estructura
validation_failedFalló estructura
raw_savedRAW guardado
staging_createdStaging creado
partially_processedProcesado con errores
normalizedNormalizado
facts_createdFacts generados
kpis_calculatedKPIs calculados
completedCarga completa
failedError general

---

45. Motor de carga FARO

def process_data_import(file, template, company_id, uploaded_by):
    batch = create_import_batch(file, template, company_id, uploaded_by)

    structure_result = validate_structure(file, template)

    if not structure_result["valid"]:
        save_import_errors(batch["id"], structure_result["errors"])
        return {
            "status": "validation_failed",
            "batch_id": batch["id"]
        }

    raw_event = save_raw(file, batch)

    staging_result = create_staging_rows(file, template, raw_event)

    normalization_result = normalize_staging_rows(staging_result["rows"])

    facts_result = create_facts(normalization_result["valid_rows"])

    quality_score = calculate_import_quality(
        total_rows=staging_result["total_rows"],
        valid_rows=facts_result["created_rows"],
        error_rows=staging_result["error_rows"],
        warning_rows=staging_result["warning_rows"]
    )

    return {
        "status": "completed_with_observations" if staging_result["error_rows"] else "completed",
        "batch_id": batch["id"],
        "quality_score": quality_score
    }

---

46. Cálculo simple de calidad de importación

def calculate_import_quality(total_rows, valid_rows, error_rows, warning_rows):
    if total_rows == 0:
        return 0

    valid_rate = valid_rows / total_rows
    error_penalty = error_rows / total_rows
    warning_penalty = (warning_rows / total_rows) * 0.5

    score = valid_rate - error_penalty - warning_penalty

    return max(0, min(1, round(score, 2)))

---

47. Relación plantilla → tabla destino

PlantillaRAWStagingFacts / Dim
Productosraw_ingestion_eventsstaging_productsdim_products
Clientesraw_ingestion_eventsstaging_customersdim_customers
Empleadosraw_ingestion_eventsstaging_employeesdim_employees
Ventasraw_ingestion_eventsstaging_salesfact_sales
Stockraw_ingestion_eventsstaging_inventoryfact_inventory
CxCraw_ingestion_eventsstaging_arfact_accounts_receivable
Comprasraw_ingestion_eventsstaging_purchasesfact_purchases
Gastosraw_ingestion_eventsstaging_expensesfact_expenses
Bancosraw_ingestion_eventsstaging_bank_movementsfact_bank_movements
Accionesraw_ingestion_eventsstaging_actionsaction_events

---

48. Orden recomendado de carga inicial

Para evitar errores, cargar en este orden:

1. Empresa / sucursales / áreas
2. Empleados / responsables
3. Proveedores
4. Productos
5. Clientes
6. Ventas
7. Stock
8. Cuentas por cobrar
9. Compras
10. Gastos
11. Bancos / caja
12. Acciones iniciales
13. Evidencias
14. Objetivos / umbrales

Regla:

Primero maestros. Después movimientos.

Cargar ventas antes de productos y clientes es pedirle al sistema que adivine. FARO no debería adivinar; debería normalizar.

---

49. Versionado de plantillas

Cada plantilla debe tener versión.

Ejemplo:

FARO-PL-006 Ventas v1.0
FARO-PL-006 Ventas v1.1
FARO-PL-006 Ventas v2.0

Cuándo subir versión menor

se agrega columna opcional,
se mejora validación,
se corrige descripción.

Cuándo subir versión mayor

se cambia nombre de columna,
se cambia estructura,
se cambia lógica de cálculo,
se vuelve obligatoria una columna antes opcional.

---

50. Gobierno de plantillas

Las plantillas no deben cambiar sin control.

Debe quedar registrado:

quién cambió,
qué cambió,
por qué,
qué versión reemplaza,
desde cuándo aplica,
qué clientes usan qué versión.

Tabla sugerida:

CREATE TABLE template_versions (
    template_version_id TEXT PRIMARY KEY,
    template_code TEXT NOT NULL,
    version TEXT NOT NULL,
    change_summary TEXT,
    breaking_change BOOLEAN DEFAULT false,
    active BOOLEAN DEFAULT true,
    created_by TEXT,
    created_at TIMESTAMP DEFAULT now()
);

---

51. Checklist de validación antes de usar un archivo para diagnóstico

Antes de usar datos para diagnóstico fuerte, FARO debe revisar:

¿El archivo tiene calidad >= 0.75?
¿Los productos se normalizaron?
¿Los clientes se normalizaron?
¿El margen tiene costos suficientes?
¿La cobranza tiene vencimientos?
¿El stock tiene fecha actual?
¿Las sucursales están completas?
¿Hay duplicados relevantes?
¿Hay advertencias críticas?

Si no cumple:

FARO puede mostrar KPIs orientativos,
pero debe bajar confianza del diagnóstico.

---

52. Impacto de plantillas en FARO Score

La calidad de plantillas afecta:

calidad de datos,
confianza de KPIs,
confianza del diagnóstico,
FARO Score,
reportes ejecutivos,
priorización.

Ejemplo:

Si ventas están completas pero costos faltan en 30% de filas,
FARO puede calcular ventas,
pero margen y tensión crecimiento no rentable deben tener confianza media/baja.

---

53. Riesgos si no existe el Anexo 43

RiesgoConsecuencia
Cada cliente manda Excel distintoImplementación lenta
Datos sin estructuraKPIs poco confiables
Sin RAWNo hay trazabilidad
Sin stagingErrores contaminan facts
Sin validacionesDiagnósticos débiles
Sin dataset demoNo se prueba el MVP
Sin versionadoCambios rompen cargas
Sin diccionarioCliente no sabe completar
Sin errores clarosSoporte se satura
Sin orden de cargaNormalización falla

---

54. Errores comunes

Aceptar cualquier Excel.
No exigir códigos.
Usar nombres como identificadores únicos.
No guardar RAW.
No separar staging.
No validar fechas.
No validar duplicados.
No distinguir error de advertencia.
No mostrar errores al usuario.
No tener dataset demo diseñado.
No versionar plantillas.

El más peligroso:

Usar Excel directo para dashboards y después querer convertir eso en sistema. Es construir arriba de barro.

---

55. Output final del Anexo 43

Al finalizar este anexo, FARO debe tener definido:

1. Plantillas oficiales MVP.
2. Formatos aceptados.
3. Convención de nombres de archivo.
4. Estructura interna de cada plantilla.
5. Campos técnicos comunes.
6. Plantilla de empresas/sucursales/áreas.
7. Plantilla de productos.
8. Plantilla de clientes.
9. Plantilla de empleados/vendedores.
10. Plantilla de proveedores.
11. Plantilla de ventas.
12. Plantilla de stock.
13. Plantilla de cuentas por cobrar.
14. Plantilla de compras.
15. Plantilla de gastos/pagos.
16. Plantilla de bancos/caja.
17. Plantilla de acciones iniciales.
18. Plantilla de evidencias.
19. Plantilla de objetivos/umbrales.
20. Validaciones generales.
21. Errores bloqueantes.
22. Errores por fila.
23. Advertencias críticas.
24. Score de calidad de archivo.
25. Flujo oficial de carga.
26. Tablas SQL de plantillas e importaciones.
27. Dataset demo MVP.
28. Caso demo principal.
29. Volúmenes demo.
30. Errores intencionales demo.
31. Salidas esperadas.
32. Estados de carga.
33. Motor de carga.
34. Relación plantilla → tabla destino.
35. Orden recomendado de carga.
36. Versionado de plantillas.
37. Gobierno de plantillas.
38. Checklist antes de diagnóstico.
39. Impacto en FARO Score.

---

56. Conexión con otros anexos

Anexo relacionadoRelación
**Anexo 41 — Contrato de Datos MVP**Define qué datos hacen falta; este anexo define cómo se cargan.
**Anexo 42 — Decisiones técnicas pendientes**Define criterios técnicos para plantillas, RAW, staging, validaciones y dataset.
**Anexo 4 — Ingesta**Usa estas plantillas como fuente inicial.
**Anexo 5 — RAW**Guarda archivo original y payload.
**Anexo 6 — Staging**Recibe filas limpias y pendientes.
**Anexo 10 — Normalización**Usa códigos, aliases y maestros.
**Anexo 11 — Tablas maestras**Se alimenta con productos, clientes, empleados y proveedores.
**Anexo 12 — Modelo ejecutivo**Convierte plantillas en facts.
**Anexo 17 — KPIs**Calcula indicadores desde facts.
**Anexo 21 — Alertas**Usa KPIs calculados desde estas cargas.
**Anexo 22 — Tensiones**Detecta contradicciones desde datos cargados.
**Anexo 35 — FARO Score**Ajusta Score según calidad de datos.
**Anexo 39 — Arquitectura técnica**Implementa técnicamente el flujo de carga.
**Anexo 40 — Implementación**Usa estas plantillas para construir el MVP.

---

57. Frase para explicar el Anexo 43

El Anexo 43 define las plantillas oficiales Excel/CSV y el dataset demo MVP de FARO Connect. Establece qué archivos se cargan, qué columnas tienen, qué validaciones aplican, cómo se procesan, qué errores se detectan, cómo se mide la calidad del archivo y qué datos demo se usan para probar la cadena completa dato → KPI → alerta → tensión → acción → Score.

Versión más directa:

Sin plantillas oficiales, FARO depende del caos del Excel de turno. Con este anexo, cada dato entra con estructura, validación, trazabilidad y propósito. Ahí empieza la dirección seria.

Profundización técnica v2.0 · Validación embedded en Excel

Capa 1 · Data validation rules embebidas en cada plantilla

Cada plantilla PL-NNN tiene reglas de validación al nivel de celda Excel (no solo en backend):

PL-006 Ventas
  · fecha_venta: DateRule between(today-90, today)
  · cliente_codigo: ListValidation from sheet 99_Diccionarios
  · cantidad: NumberRule >0
  · precio_unitario: NumberRule >=0
  · descuento_pct: NumberRule between(0, 100)
  · canal_venta: ListValidation (Físico|E-commerce|Mayorista)
  · medio_cobro: ListValidation (Efectivo|Transf|Cheque|Tarjeta)

Capa 2 · Validación al importar (60 CLN + 120 DQ)

Cliente carga → FARO ejecuta:
  1. Schema check (columnas obligatorias presentes)
  2. Type coercion (fechas ISO, numeric, etc.)
  3. CLN-001 a CLN-060 · normalización
  4. DQ-001 a DQ-120 · validación con severidad
  5. Cross-validation con maestros existentes
  6. Score calidad por sheet
  7. Reporte de errores + advertencias

Capa 3 · Demo dataset incluido

PL-015 Dataset_Demo tiene 19 sheets con datos cruzados (no random):