Skip to content

The shop's declared default, actually firing - #795

Merged
sridharkalaibala merged 1 commit into
developfrom
fix/the-shop-rule-that-never-fired
Sep 16, 2026
Merged

sridharkalaibala merged 1 commit into
developfrom
fix/the-shop-rule-that-never-fired

Conversation

@sridharkalaibala

Copy link
Copy Markdown
Contributor

Your ask: "let restaurent owner decide that. give option auto cancel or auto accept.
based ont time he defines it. by default dont accpept or reject."

It was built, and it has never once happened

waiting-order-policy.js was written, tested and merged. It decides perfectly.
Nothing ever asked it for a decision it could act on - two dead ends, one on top
of the other
:

  1. setPolicy() on the desktop alarm was called from nowhere, so the policy was
    always { onSilence: 'nothing', decideAfterMinutes: 0 } and decide() could only
    ever answer "nothing". There was no setting to feed it either.
  2. When it did speak, the till emitted posnic:order-decided on the process bus -
    which nothing listened to - and then deleted the order from its pending map.

So the alarm went quiet with the order still sitting there and the customer still
waiting. An alarm that stops is a promise that somebody dealt with it, and that
promise was false. That is the exact failure this whole area exists to prevent, and it
was built in.

Where the rule lives now

In the API, not the till. Three reasons:

  • The till is a sound module, and its own comment says deciding belongs where the order
    lives: "a sound module that could cancel a customer's order would be a surprising
    place to find that power."
  • A shop served from the cloud has no till at all, and its held orders would sit for
    ever.
  • It goes through decideOnOrder, the same door a person at the queue uses, so an
    automatic acceptance prints its kitchen ticket exactly the way a tapped one does -
    rather than by a second path that would drift from it.

Both halves read the same pure policy for different fields: the till reads alert and
reach and makes a noise, the server reads decide and moves the order. Two copies,
because the API ships outside the asar archive, pinned by a behavioural test over a
thousand combinations - a drift there would have a shop's alarm and a shop's rule
working to two different clocks.

And it reads the order back before it announces anything

decideOnOrder narrows its write by whatever tenant the process was last serving,
and reports success on what it asked for rather than on what changed. A write that
matched nothing still answers yes. Stopping the alarm on that would be the same bug
arriving by a different door, so the state is checked and silence is only ever earned.

What it will not do

A shop that chose nothing nothing, ever. Absent settings mean no rule
Half a rule nothing. A choice with no time fires at once; a time with no choice fires nothing
An order older than 12 hours left for a person. Cooking food for somebody who left last night is not a rule's call
An aggregator's order past their own window nothing. Swiggy and Zomato reject on their own timer and count it against you; landing after them records the opposite of what happened
More than 20 in one tick the rest wait. A shop back from an outage must not print two hundred tickets in one breath

The setting

Settings → New online orders, beside "When an order arrives":

  • If nobody answers - Leave it waiting (default) / Accept it and send to the kitchen /
    Cancel it and tell the customer
  • After how long - 5m / 10m / 15m / 30m / 1h

Hidden entirely while a shop is on automatic, because a shop that holds nothing has no
queue for this to be about. The alarm keeps asking either way, backing off as it goes.

Checks

  • api: 375 suites, 10,829 tests (18 new, against a real mongod)
  • tests/: the two policy copies over 1,000+ combinations, plus wiring tests that the
    rule is actually started and that the till no longer pretends to decide
  • npm run check: 7/7
  • 7 new strings translated into all 17 packs

Owner: "let restaurent owner decide that. give option auto cancel or auto
accept. based ont time he defines it. by default dont accpept or reject."

waiting-order-policy.js was written, tested and merged, and decided
perfectly for nobody. Two dead ends, one on top of the other:

setPolicy() on the desktop OrderAlert was called from nowhere, so the
policy was always { onSilence: 'nothing', decideAfterMinutes: 0 } and
decide() could only ever answer "nothing". There was no setting to feed
it either. So "auto cancel after ten minutes" has never once happened.

And when it did speak, the till emitted posnic:order-decided on the
process bus, WHICH NOTHING LISTENED TO - and then deleted the order from
its pending map. The alarm went quiet with the order still sitting there
and the customer still waiting. An alarm that stops is a promise that
somebody dealt with it, and that promise was false. That is the exact
failure this whole area exists to prevent, and it was built in.

The rule now fires in the API. The till is a sound module, and its own
comment says deciding belongs where the order lives; it is also the wrong
half, because a shop served from the cloud has no till and its held
orders would sit for ever. Both halves read the same pure policy for
different fields: the till reads alert and reach and makes a noise, the
server reads decide and moves the order. Two copies, because the API
ships outside the asar archive, pinned by a behavioural test over a
thousand combinations.

It goes through decideOnOrder, the same door a person at the queue uses,
so an automatic acceptance prints its kitchen ticket exactly the way a
tapped one does rather than by a second path that would drift from it.

AND IT READS THE ORDER BACK BEFORE IT ANNOUNCES ANYTHING. decideOnOrder
narrows its write by whatever tenant the process was last serving and
answers success on what it asked for rather than on what changed, so a
write that matched nothing still says yes. Stopping the alarm on that
would be the same bug arriving by a different door.

Nothing happens unless a shop asked. Absent settings mean nothing, both
halves of the rule are required, an order older than twelve hours is left
for a person, and an aggregator's own deadline is never overrun.

Settings sit under New online orders, beside "When an order arrives", and
are hidden entirely while a shop is on automatic.
@sridharkalaibala
sridharkalaibala merged commit b90ab60 into develop Sep 16, 2026
9 of 10 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