Files
openrun/NEXT_SESSION.md
noisedestroyers 87f73ad36b web: port Sync page login + sync to garminconnect backend
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>
2026-06-12 07:38:50 -04:00

75 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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, run
`git 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). `gitlab` remote URL typo
(ttps://) fixed. `scripts/backup_db.sh` snapshots the DB, keeps 14.
- DB: `garmin/data/garmin.db` is 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 17Jun 2, epoch-ms
timestamps, no FITs). Copied to
`data/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.py` now authenticates with
python-garminconnect 0.3.5 DI tokens (`.secrets/garmin_tokens.json`) and
shims garth's client surface; `openrun-sync --backend=auto` prefers 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 run` is single-process; secrets must stay server-side).
- `race_plan` table is EMPTY and `manual_activities` empty, 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 in `src/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 populate `race_plan` through 2026-09-12
using `banister_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 as
`openrun-sync --backend=garminconnect` instead 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_gain` already in schema, unused).
- Sync automation (launchd/cron weekly `openrun-sync`).