diet-guard/app/README.md
Krzysztof kuhy Rudnicki b3aeb4f4b7
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (push) Waiting to run
Tests / test (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
Re-point paths for the ~ reorganisation (home-tidy)
Also bumps Flutter 3.47.3, flutter_secure_storage 11.1.0, idb_shim 2.9.9,
mcp 2.2.0 and ruff 0.16.7 so the freshness gate lets this through.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF
2026-09-11 19:53:03 +02:00

76 lines
3.2 KiB
Markdown

# diet_guard_app
Companion app for `diet_guard`: log meals on the phone, and on the Linux
desktop, sharing one food log through GitHub-backed sync.
## Two targets, and only two
| Target | What it is |
|---|---|
| Android | a normal Flutter app (`flutter build apk`) |
| Linux desktop | the Flutter **web** build, served by a local wrapper and shown in a Chrome `--app` window |
There is no `linux/` directory. Flutter's GTK embedder manages ~20fps at
3840x2160 -- measured on a stock `flutter create` counter app, so it is the
toolkit rather than this code -- where the same Dart rendered by Chrome
sustains ~144fps (`~/src/todo/docs/DOCS-desktop-performance-findings.md`). Running
`flutter create --platforms linux` here would silently restore the slow path.
## Commands
```bash
flutter test # the app's suite
flutter analyze
bash run.sh # build the web bundle and launch the desktop app
bash install_arch.sh # build + install the pacman package and .desktop entry
flutter build apk --release # the phone build
adb install -r build/app/outputs/flutter-apk/app-release.apk
```
Never `adb uninstall` or `pm clear` this package: both wipe the on-device log.
## The desktop wrapper
`bin/diet_guard_desktop.dart` is the other half of the desktop app, because a
browser cannot touch the filesystem. It:
- serves the built web assets from `build/web` (or `/opt/diet-guard-app/web`
once packaged);
- keeps an on-disk copy of every document and photo under
`~/.local/share/diet-guard-desktop/`, which is what makes a wiped Chrome
profile recoverable -- for photos it is the *only* copy, since they never
sync;
- holds the GitHub token (`~/.config/diet_guard_app/sync_token`, falling back
to the PC gate's `~/.config/diet_guard/sync_token`) and proxies
`api.github.com` plus the device flow, whose endpoints send no CORS headers
and so cannot be called from a page at all.
**The port (8732) and the Chrome `--user-data-dir` must stay fixed.**
IndexedDB is keyed by origin and lives inside that profile, so changing either
looks to the app like a device with no history.
## Platform seams
`dart:io` does not fail a web *compile*; it becomes a stub that throws at
runtime, so the symptom of a missed seam is a blank white window rather than a
build error. Every platform edge is a conditional export -- `document_store*`,
`blob_store*`, `background_tasks*`, `notification_backend*`, `token_vault*`,
`github_client_factory*`, `attached_image*`. Branch on `kIsWeb` *before* any
`Platform.is…`, which itself throws on web.
What the desktop genuinely loses, by design rather than omission:
- **Background reminders.** A browser runs nothing once its window is closed,
so the due-slot check runs in-page every 5 minutes while the window is open.
On the PC the real backstop is `diet-guard-gate.timer`, which locks the
screen.
- **Camera capture.** The browser picker is a file input.
- **Photo sharing between devices** -- unchanged: `imagePath` was always
stripped before push.
## Sync identity
Three devices push under `diet-guard-sync/devices/`: `pc` (the Python gate),
`phone`, and `desktop`. Each must keep its own id -- two devices sharing one
would overwrite each other's pushed log on every tick.