diff --git a/docs/2026-08-15-thirty-day-reconciliation.html b/docs/2026-08-15-thirty-day-reconciliation.html index 952efcd7..65cf31e6 100644 --- a/docs/2026-08-15-thirty-day-reconciliation.html +++ b/docs/2026-08-15-thirty-day-reconciliation.html @@ -120,7 +120,7 @@
The importer deliberately understands both the old and new record names, so the change can - be deployed before the renaming finishes. That tolerance is a bridge, not a destination — - while any record still carries an unscoped name, two clients can still land on it, and the - guarantee rests on a convention rather than on the data.
-Measuring the whole database rather than the part that was migrated gives an honest - picture, and it is not a flattering one.
+The importer understands both the old and new record names, so the change can be deployed + before the renaming finishes. That tolerance is a bridge, not a destination — while any + record still carries an unscoped name, two clients can land on it and the guarantee rests on + a convention rather than on the data. So the renaming was run to completion and measured.
| Record type | Client-scoped | Still unscoped | No owner to scope by |
|---|---|---|---|
| Card payments | 17,046,418 | 0 | 0 |
| Refunds | 51,986 | 0 | 0 |
| Payouts | 144,652 | 0 | 36 |
| Cash-drawer shifts | 69,291 | 0 | 0 |
| Card payments | 259,763 (1.6%) | 14,241,890 | 2,122,161 |
Refunds, payouts and shifts are done. Card payments are not — the migration - described above covered the ten clients sharing a location today, within the reporting window, - which is 1.6% of them. And sampling 2% of the orders belonging to every client that has - ever contended found 12,954 payments still owned by two orders, which - extrapolates to roughly 650,000 across that population.
-So the correct reading of the balance figures earlier in this report is: they are what the - calculation fixes are worth, measured on data where the sharing had been resolved for the - clients and period in question. They are not a claim that the whole database is clean.
+Every record in the database now carries its owner's name. The 36 payouts are ones with no + client or location recorded anywhere, so there is nothing to name them after.
+Renaming had to be driven from orders, because a payment's rightful owner is whichever + order refers to it — so completing it meant walking all 19,040,296 orders, not + just the clients that look shared today. Nine client pairs contended in the past without + sharing a location now, and a migration scoped to the current configuration would have missed + every one of them.
Renaming has to be driven from orders, because a payment's rightful owner is whichever order - refers to it — so completing it means walking all 19,040,296 orders, not just the clients that - look shared today. Nine client pairs contended in the past without sharing a location now, and - a migration scoped to the current configuration misses every one of them.
-On the test machine this ran at roughly 15,000 orders an hour once the database no longer - fitted in memory, which puts a full pass in days rather than hours. That is a hardware - characteristic of a swapping 29 GB restore, not a property of the work: the same code - completed 267,012 orders in 100 seconds when the cache was warm. It belongs in a maintenance - window on properly sized hardware, and it is resumable and safe to re-run — a second pass over - already-renamed records does nothing at all.
+| Shared payments after the migration | Count | Meaning |
|---|---|---|
| Owned by two different clients | 0 | the problem this work exists to solve — gone |
| Owned by two orders of the same client | 104 | left shared deliberately, see below |
| sampled from | 250,000 orders | spread across the whole database |
Why the 104 are left alone. They are cases where Square split one tender + across two of a single client's own orders. Copying the payment for each order would be wrong + twice over: both orders compute the same name, so there is no second name a copy could take — + and a copy would double that client's takings for the day. One payment covering both orders is + the truthful record.
+The consequence is that the deletion cascade can still reach these — removing one of those
+ two orders would take the payment with it. That is why the guard on
+ remove-voided-orders is not optional housekeeping but a required companion to this
+ work: it should detach a shared payment rather than delete it, whoever the other order
+ belongs to.
A second complete pass walked all 19,040,296 orders in 7.8 minutes and changed + nothing — no renames, no copies. A record that already carries the right name is left + untouched, so the migration can be stopped, resumed, or repeated without consequence. Useful, + since the first full pass took hours on a machine where the 29 GB database no longer fitted in + memory; on warm cache the same code did 267,012 orders in 100 seconds.
The finish line is measurable, not a judgement call.
- unscoped-report counts, for every record type, how many names are client-scoped,
- how many are still unscoped, and how many have no owner. Two things follow from it:
What follows from the gate reading zero. unscoped-report counts
+ these figures on demand. Now that unscoped is zero across the board, the importer's
+ understanding of the old name form can be removed — at which point two clients sharing a
+ location becomes structurally incapable of producing a shared record, rather than prevented by
+ a convention that a future import could quietly break. That removal is the one remaining step
+ of this piece of work.