Skip to content

The kitchen reads "less spicy" - #744

Merged
sridharkalaibala merged 3 commits into
developfrom
fix/the-kitchen-reads-less-spicy
Sep 15, 2026
Merged

sridharkalaibala merged 3 commits into
developfrom
fix/the-kitchen-reads-less-spicy

Conversation

@sridharkalaibala

Copy link
Copy Markdown
Contributor

"when item print, item notes not printed. example 'less spicy' not printed in
the kot. its bad very bad"

Right, and worse than it looks. The note is the one line on a ticket the kitchen
cannot work out for itself — the dish, the table and the quantity a cook
could reconstruct; the note they cannot. A customer who asks for something, is
told yes, and does not get it blames the restaurant, and the restaurant never
finds out.

Where it was lost, and not where anybody would look

The note was stored correctly all along. _priceOnlineLine puts it on the
sale item as item_description, and both ticket builders print it — escpos-kot
renders ** less spicy ** under the dish when the field is there.

Reading the printing code finds nothing wrong, because nothing is.

But the kitchen ticket is not printed from sale.items. The poller builds
its print jobs out of changes[].items, the record of what changed, and that
list carried eight fields:

item_id  item_name  item_quantity  process  item_code  unit  price  total

No note. Four places build that list and all four dropped it: a new order,
an amended line, a cancelled line, and a line removed from the order.

The fourth was nearly missed

The removed-line branch reads from a snapshot of the existing items taken
earlier in the same function, and that snapshot did not carry the note
either
— so it needed fixing in two places rather than one.

It matters more than it sounds: a removal ticket says which dish to stop, and
a table with two of the same dish is told apart by the note. That is exactly the
case where getting it wrong cancels the wrong plate.

One ordering decision

On an amendment the request's note wins over the stored one, because the
request carries what the person has only now said and the stored copy is what
they said before. Reading the stored one first would quietly ignore a change of
mind.

Also in here, and it needs saying

The acknowledgement check from the print-ledger work. It was pushed after
#741 had already been merged, so it never reached main. Without it a failed
markKitchenPrinted still logs success, the server keeps offering the same
jobs, and a restart prints the whole day again — the ten-to-fifteen-ticket
storm.

I checked the packaged build before noticing: the ledger is in main, the
acknowledgement check is not.

Tests

7 new. The one that matters asserts every changesItems list carries the
note, not a specific one — the bug was one place being right and three silently
not, so a test naming one would have passed while the kitchen still got nothing.

Two notes for whoever writes the next test here: my first finder matched
item_quantity: qty and swept up ordinary sale-item constructions with it, and
my first search for the note mapping used an 8,000-character slice when the
mapping sits 450 lines into the function. Both are anchored properly now.

API suite: 10,625 passing.

Release: what is on the plate, and the menu that shows it
Owner: "whenver i start polling, i see all prints are going. i dont know
how 10 or 15 prints going".

The chain, end to end:

1. The server keeps offering a job until last_printed_change_index
   advances past it. That index is the durable guard.
2. It only advances when POST /sales/markKitchenPrinted succeeds.
3. That call's answer was never looked at. fetch does not throw on a 401
   or a 500 - it resolves with ok:false - so the very next line logged
   "Marked N order(s) as printed" whatever came back.
4. Within one run, the in-memory set hid it.
5. On a restart that set is empty, the server is still offering
   everything from today, and the whole day prints again. Ten or fifteen
   tickets, exactly as described.

So the ledger in the previous commit stops the reprint, and this stops
the backlog that fed it. The response is checked now, and a failure says
what happens next rather than only that it failed - "they will be offered
again; the print ledger is what stops them printing twice" is the part
somebody reading a log at nine in the evening actually needs.

THIS IS THE THIRD TIME IN THIS AREA that a return value which was the
only evidence of success was thrown away: the four winspool calls, the
result of silentPrint at its call site, and now this. Worth naming as a
pattern rather than three separate fixes.

The silentPrint one is still not fixed, on purpose: correcting it means
retrying failed prints, and retries are how duplicates happen. It wants
the queue and a decision.
Owner, holding a ticket: "when item print, item notes not printed.
example 'less spicy' not printed in the kot. its bad very bad".

He is right, and it is worse than it looks. The note is the one line on a
ticket the kitchen cannot work out for itself - the dish, the table and
the quantity a cook could reconstruct, the note they cannot. A customer
who asks for something, is told yes, and does not get it blames the
restaurant, and the restaurant never finds out it happened.

WHERE IT WAS LOST, and not where anybody would look first.

The note was stored correctly all along. _priceOnlineLine puts it on the
sale item as item_description, and both ticket builders print it -
escpos-kot renders ** less spicy ** under the dish when the field is
there. Reading the printing code finds nothing wrong, because nothing is.

But the kitchen ticket is not printed from sale.items. The poller builds
its print jobs out of changes[].items - the record of what changed - and
that list carried eight fields: id, name, quantity, process, code, unit,
price, total. No note. FOUR places build that list and all four dropped
it: a new order, an amended line, a cancelled line, and a line removed
from the order.

The fourth was nearly missed. It reads from a snapshot of the existing
items taken earlier in the same function, and that snapshot did not carry
the note either, so it needed fixing in two places rather than one. A
removal ticket says which dish to stop, and a table with two of the same
dish is told apart by the note - exactly the case where getting it wrong
cancels the wrong plate.

On an amendment the request's note wins over the stored one, because the
request carries what the person has only now said and the stored copy is
what they said before. Reading the stored one first would quietly ignore
a change of mind.

Also in here: the acknowledgement check from the print-ledger work, which
was pushed after #741 had already been merged and so never reached main.
Without it a failed markKitchenPrinted still logs success, the server
keeps offering the same jobs, and a restart prints the whole day again.
@sridharkalaibala
sridharkalaibala merged commit ca265be into develop Sep 15, 2026
9 checks passed
@github-actions github-actions Bot added the ready for QA Merged to develop and live on develop.posnic.io - anyone can test it label Sep 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Merged to develop. Anyone can test this - you do not need write access.

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:3000

When you have tested it, say what you did and what happened, and set
QA passed or QA failed. If you cannot set labels, just comment -
a maintainer will.

Reporting that something is broken is as useful as fixing it. It is
better found here than by a shopkeeper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for QA Merged to develop and live on develop.posnic.io - anyone can test it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant