feat(ops): atm-reconcile — check cassette ledgers against recorded history
The cassettes table is a running total, so it can be re-derived: an absolute truth point (a recount, or an empty) plus the refills and dispenses since. A derived count that disagrees with the stored one is evidence of something the ledger never saw. Reconciliation deliberately refuses to start from a refill. A refill is a delta, and applying deltas on top of a wrong number just carries the error forward — which is how sintra's 20-EUR bay ran 10 notes high for weeks while its 50-EUR bay, zeroed by an `empty` before refilling, reconciled exactly. A bay with no baseline is reported as unreconcilable rather than silently assumed good. Also surfaces the two things that make a count untrustworthy: the counts-uncertain flag, and any transaction still sitting in dispense_error / partial. The SQL uses scalar subqueries rather than joins on purpose — joining transaction_bills to cassettes fans out across bays, and a LEFT JOIN whose rows are all excluded by the baseline cutoff collapses to NULL and poisons the arithmetic downstream (the first draft read "expected: blank" for exactly that reason). Exits non-zero on any gap or missing baseline so it can be run as a check after a test session. Refs #122
This commit is contained in:
parent
695a8bf98d
commit
ee28275bf3
2 changed files with 173 additions and 0 deletions
|
|
@ -376,6 +376,7 @@ in
|
|||
# ATM operations
|
||||
sqlite
|
||||
(writeShellScriptBin "atm-transactions" (builtins.readFile ./atm-transactions.sh))
|
||||
(writeShellScriptBin "atm-reconcile" (builtins.readFile ./atm-reconcile.sh))
|
||||
];
|
||||
|
||||
# Enable SSH for remote administration
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue