docs: fix stale env-var docs, document validateProfile's zone-range rationale
Two Minor findings from the final whole-branch review: the smartrun-dev skill still told developers to set GARMIN_EMAIL/GARMIN_PASSWORD (now sourced from the profile row instead), and validateProfile's deliberate choice not to require 0-100% HR zone coverage had no explanation.
This commit is contained in:
@@ -75,7 +75,7 @@ Each `workout_kinds.rule_json` is a recursive AND/OR condition tree (`internal/c
|
|||||||
|
|
||||||
## Dev workflow
|
## Dev workflow
|
||||||
|
|
||||||
- Backend: `cd backend && go run ./cmd/smartrund` (needs `MCP_GARMIN_PYTHON`, `MCP_GARMIN_SERVER`, `GARMIN_EMAIL`, `GARMIN_PASSWORD` env vars; see `internal/config/config.go` for all knobs).
|
- Backend: `cd backend && go run ./cmd/smartrund` (needs `MCP_GARMIN_PYTHON`/`MCP_GARMIN_SERVER` env vars for the mcp-garmin subprocess paths; see `internal/config/config.go` for all knobs). Garmin credentials are **not** env vars — they live in the `profile` singleton row (`internal/store.Profile`), set via the frontend's Profile page or directly through `PUT /api/profile`.
|
||||||
- Frontend: `cd frontend && npm run dev` (set `VITE_API_BASE_URL` if the backend isn't on `localhost:8080`).
|
- Frontend: `cd frontend && npm run dev` (set `VITE_API_BASE_URL` if the backend isn't on `localhost:8080`).
|
||||||
- No live Garmin account needed for frontend/UI work: `go run ./cmd/seedsample -db /tmp/sample.db` seeds realistic activities/laps/kinds and runs them through the real classification engine, then point `smartrund` at that DB.
|
- No live Garmin account needed for frontend/UI work: `go run ./cmd/seedsample -db /tmp/sample.db` seeds realistic activities/laps/kinds and runs them through the real classification engine, then point `smartrund` at that DB.
|
||||||
- `internal/garmin/mock` provides a fake `Client` for tests that need to exercise `internal/sync`/`internal/api` without a live subprocess.
|
- `internal/garmin/mock` provides a fake `Client` for tests that need to exercise `internal/sync`/`internal/api` without a live subprocess.
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ import (
|
|||||||
"smartrun/backend/internal/store"
|
"smartrun/backend/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// validateProfile checks the HR zones are ascending and gap-free once they
|
||||||
|
// start, but deliberately does NOT require zone 1 to start at 0% or zone 5
|
||||||
|
// to end at 100%: real Karvonen HR training zones (e.g. the seeded defaults,
|
||||||
|
// 50-60/60-70/70-80/80-90/90-100) don't cover the 0-50% range at all --
|
||||||
|
// below zone 1 simply isn't a named training zone.
|
||||||
func validateProfile(p store.Profile) error {
|
func validateProfile(p store.Profile) error {
|
||||||
if p.RestingHeartRate != nil && p.MaxHeartRate != nil && *p.RestingHeartRate >= *p.MaxHeartRate {
|
if p.RestingHeartRate != nil && p.MaxHeartRate != nil && *p.RestingHeartRate >= *p.MaxHeartRate {
|
||||||
return errors.New("resting heart rate must be less than max heart rate")
|
return errors.New("resting heart rate must be less than max heart rate")
|
||||||
|
|||||||
Reference in New Issue
Block a user