garminconnect_backend gains web-friendly auth: resume() (token restore with API validation), begin_login()/complete_mfa() (two-step MFA handshake via return_on_mfa), user_label(), and patch_garth() split out of activate(). 5_Sync.py drops the garth login flow (Cloudflare-blocked) for the new backend; the authenticated client is cached in st.session_state. Verified headlessly with streamlit AppTest: token restore, sync-button click, full incremental sync, no exceptions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4.4 KiB
4.4 KiB
Session handoff — 2026-06-12
Working plan agreed with the user: step through P0→P4 below, in order. Read this file instead of re-exploring the repo; README.md + ROADMAP.md cover architecture and conventions. Delete this file when the list is done.
State (verified 2026-06-12, P0 session)
- All 111 tests pass (
uv run pytest). - P0 DONE (commit
6df25bcd, NOT yet pushed — push denied to agent, rungit push origin main): .gitignore fixed and Takeout dump (23,673 files, personal health data) untracked; note it is still in remote history from earlier pushes — rewrite history if that ever matters. CI added at.gitea/workflows/test.yml(remote g.o00.io is Gitea — Actions must be enabled repo-side with a registered runner).gitlabremote URL typo (ttps://) fixed.scripts/backup_db.shsnapshots the DB, keeps 14. - DB:
garmin/data/garmin.dbis canonical — 378 activities (→ 2026-05-10), 349 FITs linked, wellness through 2026-05-17. - The stray
../data/garmin.db(vault root) was a Takeout-ZIP ingest run from the wrong cwd on 2026-06-08 (7 extra activities May 17–Jun 2, epoch-ms timestamps, no FITs). Copied todata/backups/vault-root-takeout-ingest-2026-06-08.db; the original at../data/is redundant once live sync runs — user should delete it. - SYNC DONE (2026-06-12) via new garminconnect backend. garth's SSO login
is Cloudflare-429-blocked AND garth is deprecated (matin/garth#222), so
src/openrun/ingest/garminconnect_backend.pynow authenticates with python-garminconnect 0.3.5 DI tokens (.secrets/garmin_tokens.json) and shims garth's client surface;openrun-sync --backend=autoprefers it. This is P3-lite, pulled forward. Login (once/year-ish):uv run python -m openrun.ingest.garminconnect_backend. Gotchas learned: usersummary endpoint needs UUID displayName, not userName (403 otherwise); a parseable-but-dead tokenstore blocks the password fallback in gc.login (main() parks it as .bak first). - DB after sync: 385 activities (→ 2026-06-02), all ISO timestamps on new rows, 356 FITs linked, 364 TIZ rows, wellness through 2026-06-12. The 18 legacy epoch-ms rows remain (P2).
- Web Sync page ported to the gc backend (same session): login + MFA
round-trip + sync button all run on garminconnect; verified headlessly via
streamlit AppTest (login restore, button click, full sync, no exceptions).
openrun.ingest.auth(garth) remains only for--backend=garth. - New goal (user, 2026-06-12): shareable web UI — let others run the
openrun web app against their own Garmin account. Known gaps: per-user
token store + DB (everything is cwd-relative single-user today), per-user
openrun.toml (zones/races — openrun-init helps), and deploy story
(
streamlit runis single-process; secrets must stay server-side). race_plantable is EMPTY andmanual_activitiesempty, but openrun.toml has races: 30K 2026-06-13, 50K 2026-07-25, 50 MILE 2026-09-12.- Known bugs: 18 activities have epoch-ms floats in
start_time_local(should be ISO strings) — normalize on ingest + one-time migration;datetime.utcnow()deprecation warnings insrc/openrun/ingest/garmin_api.py.
Plan
- P0 — protect the work: .gitignore, private remote, CI running pytest, pick canonical DB + backup story. (commit done)
- P1 — use it for the ultra build: live sync (
openrun-auth+openrun-sync, fall back to../garmin-pgc/python-garminconnect backend if garth hits Cloudflare 429), then populaterace_planthrough 2026-09-12 usingbanister_forecast+calibrate_tl_per_km; log off-watch work. - P2 — data quality: fix the 18 mixed-format timestamps, utcnow warnings,
add
schema_version+ tiny migration runner before any public release. - P3 — merge sync fork: fold
../garmin-pgc/into openrun asopenrun-sync --backend=garminconnectinstead of a sibling project. - P4 — roadmap items reordered for the ultra: TrainingReadinessDTO + RunRacePredictions ingest (ROADMAP 1.2), route map (3.2). Defer DBSCAN, multi-athlete, distribution until after September.
Gaps identified (not yet scheduled)
- Subjective data: RPE/soreness/injury notes (user hand-writes these in ../RunningLogs.md; March right-leg injury) — tie into DB, plot vs ACWR/TSB.
- Ultra metrics: weekly vert, time-on-feet, back-to-back long-run detection,
grade-adjusted pace (
elevation_gainalready in schema, unused). - Sync automation (launchd/cron weekly
openrun-sync).