2.5 KiB
2.5 KiB
F-143 — Acceptance
AC1 — contrato de filtros
GET /reporting/filters/schema(admin) → 200 →{ filterSchema, comparison, dataAvailability, permissions }.comparison.modesincluyenone,previous_equal,previous_calendar.comparison.rangeBounds === 'inclusive_start_exclusive_end'.dataAvailabilityrefleja el baseline F-142 (grossSales/discounts/tax/unitsSold/orders/customersavailable; netSales/margin/paymentMethod/refunds/shippingunavailable).filterSchema.filtersincluyestoreId(repeatable, uuid),compare,channel,groupBy,page,pageSize.
AC2 — RBAC (backend-authority)
customer(role customer) → 403 en/reporting/filters/schemay/reporting/filters/validate.adminyeditor→ 200 en/reporting/filters/schema(tienenREPORTING_VIEW).admin/editor/pos_manager/pos_cashier→ 200 en/reporting/filters/validate(tienenREPORTING_SALES).customerNO aparece enREPORTING_ROLE_PERMISSIONScon permisos.
AC3 — parseo + rango [from,to)
GET /reporting/filters/validate?from=2026-08-01T00:00:00Z&to=2026-08-31T23:59:59Z&compare=previous_equal→ 200 →filters.range.from/tonormalizados;comparison.range.from<filters.range.from<filters.range.to;comparison.range.to===filters.range.from.pageSizeypagevienen por defecto (1 y 50) cuando no se pasan.
AC4 — validación
from > to→ 400 (VALIDATION_ERROR/ 400).?storeId=<single uuid>parsea a array de 1 elemento;?storeId=a&storeId=ba array de 2.- UUID inválido → 400.
AC5 — comparison modes (unit)
comparisonRange(range, 'none')===null.previous_equal:to_prev === from_actual,from_prev === from_actual - duration.previous_calendar: ventana alineada a UTC,to_prev <= from_actual.
AC6 — granularidad de permisos
REPORTING_FINANCIALconcedido solo aadmin(editor/pos_manager/pos_cashier → 403).requireReportingPermissionlanza AppError(403) para roles sin el permiso.
AC7 — tests unitarios (sin DB)
parseReportingFilters: defaults, repeatable uuid arrays, from>to rechazado.comparisonRange: 3 modos.- Matriz de permisos role→perms.
- Tests: ≥8 unit + ≥6 route.
tsc --noEmit0 errores;npm testsin regresiones;lint:boundariessin violaciones nuevas.
lint:boundaries(scripts/check-module-boundaries.mjs) — reporting NO aparece todavía en la lista de módulos existentes; confirma que reporting importa soloshared/*/zod.