Initial commit: GPX ride viewer with local-LLM coaching insights
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
uv run uvicorn app:app --reload # start dev server at http://localhost:8000
|
||||
LLAMACPP_BASE_URL=http://host:port/v1 uv run uvicorn app:app --reload # point at a specific LLM
|
||||
uv sync # install/sync dependencies
|
||||
uv add <package> # add a new dependency
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
Two-file app: a FastAPI backend (`app.py`) and a single-page frontend (`static/index.html`).
|
||||
|
||||
**`app.py`** parses all GPX files in `garmin_gpx_exports/` at startup into an in-memory dict (`_rides`), keyed by filename stem. Stats (haversine distance, elevation gain/loss, HR zones) are computed once at load time. Three API routes:
|
||||
- `GET /api/rides` — summary list (no track points)
|
||||
- `GET /api/rides/{id}/points` — full lat/lon/ele/hr array
|
||||
- `POST /api/rides/{id}/insights` — streams AI response via OpenAI SDK
|
||||
|
||||
**AI integration** uses the OpenAI Python SDK pointed at a local LLM endpoint (`LLAMACPP_BASE_URL` env var, defaults to `http://localhost:8080/v1`). The model name is auto-discovered from `GET /v1/models` at startup (falls back to `"local-model"`). The model is a reasoning model (GLM-4.7-Flash alias) that streams output into `reasoning_content` rather than the standard `content` field — the chunk reader handles both.
|
||||
|
||||
**`static/index.html`** is a self-contained SPA (no build step). Leaflet.js draws the route as per-segment polylines colored by HR intensity. Chart.js renders elevation and HR profiles against cumulative distance. AI insights stream via `fetch` + `ReadableStream`.
|
||||
|
||||
**`main.py`** is a separate Garmin Connect download script (not part of the web app).
|
||||
|
||||
## GPX data notes
|
||||
|
||||
- Garmin extension namespace for HR: `http://www.garmin.com/xmlschemas/TrackPointExtension/v1` (`ns3:hr`)
|
||||
- One file (`2026-06-21_18-17-11_Indoor Cycling_*`) has an empty `<trkseg/>` — `has_gps: false` in the API, frontend shows no map/charts for it
|
||||
- HR zone boundaries: Z1 <120, Z2 120–140, Z3 140–160, Z4 160–180, Z5 >180 bpm
|
||||
Reference in New Issue
Block a user