diet-guard/app/lib/services
Krzysztof kuhy Rudnicki af35eb20c8 feat: offer delivered dishes to the log form, one tap each
The phone now prefills the log form with today's delivered dishes, in the
caterer's own meal order. It still never logs anything itself -- a delivered
meal is not an eaten meal, so the user taps for each dish.

Two guards carried over from the PC, both of which fail silently if dropped:

- **The queue survives a submit.** `prefillNextDish` has two callers: the
  initial load and the post-submit advance. On the PC the second briefly did
  not exist, which made "(N more to go)" a dead letter -- every dish after the
  first waited behind another tap. The test asserts the *form controller*
  holds dish 2 after dish 1 is logged, not that a dish is "available"; the
  latter passes throughout that bug.
- **The automatic refresh is guarded** by a device-local last-fetched date,
  mirroring `refresh_delivery_once`. The log-flow trigger can fire after every
  meal and each unguarded walk is a login plus three requests. The settings
  button deliberately stays unguarded: an explicit ask always goes and looks,
  matching `diet-guard kuchnia`. Only a clean fetch records the day, so an
  outage retries.

Dishes are ordered against `MealScheduleService.current`, never a hardcoded
four slots -- offering a dish for a slot the user's schedule does not have is
the "checkpoint that can never be satisfied" failure in a new costume.

Editing the description before submitting leaves the dish queued: what was
logged was not the delivered dish, and marking it eaten would lose a real
delivery silently.

Two bugs the tests caught:

- `dishesStillQueued` excluded the offered dish, so the status line read
  "0 more" while a real dish sat in the form. The offered dish is prefilled,
  not logged; it counts.
- An end-to-end test through the real `LogMealScreen` never terminated --
  that screen's `initState` fans out into sync, notifications and the food
  bank, and pumping it to quiescence hangs. Rather than keep fighting it, the
  behaviour is tested at the mixin that owns it, through a minimal host. The
  guarantee asserted is the same one: form contents after a submit.

`log_meal_screen.dart` is back under the 250-line cap by moving the nutrition
build into `log_meal_actions.dart` and inlining a one-line alias.

694 Dart tests, 1040 Python tests, 100% Python branch coverage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQpCiPaSbyRpwsLkH3dgsX
2026-08-23 09:07:17 +02:00
..
app_settings_service.dart Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
average_service.dart Step Dart dates by the calendar, not by 24 hours 2026-08-09 15:06:41 +02:00
background_check_service.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
background_sync_service.dart feat: carry the catering credential to the phone 2026-08-23 08:25:27 +02:00
background_tasks_io.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
background_tasks_web.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
background_tasks.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
budget_history_service.dart Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
budget_schedule.dart Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
day_status_service.dart Step Dart dates by the calendar, not by 24 hours 2026-08-09 15:06:41 +02:00
desktop_wrapper.dart Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
document_store_factory.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
document_store_indexeddb.dart app: test the IndexedDB stores instead of shipping them unverified 2026-07-20 16:56:15 +02:00
document_store_io.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
document_store_web.dart app: test the IndexedDB stores instead of shipping them unverified 2026-07-20 16:56:15 +02:00
document_store.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
due_slot_check.dart Read the meal schedule from a forward-only history (Dart) 2026-08-16 14:41:37 +02:00
firebase_backend.dart Split the last four Dart lib files; file-length gate now reports zero 2026-08-15 21:07:24 +02:00
firebase_client.dart Split the last four Dart lib files; file-length gate now reports zero 2026-08-15 21:07:24 +02:00
foodbank_service_manual.dart Split the last four Dart lib files; file-length gate now reports zero 2026-08-15 21:07:24 +02:00
foodbank_service.dart Split the last four Dart lib files; file-length gate now reports zero 2026-08-15 21:07:24 +02:00
frame_stats.dart app: package the desktop app as the web build, and delete the Linux embedder 2026-07-20 16:32:24 +02:00
fuzzy.dart Add Flutter companion app skeleton with local meal logging 2026-06-22 18:22:42 +02:00
github_client_factory_io.dart app: use the shared github_device_auth package 2026-08-15 16:15:24 +02:00
github_client_factory_web.dart app: use the shared github_device_auth package 2026-08-15 16:15:24 +02:00
github_client_factory.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
google_platform_io.dart Add Google sign-in support for the Firebase sync account 2026-08-12 23:36:10 +02:00
google_platform_web.dart Add Google sign-in support for the Firebase sync account 2026-08-12 23:36:10 +02:00
google_platform.dart Add Google sign-in support for the Firebase sync account 2026-08-12 23:36:10 +02:00
google_sign_in_backend.dart Add Google sign-in support for the Firebase sync account 2026-08-12 23:36:10 +02:00
kuchnia_client.dart feat: let the phone fetch and bank the catering delivery itself 2026-08-23 08:30:21 +02:00
kuchnia_credential_service.dart feat: carry the catering credential to the phone 2026-08-23 08:25:27 +02:00
kuchnia_errors.dart feat: let the phone fetch and bank the catering delivery itself 2026-08-23 08:30:21 +02:00
kuchnia_import.dart feat: let the phone fetch and bank the catering delivery itself 2026-08-23 08:30:21 +02:00
kuchnia_orders.dart feat: let the phone fetch and bank the catering delivery itself 2026-08-23 08:30:21 +02:00
kuchnia_parse.dart feat: mirror the catering parser and slot spread in Dart, gated by one fixture 2026-08-23 08:00:54 +02:00
kuchnia_queue.dart feat: offer delivered dishes to the log form, one tap each 2026-08-23 09:07:17 +02:00
kuchnia_spread.dart feat: offer delivered dishes to the log form, one tap each 2026-08-23 09:07:17 +02:00
log_storage_service.dart Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
meal_schedule_history.dart Read the meal schedule from a forward-only history (Dart) 2026-08-16 14:41:37 +02:00
meal_schedule_service.dart Read the meal schedule from a forward-only history (Dart) 2026-08-16 14:41:37 +02:00
notification_backend_factory.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
notification_backend_io.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
notification_backend_web.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
notification_backend.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
notification_service.dart Read the meal schedule from a forward-only history (Dart) 2026-08-16 14:41:37 +02:00
sync_device_id.dart Push under a persisted per-install uuid, not a fixed role id 2026-08-09 17:18:42 +02:00
sync_health.dart Make the phone publish on every tick, and fail closed on Firebase errors 2026-08-10 14:35:37 +02:00
sync_merge_banks.dart Split wrapper_server and sync_merge into siblings 2026-08-15 16:42:27 +02:00
sync_merge_budget.dart Sync the meal schedule as sched: fields on the budget record 2026-08-16 14:49:08 +02:00
sync_merge_kuchnia.dart feat: carry the catering credential to the phone 2026-08-23 08:25:27 +02:00
sync_merge_schedule.dart Sync the meal schedule as sched: fields on the budget record 2026-08-16 14:49:08 +02:00
sync_merge.dart Split wrapper_server and sync_merge into siblings 2026-08-15 16:42:27 +02:00
sync_service.dart feat: carry the catering credential to the phone 2026-08-23 08:25:27 +02:00
sync_settings.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
sync_state_factory_io.dart Sync meals and the food bank through Firebase, mirroring to GitHub 2026-08-05 08:35:21 +02:00
sync_state_factory_web.dart Sync meals and the food bank through Firebase, mirroring to GitHub 2026-08-05 08:35:21 +02:00
sync_state_factory.dart Sync meals and the food bank through Firebase, mirroring to GitHub 2026-08-05 08:35:21 +02:00
token_vault_factory.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
token_vault_io.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
token_vault_web.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00
token_vault.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00