c3d95cba6a4cd752460dc9ba84f352e289ea84f7
The migration had been run over a chosen subset — the ten clients that share a Square location today, within a date window. Measuring the whole database showed how partial that was: charges 259,763 scoped · 14,241,890 legacy · 2,122,161 with no owner refunds, payouts, shifts: complete So 1.6% of charges carried a client-scoped key. The importer's tolerance of both key schemes was not easing a transition, it was holding the system together. unscoped-report counts, per entity type, how many keys are scoped, how many are still legacy, and how many have no owner to scope by. That is the gate: while legacy is above zero the database is in a mixed state and a stray unscoped record can still be adopted by whichever client imports it first. At zero, the fallback lookup in square.core3/existing-id can be removed and the guarantee becomes structural rather than conventional. migrate-all! runs it over every order rather than a subset. Splitting has to be driven from orders because a payment's rightful owner is whichever order refers to it — and nine client pairs contended in the past without sharing a location today, so a migration scoped to the current configuration misses all of them. Two changes were needed to run at that scale. The split no longer remembers every charge it has seen; whether a charge is claimed is read from the charge, which needs a map of the whole table otherwise. And claiming a charge now records the claiming client on it, which is how a later order recovers the Square id from an already-scoped key — the regression test caught the omission immediately. Re-running is now a true no-op rather than a repeated rename. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
Languages
Clojure
91%
CSS
4.2%
Sass
2.3%
HTML
1.2%
HCL
0.4%
Other
0.7%