Flow
How the store check spread
1Sales matching
A sale only pairs with a shelf fact from its own store.
2Inventory done check
A fact from another store no longer marks a product as done.
3Evidence picker
Proof is taken from the right store, and rows that disagree with their run are dropped.
4Handoff to the writer
Every piece of the picked evidence is passed along, and a missing piece is refused.
5Duplicate check
Sales coverage is keyed on product and store, not on one copy of a shelf fact.
Around two months of sales for several more stores went into the ordering system, every product was one I'd already approved, and the step that turns sales into facts found zero work. That was the right answer, but only because I'd added a guard just before the run.
What has to exist before an order
My system wants two facts for each product at each store before it will suggest an order: what sold there and what's on the shelf there. Raw records come in first and are kept as evidence, then they're promoted into facts one at a time, and each fact records which store it was accepted for. Until now, all my inventory facts were for one store, and the new sales were from the others.
Matching on product alone
Sales were matched to inventory by product. That works with one store, but with more, a sale at one store can latch onto another store's shelf count, and the result looks valid in every field, so nothing later on can tell it's wrong.
So the match now checks the store too.
The match now skips any record from a different store and counts the skip.
If a store tag is missing or broken, that counts as a mismatch, and a mismatch is skipped and counted, never pointed at some other record instead. My test makes everything right except the store and checks that nothing gets written.
The live run over the new stores found hundreds of mismatches, zero matches and no writes. Without the count, that zero would have looked like no sales at all. With it, the zero said what was missing: inventory facts for those stores.
Inventory repair checked product only, too
The inventory repair step had its own idea of "done," and it also looked only at product. A fact from my first store made the product look done everywhere, so the repair for a new store would never run. It now uses the same store check.
The last step caught a bad handoff
My first repair for a new store found work, and then the step that writes facts refused it, because the evidence it got was still from the first store. The picker had looked it up the old way, through a mapping that only knew that store.
Now the picker finds evidence for the right store itself and passes it along in full. If a row names a different store than the run it came from, the row is dropped. If a piece of the handoff is missing, it's refused. An early version still borrowed one source field from the old mapping, which would have filed the fact under the wrong source. That's passed along now too.
A jump that wasn't real
After inventory repair for one new store, I reran sales and the ready count jumped, but the order math in the next step found the same ready pairs as before. The new sales had attached to newer inventory facts for pairs that already had sales. The duplicate check looked at the exact inventory fact, so a new version looked like a new gap. Now it looks at product and store, and I threw out the jump.
Three live observations, and the gaps I know about
All of this rests on one live run, one blocked repair and one caught jump. The tests run against a fake database. I know of a few gaps:
- Once some stores are fixed, the mismatch count will mix stores still waiting with rows that will never match.
- Dropped rows that disagree with their run aren't counted on their own.
- A store whose tag changes would stop matching its own past.
The other stores still need their inventory facts. If I built this again, I'd put the store in every key on the first day, before there was a second store to get wrong.