feat(reports): admin Reports dashboard — ledger-first charts
Adds an admin Reports screen (/setup/reports, gated report:read) — an on-demand dashboard over the signed event log. Server (ledger-first): GET /api/reports/summary?from&to&bucket aggregates in one call — entry/exit counts + all money summed straight from ledger_events (same source the shift Z-report reconciles, so totals tie out to the drawer); revenue split into ticket / subscription-sale / out-of-window mirrors the Z-report. Duration stats come from the sessions cache (flagged). All bucketing is in the SITE timezone (siteTz). A .csv export of the per-bucket series. reports.ts + routes/reports.ts. Web: Reports.tsx — date-range presets (today/7d/30d/90d), hour/day/month grain, KPI cards, entry/exit line, revenue bar + cash/card split, revenue-mix pie, peak-hours histogram, numeric breakdown, subscription stats. Charts via Recharts (MIT), lazy-loaded into its own chunk (~111KB gz) so the booth bundle is untouched. New Setup tab + nav + i18n (sq + en parity). asc() exported from @parking/db; formatMinutes helper. Tests: reports.test.ts (10) pin the sums, tz bucketing, money split, duration stats, subscription counts. server 90/90; build+lint 14/14. Wiki: reporting-analytics.md "Built v1" section + log entry. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
+14
@@ -1340,3 +1340,17 @@ deploy leaves it unset. Added a "Deploy-time server configuration (runbook)" sec
|
||||
[[disk-os-hardening]] documenting COOKIE_SECURE=0 (+ JWT_SECRET / EVENT_SIGNING_KEY) and corrected
|
||||
the stale "Secure when NODE_ENV=production" line on [[local-jwt-auth]]. auth.test.ts (5) pins the
|
||||
matrix; server 80/80.
|
||||
|
||||
## [2026-06-22] feat | Admin Reports dashboard v1 (ledger-first charts) + camera "Test ANPR"
|
||||
Built the admin Reports screen (`/setup/reports`, gated `report:read`): one server call
|
||||
(`GET /api/reports/summary?from&to&bucket`, + `.csv` export) aggregates entry/exit counts and all
|
||||
money straight from the signed `ledger_events` (LEDGER-FIRST decision) — the same source the
|
||||
`shift_z_report` reconciles, so totals tie out to the drawer; the 3-way revenue split (ticket /
|
||||
subscription sale / out-of-window) mirrors the Z-report. Duration/occupancy stats come from the
|
||||
`sessions` cache (flagged). All bucketing is in the SITE timezone (`siteTz()`). Views: KPI cards,
|
||||
entry/exit line, revenue bar + cash/card split, revenue-mix pie, peak-hours histogram, numeric
|
||||
breakdown, subscription stats. Charts via Recharts (MIT), lazy-loaded into its own chunk (111KB gz)
|
||||
so the booth bundle is untouched. reports.test.ts (10) pins the sums/tz/split/duration/subs; server
|
||||
90/90, build+lint 14/14. Also (earlier same session): a camera "Test ANPR" probe in first-run setup
|
||||
(`POST /api/setup/test-anpr`) — snapshot→vision analyze, fail-soft, shown only when a camera's ANPR
|
||||
opt-in is checked. See [[reporting-analytics]], [[opencv-anpr-service]].
|
||||
|
||||
Reference in New Issue
Block a user