Flow
How my route builds one tag write
1Pick the target
The row if the request names one, otherwise the whole package. Never both.
2Name the scope
Worked out from the same field, not typed in.
3Check first
Store, package, product, row, stock and tag names all have to match.
4Write once
One write, using that store's own login.
5Read back
The row's tags have to match the request exactly.
6Test the whole body
Tests compare the full outgoing body, not just part of it.
Flow
What the tests check
All run against a fake platform, not the real one.
1Dry run
Two reads, no write.
2Real run
Exactly one write, with only the row and the tags.
3Store not allowed
Turned away before any call goes out.
4Every store
Each write uses that store's own login.
Tagging one item in a store with my route tagged every room that item's batch had been split into. Every receipt said so, and I read that as bookkeeping, not a warning.
The ordering system writes to the stores' sales platform through a gateway I run. The gateway checks the caller, picks the right login for the store, and logs each try before it sends anything. A pilot route lets a person point at one line of stock and say "tag that one". Tags matter. The same day I was fixing a sales report that reads tags to decide what's on sale, and some tags there count as a discount.
A batch is not a shelf
The platform tracks stock two ways. A package is the batch that came in. A row is the part of that batch sitting in one room. One batch can have many rows. The tag call takes either kind of ID, and it replaces the tags on its target.
So tagging by package hits every room and wipes the old tags on all of them. The two requests differ by one field. The person asking can't see how many rooms are involved.
The gateway always sent the package. I'd guess the habit came from a test route that tags a whole test batch on purpose. I haven't checked whether a wide live write ever went out. I only have the code and tests.
Point at the row, and say which one you pointed at
The request now takes an optional row ID. If it's there, the write names only that row. If not, it falls back to the batch so old callers still work. The receipt's scope is no longer typed in by hand.
The scope is worked out from whether a row ID was given, not typed in.
The dry run and the real run use the same code, so the preview shows the real scope before anything is sent.
What a tag request has to get past
The route only takes a few fields and rejects the rest, so nobody can slip in a price or a quantity. It's off unless a flag is on and the store is allowed. It needs a confirm header and a one-time request key. It uses that store's own login, never a shared one. A dry run checks that the batch, product, row, stock and tag names all match, then shows the plan. A real run checks again, writes once, and rereads until the tags match.
Adding more stores means adding their logins. The route still does one store and one item per request.
The tests run the route against a fake platform. A dry run reads twice and never writes. A real run writes once, with exactly the row and the tags. A store that isn't allowed gets turned away before any call. Another test checks every store uses its own login.
Where I'm still exposed
The tests ran against a fake, so they say nothing about what the real platform does with a row ID. The reread only checks the target row, not its neighbors. And the fallback is still there. If a screen forgets the row ID, writes go wide again and the tests still pass. I want the live route to require the row once my screens always send it.