Merge branch 'claude/serene-mclean-b76496'

This commit is contained in:
2026-05-18 12:46:29 -04:00
7 changed files with 228 additions and 9 deletions

View File

@@ -275,30 +275,57 @@ HistoryScreen.kt observes captureDao.observeAll() as Flow. Status colored green/
- `7671416` - app.settings needs the SynqApp cast — same as dao. And it's unused in milestone 2 anyway, so just removed it
* milestone 3: android sync
** TODO implement api client
** DONE implement api client
*** acceptance
- base url configurable in app settings or build config.
- bearer token configurable in app settings or build config.
- client can call `/health`.
- client can post capture payload.
** TODO implement manual sync
*** notes
SynqApiClient in data/api/. OkHttp with 10s timeouts. checkHealth() does GET /health, returns false on any exception so callers never crash. postCapture() maps 401 → failed, non-2xx → failed, already_seen → AlreadySeen, else → Accepted. Uses org.json for request building, kotlinx-serialization for tag decoding.
*** evidence
- commit: 2a963d9
- tests: manual — sync now button, check history screen status
- datetime: [2026-05-18 Sun 18:00]
** DONE implement manual sync
*** acceptance
- sync now posts all pending captures.
- successful posts mark rows synced.
- already-seen response marks row synced.
- failures retain pending/failed status and last error.
** TODO implement opportunistic workmanager sync
*** notes
syncPending() top-level function in data/sync/SyncService.kt — shared by manual sync and WorkManager. CaptureViewModel.syncNow() calls it on Dispatchers.IO, guards with isSyncing flag. Sync icon in top bar shows CircularProgressIndicator while running.
*** evidence
- commit: 2a963d9
- tests: manual — tap sync, verify captures move to synced in history; test with wrong token, verify failed + error message
- datetime: [2026-05-18 Sun 18:00]
** DONE implement opportunistic workmanager sync
*** acceptance
- periodic sync is registered.
- sync only runs when network is available.
- worker first checks `/health`.
- worker does not block capture speed.
** TODO add simple server reachability settings
*** notes
SyncWorker (CoroutineWorker) in data/sync/. Registered in SynqApp.onCreate() as KEEP unique periodic work (15-min interval, NETWORK_CONNECTED constraint). Health check before sync — exits quietly if server unreachable. Does not touch UI thread.
*** evidence
- commit: 2a963d9
- tests: manual — let app sit on WiFi, verify pending captures eventually sync without manual trigger
- datetime: [2026-05-18 Sun 18:00]
** DONE add simple server reachability settings
*** acceptance
- default url can be set to `http://jeeves.mother:8765`.
- user can change server url.
- user can change token.
- invalid settings do not crash app.
*** notes
SettingsScreen + SettingsViewModel from milestone 2. DataStore-backed. Default serverUrl is http://jeeves.mother:8765. All network calls wrap exceptions so invalid URL/token never crashes — they just produce PostResult.Failed with the error message.
*** evidence
- commit: 19b05a8 (screen), 2a963d9 (wired to sync)
- tests: manual — set bad URL, tap sync, verify captures stay pending/failed with error; set correct URL + token, sync succeeds
- datetime: [2026-05-18 Sun 18:00]
* milestone 4: polish and hardening
** TODO make launch path fast