feat: re-model drawer cash as directional vouchers (Mandat Arkëtimi / Pagese)

Replace the single signed-± cash_movement with two distinct financial
documents — the direction is the event TYPE, not the sign of an amount:

  cash_in  = Mandat Arkëtimi (receipt / pay-IN,  +)  voucher AR-NNNN
  cash_out = Mandat Pagese  (disbursement / pay-OUT, −)  voucher PA-NNNN

Each carries a positive magnitude, voucher number, reason, the operator who
raised it and the admin who authorized it, and prints an Albanian slip.

Authorization changes from admin-only to operator-RAISED / admin-AUTHORIZED:
any shift:create holder raises the voucher, but POST /api/cash-voucher only
commits when authorizedBy is a real admin (shift:cash) re-entering their
password (verified server-side). Keeps the float control while letting the
operator do the booth paperwork.

Legacy cash_movement events are kept — they still verify and still fold into
the drawer (signed-±); the append-only chain is never rewritten. The drawer
fold and the Z-report window now sum all three types.

Verified against a copy of the live DB with the real signing modules:
cash_in 3000 + cash_out 5000 → drawer −2000, hash-chain verifies OK.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-06-20 16:18:26 +02:00
parent a20400c2c5
commit 2835f78635
13 changed files with 335 additions and 78 deletions
+18
View File
@@ -1100,3 +1100,21 @@ the signed ledger is untouched. Added `plate?` to the shared `LedgerEvent` + `Ac
`SessionLookup`; a small amber badge in the UI. Caveat: a `vehicle_entry` is signed + pushed
over WS BEFORE the async ANPR read lands, so a fresh feed row may show no plate until reload;
always present on active sessions. Build + lint 12/12.
## [2026-06-20] feat | Drawer cash re-modelled as directional vouchers (Mandat Arkëtimi / Pagese)
Replaced the single signed-± `cash_movement` (one event, +load/−removal in the sign of an
amount) with two distinct financial documents — the direction is now the event TYPE:
`cash_in` = **Mandat Arkëtimi** (receipt / pay-IN, +) and `cash_out` = **Mandat Pagese**
(disbursement / pay-OUT, −). Each carries a positive magnitude, a voucher number (`AR-NNNN`
/ `PA-NNNN`), reason, the operator who raised it and the admin who authorized it, and prints
an Albanian slip. **Authorization changed**: was admin-only; now **operator-RAISED,
admin-AUTHORIZED** — any `shift:create` holder raises the voucher but `POST /api/cash-voucher`
only commits if `authorizedBy` is a real admin (`shift:cash`) re-entering their password.
Legacy `cash_movement` events are KEPT (still verify, still fold into the drawer signed-±) —
the append-only chain is never rewritten. Drawer fold + Z-report window updated to sum all
three types. Verified against a COPY of the live DB with the real signing modules: cash_in
3000 + cash_out 5000 → drawer −2000, hash-chain still verifies OK. Build + lint 12/12.
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).