Files
openrun/NEXT_SESSION.md
noisedestroyers 1b6ad40897 web: surface personal training findings — cadence, fueling
- NatesNotes.md restructured into the personal-findings doc (cadence 170
  target / 161 natural, 80 g carb/h, 3/2 breathing, gait cues, injury log)
- load_activities exposes avg_cadence_spm (summaryDTO.averageRunCadence,
  falling back to Takeout's avgDoubleCadence — full coverage, 342/342 runs)
- load_fit_records: FIT running cadence is single-leg rev/min; now returns
  true steps/min ((cadence + fractional_cadence) * 2)
- Dashboard: cadence trend chart (per-run avg, 28-day mean, 170/161 lines)
  + Cad column in recent activities
- Activity Detail: per-second cadence trace with %time >= 170
- Race Plan: fueling section (carb g/h x est. finish time per race)
- one-time migration: 18 epoch-ms-as-text timestamps -> ISO (P2 item;
  backup at data/backups/garmin-20260612-082025.db)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 08:35:01 -04:00

86 lines
5.2 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`.
- **Personal findings surfaced in UI (2026-06-12)**: NatesNotes.md is the
findings doc (cadence 170/161, 80 g carb/h, 3/2 breathing, gait cues).
Dashboard gained a cadence trend chart + table column; Activity Detail a
per-second cadence trace (FIT cadence is single-leg — load_fit_records now
doubles it); Race Plan a fueling calculator. Targets 170/161 are constants
in the pages — move to openrun.toml when config grows a slot. Still unsurfaced:
walking/time-on-feet (Dashboard filters type='running'; off-watch walking
only exists in daily_steps).
- **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**: the 18 epoch-ms timestamps were migrated to ISO via
one-time UPDATE on 2026-06-12 (they were stored as TEXT like
"1658951176000.0"; backup at data/backups/garmin-20260612-082025.db).
Still to do: normalize on ingest so Takeout re-ingest can't reintroduce
them, utcnow warnings, `schema_version` + tiny migration runner.
- **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`).