The kitchen queue watches, and prints nothing - #787
Merged
sridharkalaibala merged 1 commit intoSep 15, 2026
Merged
Conversation
Step 1 of Stage 2 in the print roadmap, and the step usually skipped: "Write print_jobs rows and drain nothing. Compare, for a week, what the queue says should print against what actually printed. Any disagreement is a bug found before it can cost anything." WHY IT IS WORTH A WHOLE CHANGE TO PRINT NOTHING Ninety shops feed their kitchens through multiKitchenPrint. The failure mode of a bad cutover is not an error message - it is a dish nobody made, or two dishes where one was ordered. Owner: "printing dont bring me new issues. keep changes safely." So the queue records what it believes should print, the old path keeps printing exactly as it does, and the two are compared. Nobody can currently say whether duplicates happen four times a week or forty; this can answer that without touching a printer. HOW IT CANNOT PRINT Rows are written with status `shadow`, which nothing claims - claimPrintJobs matches `queued` only, and the till asks for bills. A test drives the real claim and fails if that filter ever widens. They carry no payload either, so there is nothing to print even by accident. WHAT IT RECORDS Tickets named the way the TILL names them, both schemes - a sale with no print_jobs array is named by the fallback rather than skipped, because skipping it would make the shadow blind to a whole class of ticket and then report perfect agreement, which is the worst outcome a measurement can have. One row per ticket, enforced by a partial unique index rather than by a read-then-write: two tills polling at once would both read "absent" and both insert. An amended order is a second row, because it is a second ticket. CLOSING A ROW, AND THE BUILD THAT DOES NOT KNOW ABOUT IT The till now sends printedKeys - the names of what actually reached paper, only when paper actually came out. A failed ticket reported as printed would close a row that should be showing up as a disagreement. But ticket names are new on the wire, and closing only by name would leave every row from every older till open for ever - the first report would say the whole estate is failing, which is worthless exactly when it is meant to establish a baseline. So an older till still closes its rows by sale. That is less precise and understates disagreement rather than inventing it, which is the safe direction for a number nobody has yet. It is a bystander throughout: every failure is swallowed inside, and a test drives it against a database that throws on every call to prove a broken shadow cannot fail a service. API 10715 pass, desktop 2541 pass.
Contributor
|
Merged to Try it at https://develop.posnic.io, or run it yourself: git fetch origin develop && git checkout develop
npm install && npm --prefix api install
npm run dev # then http://localhost:3000When you have tested it, say what you did and what happened, and set Reporting that something is broken is as useful as fixing it. It is |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 1 of Stage 2 in the print roadmap, and the step usually skipped:
Why it's worth a whole change to print nothing
Ninety shops feed their kitchens through
multiKitchenPrint. The failure mode ofa bad cutover is not an error message — it is a dish nobody made, or two dishes
where one was ordered.
So the queue records what it believes should print, the old path keeps printing
exactly as it does, and the two are compared. Nobody can currently say whether
duplicates happen four times a week or forty. This can answer that without
touching a printer.
How it cannot print
Rows are written with status
shadow, which nothing claims —claimPrintJobsmatches
queuedonly, and the till asks for bills. A test drives the realclaim and fails if that filter ever widens:
They carry no payload either, so there is nothing to print even by accident.
What it records
Tickets named the way the till names them — both schemes. A sale with no
print_jobsarray is named by the fallback rather than skipped, because skippingit would make the shadow blind to a whole class of ticket and then report
perfect agreement, which is the worst outcome a measurement can have.
One row per ticket, enforced by a partial unique index rather than a
read-then-write: two tills polling at once would both read "absent" and both
insert. An amended order is a second row, because it is a second ticket.
Closing a row, and the build that doesn't know about it
The till now sends
printedKeys— the names of what actually reached paper, andonly when paper actually came out. A failed ticket reported as printed would
close a row that should be showing up as a disagreement.
But ticket names are new on the wire. Closing only by name would leave every row
from every older till open for ever, and the first report would say the whole
estate is failing — worthless exactly when it's meant to establish a baseline.
So an older till still closes its rows by sale. Less precise, and it
understates disagreement rather than inventing it, which is the safe direction
for a number nobody has yet.
It is a bystander
Every failure is swallowed inside, and a test drives all three functions against
a database that throws on every call:
A shadow that breaks a service is worse than no shadow at all.
Tests
17 new cases. API 10715 pass / 0 fail. Desktop 2622 pass / 0 fail.
What this makes possible
After a week of real data,
disagreements()answers two questions that havenever had an answer:
it printed
expect, which is the shape a duplicate has
That baseline is what Stage 2's cutover decision should rest on.