Flow
Checks before any row changes
1Which path?
Old shape, new shape or none. A mix of both is refused.
2Right order version
The reply must name the current version. An old one is a conflict.
3Every request once
Missing, extra or doubled answers fail before anything is saved.
4Sane answers
A real product name, a positive price, and a case pack that divides the ordered units.
5Fingerprint match
Approval changes a row only if its fingerprint matches what the buyer saw. Any miss cancels the whole approval.
When a buyer approved one order in the ordering system, the code wrote to rows that other orders shared. That was the design. I changed it so each order version keeps its own copy of the supplier's answer.
One slot per kind of request
Some orders ask for a kind of product, not an exact one. The supplier answers with the real item, its case pack and its price, and a buyer says yes or no.
The answer used to live on one shared slot per kind of request. While one order had a proposal on that slot, a second order had to wait. Approval locked the whole supplier, wrote the answer onto the slot, and copied it onto shared catalog rows. So the slot was really a receipt for one decision, and the next approval overwrote it.
A row for each order version
Each version of an order now gets its own choice row for every generic request. The row starts empty, holds the supplier's answer once it arrives, and then ends approved, rejected or cancelled. The database won't let an empty row hold half an answer. Nothing on this path writes the shared slot, and a repo check fails if new code tries.
The supplier's reply must cover every request exactly once and name the order version it answers. A stale or partial reply is rejected before anything is saved. Each answer must be a real product, with a positive price and a case pack that divides the ordered units evenly.
Approving what the buyer saw
Every proposal gets a hash, which is a short fingerprint of its contents. The buyer's screen sends back the fingerprints it showed. The server only approves a row if its fingerprint still matches.
The approval updates a row only if it is still proposed and its fingerprint matches what the buyer saw.
If no row changes, the proposal moved, and the whole approval fails. The order version is claimed first, so two buyers clicking together get one winner. There's no supplier lock and no catalog write anymore.
Older orders and a decorated label
Older order versions still use the slot path. A version that mixes both shapes is refused. I also fixed the supplier's edit form, which for an approved choice was filled from a decorated label. I'd bet that label would have been saved as the product name.
Two orders on one slot
A real-database test puts two orders on the same slot with the same product. One approval lands, a repeat does nothing, the other order is untouched, and the shared rows match their old copies.
The real price is reuse: last week's answer no longer carries over, and I'm still deciding whether to offer it back as a hint.