feat(drawer): drawer hub — balance now, this-shift figure, daily activity, shift history; busy spinners
Build desktop / desktop (push) Successful in 4m12s
Build & push images / images (push) Successful in 2m53s
CI / check (push) Successful in 41s

/drawer was record + review only: no current balance, no sight of the open
shift's incomings, no daily activity, no shift history. Rebuilt as a hub:

- Drawer now: the till's running balance (new GET /api/drawer/balance,
  shift:read — exposes the service's existing drawerBalance(); the drawer
  is one site-wide till, same exposure the X-report already had) with the
  open shift's X-report breakdown alongside (float + takings + vouchers =
  expected = balance) and a "This shift: ±X" figure (expected − opening
  float — the shift's own contribution vs what it inherited).
- Today's cash activity: every cash payment + voucher since local
  midnight from the signed chain, live, with day totals (card never
  enters the till).
- Record + movements/review: the 2026-07-01 flow, unchanged.
- Closed shifts: drawer-focused history via the scope-aware /api/shifts
  (float → takings ± vouchers → expected per shift).

Also: every shift open/close button (header, /shifts, pay modal, end-
shift confirm) now shows an animated spinner + dims while busy — the old
label-swap-only feedback read as a dead click when a shift open ran slow.
The slowness itself (drawer/shift reads fold the WHOLE chain, O(chain))
is recorded as an open item in wiki/concepts/shift.md with the fix
sketch: fold from the last z-report's signed expectedDrawerMinor forward.

No new ledger surface — one read-only endpoint; RBAC test added.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-07-05 15:56:30 +02:00
parent d5ff2097bd
commit c5ed3f1308
13 changed files with 489 additions and 72 deletions
+22
View File
@@ -2320,3 +2320,25 @@ Follow-up to the lab redesign (same session): the sidebar now also lists the PUB
the row. Publishing a lab draft carries the draft's name onto the version; the composer page grew
an optional version-name field (never prefilled — republishing a tweak under last season's name
would mislabel history). Details on [[tariff]] (Tariff Lab section).
## [2026-07-05] update | Drawer hub: balance now, live daily activity, shift history
Operator: "/drawer is too simple — no daily activity, current shift incomings not reflected, closed
shifts history missing, drawer current state not shown." Rebuilt DrawerManager as a five-panel hub
(details on [[shift]] §Drawer hub): Drawer-now panel (new GET /api/drawer/balance exposing the
service's existing drawerBalance(); open-shift X-report breakdown alongside so float + takings +
vouchers = expected = balance is explicit), today's cash feed (existing /api/events since local
midnight, cash-only, live), the unchanged record/review flow, and a drawer-focused closed-shifts
list (existing scope-aware /api/shifts). No new ledger surface — one read-only endpoint, everything
else composes what the chain already records. RBAC test added (shift:read 200 / other 403 / anon 401).
## [2026-07-05] update | Drawer "this shift" figure + spinners on shift buttons; O(chain) flagged
Follow-ups to the drawer hub (same session): the Drawer-now panel gained "This shift: ±X"
(expected − opening float — the shift's own contribution vs what it inherited), and every shift
open/close button got an animated spinner + dim while busy (ui/Spinner.tsx) — the old label-swap
read as a dead click on a slow open. Root cause of the slowness recorded as an open item on
[[shift]]: drawer/shift reads fold the WHOLE chain (O(chain) — grows forever); fix when it bites =
fold from the last z-report's signed expectedDrawerMinor forward. Also from this session: dev-DB
migrations are MANUAL (pnpm db:migrate in packages/db) — a 500 "no such column" after pulling a
migration means it was skipped; booth containers migrate on boot and are immune.