diet-guard/app/lib/services
Krzysztof kuhy Rudnicki 3d82ddefd4 feat: let the phone fetch and bank the catering delivery itself
The phone now walks the panel on its own -- login, active order, delivery,
menu -- parses the dishes and banks them, so the feature works with the PC
switched off. Read-only: nothing here logs a meal.

`package:http` has no cookie jar, so the `SESSION` cookie is read off the login
response and replayed by hand. `Response.headers` folds duplicate `set-cookie`
values into one comma-joined string, so the parser splits on both `,` and `;`
and looks for the named cookie rather than assuming the header holds only it --
tested against both orderings and against a panel that sets no session cookie
at all.

Android-only, as decided: the panel sends no CORS headers, so a browser cannot
call it. `refreshDelivery` checks `kIsWeb` first and returns the unsupported
reason without touching the network. No `dart:io` anywhere -- `package:http`
compiles for web, it is the panel that refuses, not the toolchain, so this
needs no `_io`/`_web` seam.

The idempotency guard is ported with its teeth: `addManualEntry` restamps
`editedAt` unconditionally, so re-banking an unchanged dish republishes the
whole curated bank to every peer. `bankDishes` compares the nutritional fields
first and returns a write *count*, which is what the tests assert on -- "the
entry exists" passes while this misbehaves. The comparison is numeric, not
string, so `270 == 270.0` is a match exactly as in Python's `_matches`.

Every failure becomes a reason string, never a throw, so a catering outage
cannot break the caller: a rejected login, a delivery whose dishes all fail
the unit check, and missing credentials each have a test.

One test bug worth noting: the assertion that nothing is logged was missing an
`await` and so was comparing a Future against `isEmpty` -- the single most
important guarantee in this file was passing vacuously until the split forced
it to run.

Test files split three ways for the 250-line cap; block counts checked against
the pre-split file (16 either side), not just a green suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQpCiPaSbyRpwsLkH3dgsX
2026-08-23 08:30:21 +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_spread.dart feat: carry the catering credential to the phone 2026-08-23 08:25:27 +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