Work / AskCal / Wiki / Surfaces
correct-item
Surfacecanonicalverified 2026-09-26
SURFACE.MOBILE.SCAN.CORRECTSummary
Saying what one item on the plate actually is — or that it was never there.
Raw wireframe
- .context/designs/mobile/scan/correct-item.html
Why it is drawn this way
One item, and the whole dish is correct-dish. This screen used to be both, switched by a segmented control, and the control was the problem rather than the solution. The scope was always known from the caller — you arrive here by tapping a row — so the control asked a question whose answer had already been supplied. The two are also not the same correction: renaming the dish re-derives every row, renaming one row leaves the other four alone. Sharing a screen made them look like one act with a setting, and landing on the wrong default was one unnoticed tap away from discarding the rows the model got right.
"Remove it" replaced the database link. The complaint behind most single-row corrections is not "this is the wrong food", it is "this food was not there" — the estimator reads a coleslaw out of a reflection, or counts the garnish as a side. Renaming it to nothing is not possible, and nudging it to zero leaves a weightless row in the log for ever.
"Pick it from the food database instead" is gone. It sent the user to the search tab, which is a different tab with its own stack, on a screen whose job is to log its own meal — so coming back was not coming back: the scan was gone and the user was standing on Today. A link that leaves the flow does not belong in the middle of the flow. Swapping a row for a verified match is a real want, and it belongs on the item editor next to the source line that says where the numbers came from.
This is still the only free-text field in the scan flow, along with correct-dish. A question screen forbids one on purpose — a question with a keyboard is a form. This is not a question, it is a correction, and no list of options contains every food on earth.
Related
Departure from the app — one route, two renderings
The two wireframes stay separate files because they draw genuinely different
screens: the dish face warns that every row is re-derived, and the item face
offers Remove. Neither is a state in the closed set
(empty · loading · error · offline · locked), so by the one-screen-per-file
rule each keeps its own file and its own node in the chart.
The APP now serves both from a single route. app/scan/correct.tsx takes an
optional component param: present names a row, absent means the dish. There is
still no control to choose between them — the scope comes from the route, which
is what made the original segmented version dangerous and is the part that must
never come back.
Recorded here rather than fixed in the wireframes because the JOURNEY is unchanged: the user still taps "wrong dish?" and sees the dish face, or taps a row and sees the item face. The chart is a diagram of what the user does, and what the user does did not change.
Renamed from correct
The pair is correct-dish and correct-item. correct on its own read as the
general case with correct-dish a special one, when they are two equal scopes
of the same act — and the app takes exactly that shape: one route whose
component param names a row, its absence the dish.
Sources
- .context/designs/mobile/scan/correct-item.html
Every project of mine is written down like this.
Read the résumé