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:
+19
-2
@@ -305,8 +305,25 @@ manifest (Car Wash → `carwash`; a future Bar → `bar`). Rules:
|
||||
touch the booth by construction; the header button, the hub's start buttons and the
|
||||
drawer switch never offer a till the server would refuse. (A first cut that borrowed
|
||||
`session:read` as "works the booth till" lived for a few hours and is gone.)
|
||||
- Not done: the per-shift *activity log* is still a time window over the whole chain (money
|
||||
figures are per till, the event list is not); bay slips print on the booth printer.
|
||||
- **The activity log is per till too (2026-09-06).** `tillOfEvent(type, payload)` in
|
||||
`@parking/shared` extends the money rule to every event: a money event names its till, any
|
||||
other event belongs to the till of the module that owns its type (a `carwash_order` is
|
||||
wash-desk activity though no money moved), everything else — entries, exits, barrier
|
||||
commands, pre-till events — is the booth's. `/api/events?till=` applies the same rule in
|
||||
SQL (so the page limit applies after the filter); the hub's shift log, the Drawer "today"
|
||||
panel and the booth feed (history and live pushes) pass their till. The events route also
|
||||
admits a role without `event:read` that holds a module's feed permission, and then returns
|
||||
only that module's event types — the live-socket rule, so a wash operator's hub shows the
|
||||
wash shift's log.
|
||||
- **The booth Z-report breaks module money out (2026-09-06).** `chargesByModuleMinor`
|
||||
(`{ carwash: <minor> }`, only when any was taken) sums the `chargeLines` on the till's
|
||||
payments by owning module; the ticket bucket EXCLUDES it, so `Bileta` is parking money only
|
||||
and ticket + subscriptions + Σcharges = cash + card. Printed as `Lavazh (në biletë): X` on
|
||||
the booth slip; the wash till's own slip prints its takings under `Lavazh:` (it sells no
|
||||
tickets or subscriptions). Signed on `shift_z_report`; older reports read back as `{}`.
|
||||
- **The wash till prints on its own printer (2026-09-06).** Printer role `wash-desk`; the
|
||||
wash till's Z-report and vouchers go there, falling back to the booth printer — see
|
||||
[[printer-roles-failover]].
|
||||
|
||||
## Where the fraud control actually lives
|
||||
|
||||
|
||||
Reference in New Issue
Block a user