# Reporting — Roadmap de tareas

Este documento divide la implementación en tickets pequeños y verificables. **F-142 solo entrega discovery/arquitectura; no implementa dashboards.** Las referencias `RPT-*` son identificadores de trabajo del plan y se han abierto en backlog como:

| Plan | Ticket backlog | Título |
|---|---|---|
| RPT-001 | F-143 | Contracts, filters and RBAC |
| RPT-002 | F-144 | Historical store and financial snapshots |
| RPT-003 | F-145 | Payment lines and POS cash-safe capture |
| RPT-004 | F-146 | ReportingService, summary and sales API |
| RPT-005 | F-147 | Admin reporting shell and global filters |
| RPT-006 | F-148 | Sales dashboard and channel views |
| RPT-007 | F-149 | Product, category and brand reports |
| RPT-008 | F-150 | CSV export |

RPT-009 en adelante se abrirá como backlog cuando sus dependencias P0 estén aprobadas.

## Dependencias y orden recomendado

```text
RPT-001 contratos/filtros/RBAC
   ├── RPT-002 datos históricos mínimos (store, tax/cost snapshots)
   ├── RPT-003 líneas de pago POS/ecommerce
   └── RPT-004 ReportingService + summary/sales
              ├── RPT-005 Admin shell + filtros URL
              ├── RPT-006 Sales dashboard / channel / store / terminal
              ├── RPT-007 Product/category/brand reports
              └── RPT-008 CSV export

RPT-003 ──> RPT-011 Payments report
RPT-002 ──> RPT-012 Tax report / RPT-013 margin
POS cash implementation ──> RPT-014 cash report
Refund model ──> RPT-015 refunds report
```

Regla: ningún ticket debe inventar datos ausentes; si una métrica no tiene fuente, se incorpora como `unavailable` o se crea primero el ticket de modelo correspondiente.

---

# P0 — Base útil y primera entrega

## RPT-001 — Reporting contracts, filters and permissions

**Objetivo:** crear `ReportingFilters`, parser común, rangos relativos, comparación y permisos backend/frontend.

**Incluye:**

- intervalos `[from,to)` en UTC + zona `Europe/Madrid` para agrupaciones;
- presets hoy/ayer/7/30 días/mes/año/período anterior;
- `channel`, tiendas, terminales, cajeros, producto, categoría, marca, cliente, estado;
- paginación, orden y límite máximo;
- respuesta común con `range`, `comparison`, `dataAvailability`, `updatedAt`;
- permisos `REPORTING_*`, incluyendo `REPORTING_FINANCIAL` y `REPORTING_EXPORT`;
- tests de fechas invertidas, zona, cero y filtros combinados.

**No incluye:** SQL de reportes ni UI final.

## RPT-002 — Reporting data snapshots and store scope

**Objetivo:** hacer reportables de forma fiable las dimensiones históricas obligatorias.

**Evaluar/implementar en migraciones:**

- `orders_orders.store_id` NOT NULL, FK, backfill y escritura desde ecommerce/POS/admin;
- snapshot `vat_rate` y `cost_at_sale_cents` nullable en `orders_items`;
- snapshot de marca/categoría solo si el negocio necesita histórico estable, no copiar el catálogo sin justificación;
- separación de `shipping_cents` de los totales;
- índices medidos para fecha/tienda/canal.

**Aceptación:** migración reversible/documentada, ventas antiguas conservan valores, margen/IVA siguen `unavailable` si faltan snapshots.

## RPT-003 — Payment lines and cash-safe payment capture

**Objetivo:** poder informar efectivo/tarjeta/otros y pagos mixtos sin guardar datos de tarjeta.

**Incluye:**

- tabla inmutable `order_payment_lines` o equivalente, con order, método, tienda, terminal, sesión, importe, currency, provider ref, estado y timestamps;
- integración de venta ecommerce y POS con la línea real;
- idempotencia por evento/provider;
- no PAN/CVV;
- relación con reembolsos preparada.

**Aceptación:** una venta con uno o varios métodos se puede sumar exactamente una vez; pruebas de duplicado y cross-store.

## RPT-004 — ReportingService, summary and sales API

**Objetivo:** primera API real de reporting a partir de pedidos/líneas.

**Endpoints:** `GET /reporting/summary` y `GET /reporting/sales`.

**Métricas P0:** ventas totales registradas, pedidos/tickets, unidades, ticket medio, descuentos e impuestos registrados; tendencia y comparación cuando haya período anterior.

**Agrupaciones:** día, semana, mes, canal, tienda y terminal cuando existan.

**Aceptación:** SQL parametrizado, sin N+1, estados documentados, respuesta de disponibilidad, tests unitarios de fórmulas e integración con ecommerce/POS.

## RPT-005 — Admin Reporting shell and global filters

**Objetivo:** añadir `Reporting` al menú Admin y una pantalla `/reporting` reutilizando Auth/API/layout existentes.

**Componentes:** `ReportingLayout`, `ReportingFilters`, `DateRangePicker`, `ComparisonSelector`, `KpiCard`, `ComparisonKpi`, loading/error/empty/no-data states.

**Aceptación:** filtros se reflejan en URL, sobreviven navegación válida, tablet usable, no se cargan listas masivas en frontend, backend autoriza cada petición.

## RPT-006 — Sales dashboard and channel/store views

**Objetivo:** presentar summary/sales real sin recalcular en React.

**Incluye:** KPIs, tendencia, ecommerce vs TPV, tiendas, terminales y tabla paginada con drill-down a pedidos.

**Aceptación:** filtros globales, comparación equivalente, importes EUR en céntimos convertidos solo para presentación, `unavailable` cuando no hay store/terminal histórico.

## RPT-007 — Product, category and brand reports

**Objetivo:** ranking de productos y desglose de categorías/marcas usando catálogo real.

**Incluye:** top 10/25/50, unidades, ventas de mercancía, precio medio, descuento, devoluciones si existen; filtros y orden server-side.

**Nota:** marcar que categoría/marca es clasificación actual mientras no exista snapshot histórico.

## RPT-008 — CSV export

**Objetivo:** exportar summary/sales/products respetando exactamente filtros, rango, orden y columnas.

**Aceptación:** stream/paginación server-side, BOM/encoding adecuado para Excel, cabecera con fecha/zona/filtros, permission `REPORTING_EXPORT`, límites y auditoría.

## RPT-009 — Reporting frontend API client and table primitives

**Objetivo:** adaptar `api-client.ts` con tipos de respuesta y tabla reutilizable sin duplicar fetch/serialización.

**Incluye:** abort/cancel de consultas, estados de error, columnas configurables y enlaces drill-down.

## RPT-010 — P0 integration and regression suite

**Objetivo:** fixtures transaccionales y pruebas end-to-end.

**Casos:** venta ecommerce, venta POS `COMPLETED`, pedido cancelado, descuento, stock confirmado, comparación de período, filtro tienda no autorizada y export con filtros.

---

# P1 — Informes operativos y comerciales

## RPT-011 — Payments report

Depende de RPT-003. Importe, operaciones, porcentaje, medio y devoluciones por método; admite pago mixto y filtra método/tienda/terminal.

## RPT-012 — Fiscal/IVA report

Depende del snapshot fiscal de RPT-002. Base imponible, tipo de IVA, cuota y total usando datos de la venta, nunca configuración actual.

## RPT-013 — Customers report

Clientes únicos, nuevos, recurrentes, pedidos, ventas, ticket y última compra. Ocultar PII según permiso y separar walk-ins.

## RPT-014 — Inventory report

Stock actual por tienda, vendido, stock bajo/sin stock, rotación aproximada y días de stock solo con denominador suficiente. Usa `inventory_stock`, movimientos y pedidos sin duplicar ventas.

## RPT-015 — Products without movement

Configurable 30/60/90 días: stock positivo + última venta anterior al umbral. Indicar “sin historial” distinto de “sin movimiento”.

## RPT-016 — Categories and brands detail

Tablas con ventas/unidades/pedidos/% y navegación a producto; clasificación histórica documentada.

## RPT-017 — Discounts report

Depende de snapshot de promoción. Total, porcentaje, media, código/tipo, producto/categoría/tienda/terminal/cajero y descuentos manuales identificables.

## RPT-018 — Refund model and report

Crear primero `order_refunds`/líneas y luego importe, cantidad, motivo, producto, canal, tienda, terminal, usuario y porcentaje sobre ventas. No inferir importe desde estado.

## RPT-019 — Cash sessions report

Depende de movimientos de caja/pagos POS. Apertura, ventas efectivo, esperado, contado, diferencia, cajero, terminal, tienda y filtro “solo diferencias”. Proteger con `REPORTING_CASH`/`REPORTING_FINANCIAL`.

## RPT-020 — Drill-down navigation

Ventas → canal → tienda → terminal → producto → pedido/ticket, conservando filtros compatibles y evitando IDs sensibles en URLs no autorizadas.

## RPT-021 — Period comparison UX

Presets y período equivalente; mostrar valor actual, anterior y porcentaje/null. Tests para períodos con cero y distinta duración.

## RPT-022 — Server-side reporting tables

Paginación, búsqueda, sorting, selección de columnas y límites. Nunca cargar decenas de miles de filas en React.

---

# P2 — Análisis avanzado condicionado a datos

## RPT-023 — Historical cost and gross margin

Solo tras `cost_at_sale_cents`: revenue, COGS, gross profit y margen por producto/categoría/marca/tienda/canal. No usar el coste actual.

## RPT-024 — Sales by hour and weekday

Agrupación en zona local, line/bar chart y tabla de horas punta/valle. Validar volumen mínimo para evitar conclusiones engañosas.

## RPT-025 — Sales heatmap

Heatmap día de semana/hora por ventas o tickets, con selector de métrica y accesibilidad alternativa en tabla.

## RPT-026 — Advanced stock analytics

Rotación, velocidad de venta, días de stock y productos sin movimiento con ventanas configurables y advertencia de aproximación.

## RPT-027 — XLSX export

Exportación server-side con columnas/formato/filtros y límites; conservar auditoría y evitar bloqueo del request.

## RPT-028 — PDF export

Solo para informes donde el formato aporte valor (resumen/caja/fiscal); no convertir tablas grandes a PDF sin paginación.

---

# P3 — Evolución futura, no implementar ahora

- RPT-029 — Forecast de ventas.
- RPT-030 — Forecast y alertas de stock.
- RPT-031 — Alertas de negocio.
- RPT-032 — Informes programados/email.
- RPT-033 — ABC de productos, cohortes y RFM.
- RPT-034 — Integración con BI/API externa.
- RPT-035 — Materialized views/agregaciones cuando volumen y EXPLAIN lo justifiquen.

## Definition of Done común

- Contrato/API/documentación actualizados.
- Backend calcula métricas; frontend no duplica reglas financieras.
- Query parametrizada y plan revisado para consultas críticas.
- Permiso backend + prueba negativa cross-store.
- Estados loading/empty/error/no-data/unavailable.
- Unit tests de cálculos y integration tests de datos reales.
- CSV/XLSX respeta filtros si aplica.
- `npm run build`, `npm test`, `./scripts/verify.sh` y gates reviewer/security/qa verdes.
