Work / AskCal / Wiki / Surfaces
bill
Surfaceproposedverified 2026-09-26
SURFACE.MOBILE.SCAN.BILLSummary
Reading dish names off a restaurant bill, and asking which of them were yours.
Raw wireframe
- .context/designs/mobile/scan/bill.html
Why it is drawn this way
A bill is not a plate. A photograph of food shows what one person is about to eat. A bill shows what a TABLE ordered — four people, nine dishes, and nothing on the paper saying who ate which. Logging all of it would hand one diner the whole table's calories: the single largest overcount the app could produce, on exactly the meals people most want logged.
So the bill is read and then the user says which of it was theirs. Ticking is the cheapest possible interaction for that question, and everything starts unticked — a default that guesses on the user's behalf is the overcount again with an extra step.
Names only. Prices, taxes, service charge, table number, the GST line and the restaurant's name are all read past. A price is not evidence about food: the same a 320 unit line buys a salad or a steak, and a model that has been shown a number will use it. The prompt asks for dish names and the screen shows dish names, so there is no quiet path by which a price reaches an estimate.
One scan for the whole bill. One photograph, one model call, however many dishes come back. Metering per dish would make a thali cost eight scans and teach people not to use it.
Counts on the bill are kept. "2 x Garlic bread" is the bill stating a quantity, which is better evidence than the estimator guessing one. It is the TABLE's count though, not the user's, which is what the share step after this is for — see portion share.
A bill names dishes, not recipes. How much oil went into them is still invisible, so the estimate still has to reason about it and the result screen still asks the usual question. The card at the foot says so, because a user who has just handed the app a printed list reasonably expects it to know everything.
Open questions for the schema stage
- Mode, not a separate route on the device? The camera takes
?mode=bill, orscan/bill.tsxis its own screen. The wireframe assumes the latter. - The wire needs a shape for "dish names extracted", which is not a
ScanResult— there are no macros yet. Probably its own response, then a normal/scan-shaped call once the user has ticked. no_dishesas a newScanErrorcode, rendered by the existingfailedscreen rather than a new one.
Related
Sources
- .context/designs/mobile/scan/bill.html
Every project of mine is written down like this.
Read the résumé