docs: refresh CLAUDE.md (beat service, TanStack Query, env vars, no tests)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@ Everything runs in Docker Compose. There is no way to run individual services wi
|
||||
|
||||
The app is served on port 80 by nginx, which proxies `/api/*` to the backend (port 8000) and serves the React SPA for everything else.
|
||||
|
||||
There are no automated tests. Verification is done by running the app and observing behaviour.
|
||||
|
||||
## Building and deploying
|
||||
|
||||
`docker-compose.yml` — build from source (dev/CI).
|
||||
@@ -56,6 +58,7 @@ docker compose -f docker-compose.deploy.yml up -d
|
||||
| `redis` | Celery broker + result backend |
|
||||
| `backend` | FastAPI (async) — uvicorn, single worker |
|
||||
| `worker` | Celery worker — synchronous SQLAlchemy (asyncio incompatible with prefork) |
|
||||
| `beat` | Celery Beat scheduler — runs `sync_all_garmin_connect` every 30 minutes |
|
||||
| `frontend` | React SPA built by Vite at container build time |
|
||||
| `nginx` | Reverse proxy, serves the SPA |
|
||||
|
||||
@@ -69,7 +72,7 @@ docker compose -f docker-compose.deploy.yml up -d
|
||||
- `services/wellness_parser.py` — parses Garmin wellness FIT files (metrics, sleep, HRV, SPO2, etc.)
|
||||
- `services/route_matcher.py` — bounding-box pre-filter + DTW (Dynamic Time Warping) for GPS track similarity
|
||||
- `services/garmin_connect_sync.py` — Garmin Connect API integration; `authenticate_garmin()` tries stored OAuth token first, falls back to email/password; Garmin credentials stored Fernet-encrypted using `SECRET_KEY` as the key
|
||||
- `workers/tasks.py` — Celery tasks: `process_activity_file`, `parse_wellness_fit`, `detect_route`, `compute_personal_records`, `process_garmin_health_zip`
|
||||
- `workers/tasks.py` — Celery tasks: `process_activity_file`, `parse_wellness_fit`, `detect_route`, `compute_personal_records`, `process_garmin_health_zip`, `sync_all_garmin_connect` (beat-scheduled)
|
||||
|
||||
### Key design decisions
|
||||
|
||||
@@ -86,6 +89,7 @@ docker compose -f docker-compose.deploy.yml up -d
|
||||
- `App.jsx` — React Router v6, `RequireAuth` wrapper, all routes defined here
|
||||
- `hooks/useAuth.js` — Zustand store for auth state, reads JWT from `localStorage`, handles PocketID token-in-URL flow
|
||||
- `utils/api.js` — Axios instance with JWT interceptor and 401→redirect handler
|
||||
- TanStack Query (`@tanstack/react-query`) handles all server-state fetching and caching; Zustand is used only for auth state
|
||||
- `utils/format.js` — shared formatting helpers: `formatDuration`, `formatPace`, `formatDistance`, `formatCadence`, `hrZoneColor`, `sportIcon`, `sportColor`, etc.
|
||||
- `pages/` — one file per route; includes `SegmentsPage` for route segment management
|
||||
- `components/activity/` — `ActivityMap` (Leaflet), `MetricTimeline` (Recharts), `HRZoneBar`, `LapTable`
|
||||
@@ -100,9 +104,14 @@ Required in `.env` (or passed to Docker Compose):
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `DATABASE_URL` | Full async DB URL (`postgresql+asyncpg://...`) |
|
||||
| `SECRET_KEY` | JWT signing key — generate with `openssl rand -hex 32` |
|
||||
| `SECRET_KEY` | JWT signing key — generate with `openssl rand -hex 32`; also used as Fernet key for Garmin credentials |
|
||||
| `ADMIN_USERNAME` | Admin account username (default: `admin`) |
|
||||
| `ADMIN_PASSWORD` | Seeds the admin user on first start |
|
||||
| `REDIS_URL` | Celery broker |
|
||||
| `DB_USER` / `DB_PASSWORD` | Postgres credentials (compose-level; default: `milevault`) |
|
||||
| `REDIS_PASSWORD` | Redis auth (compose-level; default: `milevault`) |
|
||||
| `HTTP_PORT` | Host port for nginx (default: `80`) |
|
||||
| `FILE_STORE_PATH` | Where uploaded FIT files are stored (default: `/data/files`) |
|
||||
| `BASE_URL` | Used for PocketID OAuth callback redirect URI |
|
||||
| `VITE_MAPBOX_TOKEN` | Optional — enables satellite tile layer |
|
||||
| `POCKETID_ISSUER` / `POCKETID_CLIENT_ID` / `POCKETID_CLIENT_SECRET` | Optional OIDC |
|
||||
|
||||
Reference in New Issue
Block a user