Skip to content

The customer can choose the extras the shop already charges for - #833

Merged
sridharkalaibala merged 1 commit into
developfrom
feat/the-customer-can-choose-the-extras
Sep 16, 2026
Merged

sridharkalaibala merged 1 commit into
developfrom
feat/the-customer-can-choose-the-extras

Conversation

@sridharkalaibala

Copy link
Copy Markdown
Contributor

The till has priced extra cheese from the shop's own option documents since the handset learned about it (#824), and storefront() sends the option sets to every client - including the customer's page.

That page named none of them. So somebody ordering from the table could not ask for a thing the waiter standing next to them could ring up.

Three parts, and the middle one is the risk

The catalogue keeps them. The bundle's whole catalogue is one object literal, and a field it does not name never reaches the page however correctly the server sent it. This is the fourth time that literal has cost something.

A basket line is a dish AND a choice, not a dish. Two dosas, one with extra cheese, are two lines. The basket has always been keyed by the dish's id, so choosing cheese on the second would have silently changed the first, and the kitchen would have made two cheesy dosas for somebody who asked for one.

The key is now the dish plus what was chosen, sorted so the same two options picked in either order are one line, with the dish's real id alongside as item_id. A line written before this change carries no item_id and still answers, because everything reads item_id first and falls back to id.

And it never sends a price. The deltas are drawn on the sheet, because a charge that appears at checkout without having been shown is what people write bad reviews about. What goes back to the shop is which options were chosen, by name. The shop prices its own extras - a page that could name the price of cheese could name a discount nobody agreed to.

Two smaller decisions

A group the shop capped at one draws radios, anything else draws ticks: a tick that silently refuses to stay ticked is worse than one that visibly replaces another. An option that costs nothing shows no price, because "+0" reads as a charge somebody has to work out is not one.

One bug this nearly shipped with

The note and the spice level are set against a line id. With extras that id is the choice key, and setCartItemNote returns quietly when it finds no line - so handing it the dish's id would have dropped the note without a word. They now land on the line the choice made.

Checks

  • 10 new tests here, plus one repair: performCheckout now depends on dishIdOf, and the checkout harness lifts functions by name into a sandbox. Without lifting it, the ReferenceError inside the checkout read from outside as a refusal that never happened - the same class of miss the harness already had a comment about for notAWord. Two existing tests caught it.
  • Root suite 2,788 of 2,791 (the three need frontend/public built, which CI does); check-locally.js all 7 pass.
  • One new string with Tamil, in both copies of the dictionary.

Corrections to the must-have list I gave you

Looking properly, three of my six were already built:

  • order tracking exists and polls (I had grepped for "track")
  • allergen information exists as the "made without" tags - gluten_free, nut_free, dairy_free, lactose_free - and the ordering page already filters on them. It is a data gap, not a code gap: 0 of 272 dishes carry any.
  • options and extras were done server-side by another session; this is the customer half.

What is genuinely still missing: coupons on the online channel (no endpoint, no field, nothing - and you ship loyalty and coupons), and the menu having any words at all - 0 of 272 dishes have a description, a diet mark or a tag.

The till has priced extra cheese from the shop's own option documents
since the handset learned about it, and the storefront sends the option
sets to every client. This page named none of them, so somebody ordering
from the table could not ask for a thing the waiter standing next to them
could ring up.

Three parts, and the middle one is the risk.

THE CATALOGUE KEEPS THEM. The bundle's whole catalogue is one object
literal, and a field it does not NAME never reaches the page however
correctly the server sent it. That is the fourth time this literal has
cost something.

A BASKET LINE IS A DISH AND A CHOICE, NOT A DISH. Two dosas, one with
extra cheese, are two lines. The basket has always been keyed by the
dish's id, so choosing cheese on the second would have silently changed
the first and the kitchen would have made two cheesy dosas for somebody
who asked for one. The key is now the dish plus what was chosen, sorted so
the same two options picked in either order are one line, and the dish's
real id rides alongside as `item_id`. A line written before this change
carries no item_id and still answers, because everything reads item_id
first and falls back to id.

AND IT NEVER SENDS A PRICE. The deltas are drawn on the sheet, because a
charge that appears at checkout without having been shown is what people
write bad reviews about - but what goes back to the shop is which options
were chosen, by name. The shop prices its own extras. A page that could
name the price of cheese could name a discount nobody agreed to.

A group the shop capped at one draws radios and anything else draws
ticks, because a tick that silently refuses to stay ticked is worse than
one that visibly replaces another. An option that costs nothing shows no
price: "+0" reads as a charge somebody has to work out is not one.

The note and the spice level are set against the line the choice made,
not against the dish - setCartItemNote returns quietly when it finds no
line, so the dish's id would have lost them without a word.
@sridharkalaibala
sridharkalaibala merged commit edf0c66 into develop Sep 16, 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 16, 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