Files
mercadodevida/work/artifacts/F-143/implementer.md
2026-08-22 11:43:42 +02:00

32 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# F-143 — Implementer evidence
## What
Establishes the shared reporting filter contract + RBAC foundation (`reporting` module, backend-only, no DB reads, no migration). New routes `GET /reporting/filters/schema` (REPORTING_VIEW) and `GET /reporting/filters/validate` (REPORTING_SALES); zod `reportingFiltersSchema` (`[from,to)` semantics), `comparisonRange` helper, and a role→permission map (`REPORTING_ROLE_PERMISSIONS`) + `requireReportingPermission`. Wired in `build-app.ts` inside `if (deps.pool)` with `combinedAuth`.
## Design recap (architect-approved — see architect.md)
- `reporting/` layered api→application→domain (mirrors pricing): pure types `domain/filters.ts` (const arrays `REPORTING_COMPARISON/CHANNELS/GROUP_BY` derive their union types DRY); zod schema + parser + `comparisonRange` + `REPORTING_FILTER_META` in `application/filters.ts`; `registerReportingRoutes` in `api/reporting.routes.ts`; public surface in `index.ts`.
- From/to are `z.string().refine(!isNaN(Date.parse))` (zod-v4-safe; `.datetime()` API moved in zod v4). Range semantics `[from,to)` via `refine(from < to)` → 400 on inversion. Repeatable UUID fields use `z.preprocess` (single string ↔ array) because Fastify querystring yields string vs array.
- RBAC: no permission table exists → role→permission map + `requireReportingPermission(user, perm)` (future table migration keeps call-site signature). FINANCIAL/EXPORT admin-only; editor/pos_* least-privilege.
- `dataAvailability` is metadata only (F-142 §4 baseline); never converts unavailable→0; no report data computed (F-144+).
- Routes have NO 200 response schema (broad passthrough, matching security.routes.ts precedent) so the dynamic DTO isn't stripped by fast-json-stringify; error responses use the shared `errorSchema`.
## Files created
- `project/src/modules/reporting/domain/filters.ts` — const arrays + pure types (`ReportingFilters`, `ReportingFilterMeta`, `DateRange`, `ComparisonRange`, `DataAvailability`, etc.).
- `project/src/modules/reporting/domain/permissions.ts``ReportingPermission`, `REPORTING_ROLE_PERMISSIONS: Record<Role, ReportingPermission[]>`, `requireReportingPermission`, `userReportingPermissions`.
- `project/src/modules/reporting/application/filters.ts``reportingFiltersSchema`, `parseReportingFilters`, `comparisonRange`, `REPORTING_FILTER_META`, `REPORTING_PAGE_SIZE_MAX`.
- `project/src/modules/reporting/api/reporting.routes.ts``registerReportingRoutes` + `ReportingRoutesDeps { authenticate }`.
- `project/src/modules/reporting/index.ts` — public re-exports.
- `project/src/modules/reporting/tests/filters.test.ts`, `tests/permissions.test.ts`, `api/reporting.routes.test.ts`.
- EDIT `project/src/app/build-app.ts``import { registerReportingRoutes } from '../modules/reporting/index.js'` + register block inside `if (deps.pool)` using `combinedAuth`.
## Tests
- NEW `reporting/tests/filters.test.ts` (9): defaults, repeatable uuid (single+array), from>=to→throw, invalid datetime, pageSize ceiling, invalid uuid→throw, comparisonRange (none/previous_equal/previous_calendar).
- NEW `reporting/tests/permissions.test.ts` (6): admin all-grants, pos_cashier least-privilege, customer none, requireReportingPermission 403 for denied, FINANCIAL admin-only (AC6), matrix covers every role.
- NEW `reporting/api/reporting.routes.test.ts` (7): schema route admin 200 + contract; customer 403 (×2); validate 200 + comparison invariants; defaults; inverted→400; missing→400; customer 403. Mirrors `security.routes.test.ts` (minimal Fastify + mock authenticate, no DB) and installs the build-app errorHandler/serializer so AppError(400/403) surface as real status codes.
## Verification
- `npx tsc --noEmit`**0 errors** (strict, noUncheckedIndexedAccess).
- `npx vitest run` (full suite) → **229 passed | 57 skipped** (DB itests skipped w/o `TEST_DATABASE_URL`); reporting contributes +22 (15 unit + 7 route); **0 regressions** vs F-138 baseline (209 passed).
- `node project/scripts/check-module-boundaries.mjs project/src`**0 NEW violations** for `reporting/` (imports only `shared/*` + `zod`). The sole remaining violation (`security/routes.ts → log-broadcaster`, an R1 deep-import) is pre-existing (introduced by F-154), untouched by F-143 — confirmed out of scope.
- `./scripts/verify.sh` → green (F-143 `in_progress` is runtime-consistent; no `pending`/`done` mismatch).