2.8 KiB
2.8 KiB
F-143 — Technical spec
Module layout
src/modules/reporting/
domain/filters.ts — pure types (ReportingFilters, ComparisonMode, GroupBy, ComparisonRange, DataAvailability, ReportingFilterMeta)
domain/permissions.ts — ReportingPermission + REPORTING_ROLE_PERMISSIONS + requireReportingPermission (imports shared/auth + shared/errors)
application/filters.ts — reportingFiltersSchema (zod), parseReportingFilters, comparisonRange, REPORTING_FILTER_META (imports domain)
api/reporting.routes.ts — registerReportingRoutes(app, deps:{authenticate}) (imports application + domain + shared)
index.ts — public surface (re-exports only)
tests/filters.test.ts — unit: parser + comparisonRange
tests/permissions.test.ts— unit: role matrix + requireReportingPermission
api/reporting.routes.test.ts — HTTP: schema/validate + RBAC (mirror security.routes.test.ts)
Boundaries (R1/R2)
reportingimporta SOLOshared/*+zod→ ningún otro módulo. ✓ R1.src/app/build-app.tsimportaregisterReportingRoutes(+ tipos) desdemodules/reporting/index.js(R2). ✓.- Registrado dentro de
if (deps.pool)conauthenticate: combinedAuth(backplane backoffice), junto al resto de módulos backoffice.
Filter contract (F-142 §6)
- Rango
[from,to):frominclusivo,toexclusivo → evita doble conteo. from/to: ISO datetime with offset →z.string().datetime({ offset: true }).- Arrays repetibles de UUID aceptan single OR array vía
z.preprocess((v)=>Array.isArray(v)?v:v===undefined?undefined:[v], z.array(z.uuid()).optional()). comparedefaultnone;channeldefaultall;page(1..);pageSize(1..200, default 50).from > to→ refine → AppError(400) (mapeado porparseJson).
Comparison (comparisonRange)
none→null.previous_equal→ shift ventana atrás por la duración exacta ([start-duration, start)).previous_calendar→ shift atrás por los días calendario transcurridos, alineado a UTC (00:00) →[prevStart, prevStart+spanDays). Documented como aproximación calendar-aligned.
RBAC (role-based, F-142 §9)
- admin → todos los
REPORTING_*. - editor → VIEW+SALES+PRODUCTS+CUSTOMERS+INVENTORY+DISCOUNTS+REFUNDS+TAXES (sin FINANCIAL/EXPORT/ADMIN).
- pos_manager → VIEW+SALES+PAYMENTS+CASH.
- pos_cashier → VIEW+SALES.
- customer → [] (403).
requireReportingPermission(user, permission)lanza AppError(403). Futuro: tablabackoffice_permissions; la firma no cambia.
Data availability (F-142 §4 baseline, server-truth)
grossSales/discounts/tax/unitsSold/orders/customers = available; netSales/margin/paymentMethod/refunds/shipping = unavailable. Se expone via REPORTING_FILTER_META.dataAvailability (no cálculos aún — F-144+).