feat: mid-shift X-report (read-only takings-so-far)
Let the operator see, on demand during an open shift, the opening float inherited, cash/card collected so far, pay-ins/pay-outs, and the current expected drawer balance — without closing. GET /api/shift/report (shift:read; 204 when no shift is open) returns the same drawer projection the Z-report computes. Factored that math into a shared ShiftService.#summariseWindow(open, asOf) used by BOTH the X-report (asOf=now, read-only) and close()'s Z-report (asOf=endedAt, signed), so the two can't drift. The X-report appends NOTHING — it's a snapshot, not an accountability mark; the Z-report at close remains the signed record. UI: a "Takings so far" button on the shift control reveals a cyan X-report panel; the header still shows the live drawer total for the at-a-glance figure. Verified against a copy of the live DB: X figures match drawerBalance(), the drawer identity holds, zero events appended, chain still verifies. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
+10
-6
@@ -204,11 +204,15 @@ reconciles the signed Z-report against the actual drawer and the bank/POS batch
|
||||
- **Shift ↔ session boundary:** a vehicle may enter under one shift and pay under another — the
|
||||
Z-report sums by **payment time** (when cash/card was taken), which is the operator who handled
|
||||
the money. Confirm that's the intended accountability (vs. by entry).
|
||||
- **Mid-shift report / X-report — REQUESTED 2026-06-20, not yet built.** The operator wants to see,
|
||||
on demand during the shift, the **opening float inherited**, **cash collected so far**, the
|
||||
pay-ins/pay-outs, and the **current expected drawer balance** — without closing. It's the same
|
||||
drawer projection the Z-report computes, just read-only and mid-shift. (The header already shows the
|
||||
live drawer *total*; this is the full breakdown.) Deferred behind the voucher re-model done the same
|
||||
day; build next if wanted.
|
||||
- **Mid-shift report / X-report — BUILT 2026-06-20.** On demand during the shift, the operator sees
|
||||
the **opening float inherited**, **cash/card collected so far**, the **pay-ins/pay-outs**, and the
|
||||
**current expected drawer balance** — without closing. `GET /api/shift/report` (`shift:read`, 204
|
||||
when no shift is open) returns the SAME drawer projection the Z-report computes, factored into a
|
||||
shared `ShiftService.#summariseWindow(open, asOf)` so X (asOf = now, read-only) and Z (asOf =
|
||||
endedAt, signed) can never drift. **It appends NOTHING** — it's not an accountability mark (the
|
||||
Z-report at close is the signed record). UI: a "Takings so far" button on the shift control opens a
|
||||
cyan X-report panel; the header still shows the live drawer *total* for the at-a-glance number.
|
||||
Verified against a copy of the live DB: matches `drawerBalance()`, drawer identity holds, 0 events
|
||||
appended, chain still verifies.
|
||||
- **Multiple lanes/booths** — whether a shift is per-operator, per-booth, or per-site
|
||||
(relates to [[open-questions]] #1 lane topology).
|
||||
|
||||
+13
@@ -1118,3 +1118,16 @@ three types. Verified against a COPY of the live DB with the real signing module
|
||||
Updated [[shift]] (Drawer balance section, math, worked example, open items). Prompted by the
|
||||
operator-balance question; the live mid-shift **X-report** breakdown is logged as REQUESTED,
|
||||
not yet built (see [[shift]] Open).
|
||||
|
||||
## [2026-06-20] feat | Mid-shift X-report (read-only takings-so-far)
|
||||
|
||||
The operator can now see, on demand during an open shift, the opening float inherited,
|
||||
cash/card collected so far, pay-ins/pay-outs, and the current expected drawer balance —
|
||||
without closing. `GET /api/shift/report` (shift:read; 204 when no shift open) returns the
|
||||
SAME projection the Z-report prints, factored into a shared `ShiftService.#summariseWindow
|
||||
(open, asOf)` so X (asOf=now, read-only) and Z (asOf=endedAt, signed) can't drift. Appends
|
||||
NOTHING — it's a snapshot, not an accountability mark (the Z at close is the signed record).
|
||||
UI: a "Takings so far" button on the shift control reveals a cyan X-report panel; the header
|
||||
keeps the live drawer total. Verified on a copy of the live DB: matches drawerBalance(),
|
||||
drawer identity holds (expected = opening + cash + added − removed), 0 events appended, chain
|
||||
verifies. Build + lint 12/12. Resolves the X-report item flagged the same day in [[shift]].
|
||||
|
||||
Reference in New Issue
Block a user