mobieusKnow Handling meal photo review tickets History #528
Author
Patrick Bass
Submitted
Aug 26, 2026 4:25pm
Summary
Handling meal-photo review tickets
'''What a meal-photo-review ticket usually is.''' Almost all of them are one of four things: the member expected the old one-tap picker, the member logged and then wanted to change something, an estimate expired, or a free member hit the paywall. None of the four is a fault.
== What changed on 2026-08-26 ==
Photographing a plate used to return whole-plate candidates and log the tapped one instantly, as '''one''' food-log entry named after the plate.
+ It now returns the plate '''broken into items'''. The member reviews them on a screen, adjusts portions, removes or adds foods, and taps '''Log meal''' — which writes '''one entry per item'''.
It now returns the plate '''broken into items'''. The member reviews them on a screen, adjusts portions, removes or adds foods, and taps '''Log meal''', which writes '''one entry per item'''.
Two consequences worth knowing before you answer anything:
* '''Taking a photo no longer logs anything.''' Backing out of the review screen leaves the day exactly as it was. A member saying "I took a photo and nothing was logged" has usually done exactly that.
+ * '''A photo meal now appears as several entries.''' Chicken, rice and broccoli are three rows in the food log, not one. This is deliberate — it is what lets them edit the rice a week later without touching the chicken.
* '''A photo meal now appears as several entries.''' Chicken, rice and broccoli are three rows in the food log, not one. This is deliberate. It is what lets them edit the rice a week later without touching the chicken.
== The four common tickets ==
=== "It used to be one tap" ===
+ It was, and the new screen is one extra tap for a member who changes nothing: the estimate is the same one that used to be pre-selected. Point them at the running total at the bottom — it is the number that used to be decided for them.
It was, and the new screen is one extra tap for a member who changes nothing: the estimate is the same one that used to be pre-selected. Point them at the running total at the bottom. It is the number that used to be decided for them.
=== "I want to change something I already logged" ===
The review screen is before the write. Afterwards it is ordinary food-log editing: open the Food screen, tap the entry, change or delete it. Each item is its own entry, so they change only the one they mean.
=== "It says the estimate has expired" ===
+ Photo estimates are held for '''24 hours'''. Past that, the screen offers to re-check the same photo, which starts a fresh reading. That is the whole fix — there is nothing to restore and nothing on our side to extend.
Photo estimates are held for '''24 hours'''. Past that, the screen offers to re-check the same photo, which starts a fresh reading. That is the whole fix. There is nothing to restore and nothing on our side to extend.
=== "It wants me to upgrade" ===
Photo logging is '''Premium''', and it was Premium before this release too. Free members log by search, barcode, voice and by hand. Do not offer a workaround; point them at the plan page.
== What support can and cannot see ==
'''Cannot: what was on the plate.''' The analysis is encrypted under the member's own key, exactly as their food log is. There is no admin screen that decrypts it and there is no query that will.
+
+ '''Can: that a request happened.''' The tenant nginx access log carries method, path, status and the app's build number:
+ <pre>
+ grep 'meal-photo' /var/log/nginx/tenant-loopa/access.log | tail -40
+ </pre>
'''Can: that a request happened.''' Platform support can read the tenant's web request log, which carries the method, the path, the status and the app's build number. Ask them for the meal-photo requests around the time the member reports.
That is enough to answer most of what is asked:
* A '''200''' on <code>/api/v1/health/meal-photo</code> and no later '''201''' on <code>/meal-photo/log</code> means the member backed out. Nothing was logged, and nothing is wrong.
* A '''402''' on either is the Premium gate.
* A '''410''' on <code>/meal-photo/log</code> is the 24-hour expiry.
+ * A '''409''' is a second submission of an estimate already logged — usually a retry on a bad connection. One meal exists, which is correct.
+ * A '''429''' is the per-member burst cap: twelve analyses in five minutes. It clears on its own.
* A '''409''' is a second submission of an estimate already logged, usually a retry on a bad connection. One meal exists, which is correct.
* A '''429''' is the per-member burst cap: twelve analyzes in five minutes. It clears on its own.
* A '''428''' is the AI disclosure sheet: the member has not yet been shown, or has withdrawn consent for, meal photo analysis. They resolve it in '''Your Data'''.
== Where it is gated ==
+ Both the analysis and the log endpoint check the same '''meal_photo''' entitlement. If a member has Premium and is still seeing the gate, check the seat first (<code>health_seats</code>) before escalating — the endpoint is not doing anything unusual.
Both the analysis and the log endpoint check the same '''meal_photo''' entitlement. If a member has Premium and is still seeing the gate, check the seat first (<code>health_seats</code>) before escalating. The endpoint is not doing anything unusual.
== What to escalate ==
* A '''500''' on either endpoint.
* '''Duplicate entries from a single submission.''' The analysis is claimed by a conditional update before anything is written, so two meals from one tap would be a real defect and engineering wants it.
* A member reporting figures on the '''food log''' that differ from what the review screen showed them. The server recomputes from the estimate rather than trusting the app, so the two should agree.
== What not to escalate ==
* '''An estimate a member disagrees with.''' That is what the screen is for, and correcting it is the feature working.
* '''An item marked "less sure".''' It is a confidence hint, not an error, and it never blocks logging.
* '''An empty result.''' A photo where nothing was recognized still opens the review screen with '''Add item''', so the member can log the meal by hand. Better light and the whole plate in frame is the advice.

'''What a meal-photo-review ticket usually is.''' Almost all of them are one of four things: the member expected the old one-tap picker, the member logged and then wanted to change something, an estimate expired, or a free member hit the paywall. None of the four is a fault.

== What changed on 2026-08-26 ==

Photographing a plate used to return whole-plate candidates and log the tapped one instantly, as '''one''' food-log entry named after the plate.

It now returns the plate '''broken into items'''. The member reviews them on a screen, adjusts portions, removes or adds foods, and taps '''Log meal''' — which writes '''one entry per item'''.

Two consequences worth knowing before you answer anything:

* '''Taking a photo no longer logs anything.''' Backing out of the review screen leaves the day exactly as it was. A member saying "I took a photo and nothing was logged" has usually done exactly that. * '''A photo meal now appears as several entries.''' Chicken, rice and broccoli are three rows in the food log, not one. This is deliberate — it is what lets them edit the rice a week later without touching the chicken.

== The four common tickets ==

=== "It used to be one tap" ===

It was, and the new screen is one extra tap for a member who changes nothing: the estimate is the same one that used to be pre-selected. Point them at the running total at the bottom — it is the number that used to be decided for them.

=== "I want to change something I already logged" ===

The review screen is before the write. Afterwards it is ordinary food-log editing: open the Food screen, tap the entry, change or delete it. Each item is its own entry, so they change only the one they mean.

=== "It says the estimate has expired" ===

Photo estimates are held for '''24 hours'''. Past that, the screen offers to re-check the same photo, which starts a fresh reading. That is the whole fix — there is nothing to restore and nothing on our side to extend.

=== "It wants me to upgrade" ===

Photo logging is '''Premium''', and it was Premium before this release too. Free members log by search, barcode, voice and by hand. Do not offer a workaround; point them at the plan page.

== What support can and cannot see ==

'''Cannot: what was on the plate.''' The analysis is encrypted under the member's own key, exactly as their food log is. There is no admin screen that decrypts it and there is no query that will.

'''Can: that a request happened.''' The tenant nginx access log carries method, path, status and the app's build number:

grep 'meal-photo' /var/log/nginx/tenant-loopa/access.log | tail -40

That is enough to answer most of what is asked:

* A '''200''' on /api/v1/health/meal-photo and no later '''201''' on /meal-photo/log means the member backed out. Nothing was logged, and nothing is wrong. * A '''402''' on either is the Premium gate. * A '''410''' on /meal-photo/log is the 24-hour expiry. * A '''409''' is a second submission of an estimate already logged — usually a retry on a bad connection. One meal exists, which is correct. * A '''429''' is the per-member burst cap: twelve analyses in five minutes. It clears on its own. * A '''428''' is the AI disclosure sheet: the member has not yet been shown, or has withdrawn consent for, meal photo analysis. They resolve it in '''Your Data'''.

== Where it is gated ==

Both the analysis and the log endpoint check the same '''meal_photo''' entitlement. If a member has Premium and is still seeing the gate, check the seat first (health_seats) before escalating — the endpoint is not doing anything unusual.

== What to escalate ==

* A '''500''' on either endpoint. * '''Duplicate entries from a single submission.''' The analysis is claimed by a conditional update before anything is written, so two meals from one tap would be a real defect and engineering wants it. * A member reporting figures on the '''food log''' that differ from what the review screen showed them. The server recomputes from the estimate rather than trusting the app, so the two should agree.

== What not to escalate ==

* '''An estimate a member disagrees with.''' That is what the screen is for, and correcting it is the feature working. * '''An item marked "less sure".''' It is a confidence hint, not an error, and it never blocks logging. * '''An empty result.''' A photo where nothing was recognized still opens the review screen with '''Add item''', so the member can log the meal by hand. Better light and the whole plate in frame is the advice.

'''What a meal-photo-review ticket usually is.''' Almost all of them are one of four things: the member expected the old one-tap picker, the member logged and then wanted to change something, an estimate expired, or a free member hit the paywall. None of the four is a fault.

== What changed on 2026-08-26 ==

Photographing a plate used to return whole-plate candidates and log the tapped one instantly, as '''one''' food-log entry named after the plate.

It now returns the plate '''broken into items'''. The member reviews them on a screen, adjusts portions, removes or adds foods, and taps '''Log meal''' — which writes '''one entry per item'''.

Two consequences worth knowing before you answer anything:

* '''Taking a photo no longer logs anything.''' Backing out of the review screen leaves the day exactly as it was. A member saying "I took a photo and nothing was logged" has usually done exactly that.
* '''A photo meal now appears as several entries.''' Chicken, rice and broccoli are three rows in the food log, not one. This is deliberate — it is what lets them edit the rice a week later without touching the chicken.

== The four common tickets ==

=== "It used to be one tap" ===

It was, and the new screen is one extra tap for a member who changes nothing: the estimate is the same one that used to be pre-selected. Point them at the running total at the bottom — it is the number that used to be decided for them.

=== "I want to change something I already logged" ===

The review screen is before the write. Afterwards it is ordinary food-log editing: open the Food screen, tap the entry, change or delete it. Each item is its own entry, so they change only the one they mean.

=== "It says the estimate has expired" ===

Photo estimates are held for '''24 hours'''. Past that, the screen offers to re-check the same photo, which starts a fresh reading. That is the whole fix — there is nothing to restore and nothing on our side to extend.

=== "It wants me to upgrade" ===

Photo logging is '''Premium''', and it was Premium before this release too. Free members log by search, barcode, voice and by hand. Do not offer a workaround; point them at the plan page.

== What support can and cannot see ==

'''Cannot: what was on the plate.''' The analysis is encrypted under the member's own key, exactly as their food log is. There is no admin screen that decrypts it and there is no query that will.

'''Can: that a request happened.''' The tenant nginx access log carries method, path, status and the app's build number:

<pre>
grep 'meal-photo' /var/log/nginx/tenant-loopa/access.log | tail -40
</pre>

That is enough to answer most of what is asked:

* A '''200''' on <code>/api/v1/health/meal-photo</code> and no later '''201''' on <code>/meal-photo/log</code> means the member backed out. Nothing was logged, and nothing is wrong.
* A '''402''' on either is the Premium gate.
* A '''410''' on <code>/meal-photo/log</code> is the 24-hour expiry.
* A '''409''' is a second submission of an estimate already logged — usually a retry on a bad connection. One meal exists, which is correct.
* A '''429''' is the per-member burst cap: twelve analyses in five minutes. It clears on its own.
* A '''428''' is the AI disclosure sheet: the member has not yet been shown, or has withdrawn consent for, meal photo analysis. They resolve it in '''Your Data'''.

== Where it is gated ==

Both the analysis and the log endpoint check the same '''meal_photo''' entitlement. If a member has Premium and is still seeing the gate, check the seat first (<code>health_seats</code>) before escalating — the endpoint is not doing anything unusual.

== What to escalate ==

* A '''500''' on either endpoint.
* '''Duplicate entries from a single submission.''' The analysis is claimed by a conditional update before anything is written, so two meals from one tap would be a real defect and engineering wants it.
* A member reporting figures on the '''food log''' that differ from what the review screen showed them. The server recomputes from the estimate rather than trusting the app, so the two should agree.

== What not to escalate ==

* '''An estimate a member disagrees with.''' That is what the screen is for, and correcting it is the feature working.
* '''An item marked "less sure".''' It is a confidence hint, not an error, and it never blocks logging.
* '''An empty result.''' A photo where nothing was recognized still opens the review screen with '''Add item''', so the member can log the meal by hand. Better light and the whole plate in frame is the advice.