2026-04-22 on prod. Sixth cycle of R1 (NIX-OS-67 Phase 3 POS): replaces the bare
confirm() on the Close Shift button with a proper cash-count dialog per spec
§8.4. Cashier enters counted cash (optionally bank), dialog auto-computes the difference
against expected (beginning cash + sales). If non-zero, surfaces a
payment difference reason dropdown fed from a new admin CRUD at
/cafe/settings/payment-diff-reasons. All closure fields land on
cafe.sessions — ending_cash, ending_bank,
diff_amount, diff_reason_id, closed_at,
closed_by_*.
cafe.sessions row is state='closed' with
ending_cash=105, diff_amount non-zero, diff_reason_id
matches the picked reason, closed_at stamped. Zero 5xx. Full cleanup on exit
(closes any stray session, deactivates test cashier, deletes test reason, restores owner's
POS PIN).