SkiPrepCoach is a server-side decision engine that answers one question: what is the best next action for this user right now? The client is thin — it displays the recommended action, collects the result, and sends it back. See Purpose for the full framing.
The engine persists almost nothing on its own: the event log of every action performed is the sole source of truth, and capability score, fatigue, warmth, pain-risk flags, and daily progress are all computed from it on demand rather than stored separately. See Core Principle for why. Time follows the same philosophy: now is always an explicit input, never read ambiently from the system clock, which is what makes the whole pipeline simulatable in tests without waiting in real time.
The spec is split into one file per part, so each can be read, edited, or reviewed independently. There's no section numbering — files are read top to bottom in the order listed below, and every cross-reference is a working link rather than a citation you'd have to go look up.
| File | Covers |
|---|---|
| Purpose | What the engine is and the GET /next → POST /result loop |
| Data Model: User Profile & Capabilities | User profile, capability definitions, derived capability targets, capability state (computed from history, not stored) |
| Data Model: Exercises & Recovery | Movement pattern taxonomy, exercise schema (built on free-exercise-db — exercises don't reference each other, familyId/progressionLevel replace stored substitute/regression/progression lists), prescriptions, recovery classes & fatigue decay |
| Data Model: History & Readiness | Activity history events (the one thing that's actually stored), readiness state, warmth state (general + per-movement-pattern) |
| Server API | GET /next (takes an explicit now), POST /result, logging without a recommendation (onboarding backfill and self-directed exercises), submitting readiness, and GET /state (every intermediate value the next pipeline computes, for debugging and future user-facing state views) |
| Next Decision Pipeline | The full algorithm from loading state to building the explanation |
| Submitting a Result | The one real write (store the event) plus every derivation formula (warmth, fatigue, capability growth, pain risk, variation history, daily progress) |
| Daily Progress | The "have we done enough today" view |
| Initial MVP Exercise Set | The starter exercise list and what's custom vs. free-exercise-db-sourced |
| MVP Development Order | Build sequence |
| Core Principle | The closed-loop philosophy: derived state not stored state, time as an explicit input not an ambient clock read |
| Resolved Parameters Reference | Every constant/formula decided during spec review, in one lookup table |
| Data Layer | PostgreSQL schema (tables, jsonb payloads, indexing), the recursive CTE for capability-score replay, and the decayed-sum queries for fatigue/warmth |
| Server Framework & Deployment | Why Hono over Express, the shared-app-plus-thin-entry-points shape, and how it runs locally, on AWS Lambda, and on Azure |
For a first read-through, follow the table top to bottom — each file links to the next and previous at top and bottom. To work on one part in isolation, jump straight to its file; cross-references to other sections are linked inline.