> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coupons.piixan.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Validador

> Comprueba tus ficheros de eventos v1 antes de enviarlos: esquema, cobertura, IVA, cupones y huecos.

El validador se ejecuta **de tu lado**, sobre los ficheros que produce tu
conector. El motor nunca ve tu base de datos: solo publica el contrato y esta
herramienta. Úsalo antes de la carga inicial del histórico y cada vez que
cambies el conector.

## Instalación

```sh theme={null}
uv tool install piixan-ai-coupons   # o: pipx install piixan-ai-coupons
validador --help
```

## Uso

```sh theme={null}
validador eventos_2025.jsonl eventos_2026.parquet --salida informe.md --json informe.json
```

Formatos admitidos:

| formato                     | `extra`                                                                    | notas                                          |
| --------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------- |
| JSONL (`.jsonl`, `.ndjson`) | objeto anidado                                                             | el canónico: un evento por línea               |
| CSV                         | columnas `extra.margen`, `extra.ticket_id`… o una columna `extra` con JSON | vacío = ausente                                |
| Parquet                     | struct o columnas aplanadas                                                | `ts` debe ser `Datetime` con `time_zone="UTC"` |

Opciones: `--antiguedad-maxima-dias` (por defecto 5 años) y `--estricto`
(código de salida 1 si hay algún rechazo o duplicado, útil en tu CI).

## Qué comprueba

<AccordionGroup>
  <Accordion title="Esquema">
    Cada evento contra el [contrato v1](/guias/contrato-eventos). Los rechazos se
    agrupan por campo y motivo, con hasta tres ejemplos (`fichero:línea`).
  </Accordion>

  <Accordion title="Duplicados y fechas">
    `event_id` repetidos (se descartan, no es error) y fechas futuras o más
    antiguas que la antigüedad máxima.
  </Accordion>

  <Accordion title="Cobertura por mes">
    Eventos por tipo, tickets, clientes, Σ importe y Σ margen en MXN y el
    porcentaje de compras con margen en cero. Un mes con margen en cero no sirve
    para aprender.
  </Accordion>

  <Accordion title="IVA">
    Si envías `ticket_total`, la mediana de Σ líneas / total dice si los importes
    traen IVA. Deben ir **sin IVA**; el total del ticket, como en el ticket.
    Esperado: ≈ 0.862.
  </Accordion>

  <Accordion title="Cupones">
    Redenciones enlazadas a su envío por `cupon_emitido_id`, redenciones antes del
    envío o después de la caducidad, cupones vencidos sin evento de caducidad ni
    redención, y envíos con `decision_id` (cuando ya decide el motor).
  </Accordion>

  <Accordion title="Huecos">
    Meses sin eventos de un tipo que aparece en otros meses y días sin ventas.
  </Accordion>
</AccordionGroup>

## Condiciones para el alta

El informe termina con la lista de condiciones que la consola exige para pasar
de «contrato validado» a «histórico cargado», y el valor actual de cada una:

```text theme={null}
- ✓ tasa de rechazo < 2 %: 0.31%
- ✗ ≥ 3 meses de ventas con margen (< 10 % en cero): 2 meses
- ✓ hay cupones en el histórico: 41,203 recibidos
- ✓ ≥ 90 % de redenciones enlazadas a su envío: 97.4%
- ✗ sin cupones vencidos sin resultado (o CUPON_CADUCADO presente): 3,118 vencidos sin evento
- ✓ sin duplicados: 0
```

<Tip>
  Si no tienes el margen por línea, calcula un coste estándar por artículo o
  categoría en el conector. Sin margen, el motor no puede medir nada.
</Tip>
