feat(tills): per-till activity log, wash bucket on the booth Z-report, wash-desk printer role
Closes the three known follow-ups of the Tills decision (venue-modules.md): - Activity log per till: `tillOfEvent(type, payload)` in @parking/shared (money events by payload till, other events by their owning module's till, everything else booth), applied by `/api/events?till=` in SQL and passed by the hub log, the Drawer "today" panel and the booth feed (history + live pushes). The events route admits a role that holds a module feed permission without event:read and returns only that module's event types — the live-socket rule. - Booth Z-report: `chargesByModuleMinor` sums the chargeLines on the till's payments by module; the ticket bucket excludes them (Bileta = parking only); printed "Lavazh (në biletë)" only when any was taken. The wash till's slip prints "Lavazh:". - Printer role `wash-desk`: the wash till's Z-report and vouchers print there, falling back to the booth printer; nothing falls back to the desk. `printerRoleOf()` is the one reading of the role field (the entry/booth loaders treated any non-booth role as an entry dispenser). Footer label "at wash desk". Also: `GET /api/carwash/settings` opens to carwash:read OR site:read (new requireAnyPermission) — the Wash operator job could not load the desk's category and service pickers. Tests for all four; wiki (shift, printer-roles-failover, venue-modules, log) updated. Claude-Session: https://claude.ai/code/session_01FWncR69HgGPuei1dLrW3cU
This commit is contained in:
+21
@@ -3049,3 +3049,24 @@ design error: the discount ENGINE (validation program rows + `applyValidation()`
|
||||
`validation` module is only the merchant's scan screen. Fixed: `dependsOn: ["parking"]`; the
|
||||
program routes are plain site:read/site:update; the merchant routes (mine/lookup/apply/void)
|
||||
stay module-gated. Tests updated. Recorded on [[venue-modules]] (v1 answers item 4 + As-built).
|
||||
|
||||
## [2026-09-06] ingest | Tills follow-ups closed: per-till activity log, wash bucket on the Z, wash-desk printer
|
||||
The three "known follow-ups" of the Tills decision are built. (1) `tillOfEvent(type, payload)`
|
||||
in `@parking/shared` — money events by payload `till`, other events by their owning module's
|
||||
till, everything else booth — is applied by `/api/events?till=` in SQL and passed by the hub
|
||||
log, the Drawer "today" panel and the booth feed; the events route now admits module-feed
|
||||
roles (a wash operator's `carwash:read`) and returns only their module's types, the same rule
|
||||
the live socket uses. (2) `chargesByModuleMinor` on the shift report/summary/signed payload:
|
||||
module charges on the till's payments by module; the ticket bucket excludes them; printed
|
||||
`Lavazh (në biletë)` on the booth slip; the wash till's slip prints `Lavazh:` for its own
|
||||
takings. (3) Printer role `wash-desk`: the wash till's Z-report and vouchers print there with
|
||||
failover to the booth printer; `printerRoleOf()` is the one reading of the role field so a
|
||||
desk printer is never mistaken for an entry dispenser; footer label "at wash desk". Updated
|
||||
[[shift]] §Tills, [[printer-roles-failover]], [[venue-modules]].
|
||||
|
||||
## [2026-09-06] ingest | Wash operator job could not load the desk's price list
|
||||
User built a role from the "Wash operator" chip (carwash:read/create/update/cash) and the desk's
|
||||
category/service pickers stayed empty. Cause: `GET /api/carwash/settings` was guarded by
|
||||
`site:read` only — the price list is Setup's data AND the desk's working data. Fixed with a
|
||||
new `requireAnyPermission(...)` guard (auth.ts): the read opens to `carwash:read` OR
|
||||
`site:read`; the write stays `site:update`. Regression test in carwash.test.ts.
|
||||
|
||||
Reference in New Issue
Block a user