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
Add the rongta PrinterDevice driver (ESC/POS over raw TCP 9100) and the
device-agnostic pieces around it:
- Roles + failover: each printer declares a role (entry-dispenser/booth-
receipt) and failoverRank; printer-routing.ts picks the best healthy printer
and falls back outside->booth for entry tickets (never the reverse).
- Live status: MonitorableDevice.readStatus()/PrinterStatus capability. The
Rongta driver scrapes the device's own /prn_stat.htm (Cover/Cutter/Paper
End/Near End/Off-Line) rather than hand-decoding DLE EOT, whose reply bytes
on this clone don't match the canonical ESC/POS bit layout (verified on
hardware) -- avoids a false-healthy. Maps to ready/degraded/offline, fail
safe on an unreachable or unexpected page.
- Server PrinterMonitor polls enabled printers (PRINTER_POLL_MS, default 5s),
caches latest, emits "printer-status" on change. Exposed via
GET /api/printers/status and an SSE stream for the booth UI.
Verified against 10.0.10.6: ready when healthy, offline when unreachable
(no throw), bus emits on change and suppresses unchanged reads.
Wiki: new rongta-printer entity, printer-roles-failover and
printer-status-monitoring concepts; BOM/index/log updated.