Skip to content

Release: the bill, a number nobody can ring, and the pass driven rather than read - #770

Merged
sridharkalaibala merged 8 commits into
mainfrom
develop
Sep 15, 2026
Merged

sridharkalaibala merged 8 commits into
mainfrom
develop

Conversation

@sridharkalaibala

@sridharkalaibala sridharkalaibala commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Promotes develop to main. Four merged pull requests.

Merge with a merge commit, never a squash. The repository ruleset enforces that.

What reaches production

#769 - the bill carries what the shop needs.

#771 - a number nobody can ring is not information. Owner's screenshot of the order queue showed a row reading +91null. I had guarded the read that built it, which stopped new orders carrying it, then went looking for the writer - and there isn't one. Both writers of that key store real strings. The value is on orders taken before that fix, and a device we do not control could send another tomorrow, so a guard at the writer fixes neither.

The bill already answered this well: isDialable asks could this be dialled rather than is this Indian, so it is right for Puducherry and anywhere else. The queue simply was not asking - and on that screen it matters more than on a bill, because somebody may try to ring it. The two can no longer disagree.

#768 - the nutrition pass driven rather than read. Owner asked whether it had been tested; the honest answer was partly. The customer pages had been driven in a real browser; the shop-facing nutrition chain had not - every test on it asserted the shape of the source, none ran the loop.

Nine tests now run it against the real modal markup. Eight passed first time. The ninth found a real bug: a refusal set the message saying why the run stopped - no key, provider down, cap spent - and the summary painted straight over it, so a shop with no AI key saw "Stopped. 1 could not be done" and never learned the cause. Nothing in the source would have shown it; the stop was there, the message was there, and the order they ran in was the whole defect.

#767 - the provenance test calls the code.

Verified before opening

Root suite 2,532 of 2,535 on the develop tip; the three remaining are the release-artifact tests that need frontend/public built, which CI does. API suite 10,638 of 10,638.

Owner, fairly: "have you tested ?"

The test written with that change read the CONTROLLER'S SOURCE with a regular
expression - that `clientIp(req)` appeared in it, that one spread came before
another. That is not a test of behaviour. It passes if the block is
unreachable, it passes if an early return skips it, and it would pass against a
file that never runs.

So the handler is called now, with a request shaped the way Express builds one,
and the assertion is about what reaches the service: the address and the user
agent come from the request, the waiter comes from the session, what the phone
says about itself is carried, and a body claiming any of the first two is
overruled. Eight cases, including the one that matters - a phone must not be
able to write the provenance of the order being investigated.

Proved against the code as it was before the change: six of the eight fail.

The regex version is replaced rather than kept beside it. Two tests of one
thing, where one of them cannot fail honestly, is worse than one.
Owner: "have you tested ?"

Partly, was the honest answer. The customer-facing work was driven in a real
browser - grouped menu, menu button, filters, card geometry at three widths,
the live page. The shop-facing nutrition chain was not driven at all. Every
test on it asserted the SHAPE of the source: that a function exists, that a
line matches a pattern, that a field is in a projection. Not one ran the loop.

That is the kind of gap that lets a feature ship broken with green tests,
because a regex over source cannot tell you that the second dish is never
asked about, that Stop does not stop, or that a refusal spends three hundred
calls before giving up.

So this runs it: the real module, in a real DOM, against a server that answers
the way the real one does - and against the REAL modal markup lifted out of
items.html, so the test cannot drift from the page it is testing.

Eight of the nine passed first time. The loop walks every dish in order, Stop
stops on the next one, an ordinary failure does not end the run while a 400
does, a skipped dish is counted as left alone rather than done, the review
screen shows the badges confirming would publish, and confirming sends only
the ticked rows.

THE NINTH FOUND A REAL BUG. A refusal set the message saying why - no key,
provider down, cap spent - and finish() painted its summary straight over it.
A shop with no AI key saw "Stopped. 1 could not be done" and never learned the
cause, which is both the likeliest reason it stops and the one with an obvious
fix. The reason is kept now and leads the summary.

Nothing in the source would have shown that. The stop was there, the message
was there, and the order they ran in was the whole defect.
Owner, sent the remaining fields off his reference invoice: "extra bill field
keep it as configuration."

Three of the five are built. Each is a switch, each off by default, each on the
same "What the bill carries" card as the other six.

SESSION reuses the serving times a shop already set for its menu, rather than
asking for them again in different words. Two lists that can disagree is how a
bill comes to say Dinner while the kitchen is serving lunch. A service running
past midnight is still that service; a sale outside every period prints nothing
rather than guessing.

HSN / SAC is carried on the SALE, not looked up from the catalogue when a bill
prints. A code corrected next month must not change what a reprinted invoice
says it charged. Every sale made before the field existed has none, so the
column is dropped entirely when no line carries a code - switching it on does
not draw a blank stripe down a year of old bills.

FSSAI is a licence number plus a switch, printed under the GSTIN where a food
invoice carries it. A shop that turns it on without entering a number prints no
label: a labelled empty line on a tax invoice reads as a fault.

AND THE SHOP ROWS MOVED INTO THE HEADER. Session, Table, Covers and Steward
were printing after the TOTAL, because they were riding in `extras`, which is
where a shop's own template rows belong. On the reference invoice they sit
beside the bill number at the top, which is where a bill is read and where a
waiter carrying one looks first. They have their own field now and `extras` is
what it always was.

NOT BUILT: KOT numbers and Room No. Neither exists as data - the server records
no kitchen ticket number and there is no room concept anywhere. A label with
nothing behind it would have been the easy half of the job and the useless one.

Nine new strings, in all seventeen packs. FSSAI, HSN and SAC stay as they are in
every language: they name an Indian authority and two code systems, and a shop
looking for the field on a Tamil screen is looking for the letters printed on
its licence.

Desktop 2513 pass, API 10630 pass.
…op-needs

The rest of the hotel bill, as configuration
…e-code

The provenance test calls the code instead of reading it
…reading-it

Drive the nutrition pass instead of reading it, and find a bug
Owner's screenshot of the order queue showed a row reading "+91null".

I guarded the READ that built it, which stopped new orders carrying it, and
then went looking for the writer. There isn't one: both writers of that key
store real strings, and the customer pages cannot produce the word. The value
is on orders taken before that fix, and a device we do not control could send
another tomorrow. A guard only at the writer fixes neither.

The bill already answered this question, and answered it well. isDialable asks
"could this be dialled" - 7 to 15 digits, no long run of one repeated digit -
rather than "is this Indian", so it is right for a shop in Puducherry and for
one anywhere else. The queue simply was not asking, and on that screen it
matters more than on a bill: somebody may try to ring it.

So the queue asks the same question the receipt asks, which also means the two
can never disagree about whether a number can be rung. One import, one call.

Refused: "+91null", "null", "undefined", blank, "0000000000", "12".
Passed: "9876543210", "+919876543210", and one with spaces in it.

The test for it first bounded the method at 5000 characters and the line sits
at 5080 - the same brittleness that has already failed twice here on code that
was correct. It reads to the end of the method now.
A number nobody can ring is not information
@sridharkalaibala sridharkalaibala changed the title Release: the bill carries what the shop needs Release: the bill, a number nobody can ring, and the pass driven rather than read Sep 15, 2026
@sridharkalaibala
sridharkalaibala merged commit f051320 into main Sep 15, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant