Tracking app requirements (TRK-*)
@enode/tracking — the coach-facing "Pro app" for running enode
velocity-based training sessions, shipped as a Capacitor iOS/Android app and
PWA. Shared behavior (auth flow, i18n, units, error engine) lives in
shared.md; this catalog only states what is specific to the app.
See the overview for the ID scheme and status legend. Test
cases: tracking-system-tests.md.
Areas: AUTH · SCHED (today's schedule) · STATION (multi-station shell) ·
WORKOUT (start & pre-start editing) · LIB (template library & sharing) ·
LIVE (sensors & live tracking) · VIDEO · INSIGHT · FINISH · OFFLINE ·
SET (settings) · PLATFORM.
Auth & entry (TRK-AUTH)
| ID | Requirement | Status | Tests |
|---|
| TRK-AUTH-01 | Sign-in and registration use the shared Pro auth flow (SHR-AUTH-01..03); on success an animated transition lands on /workouts/today. | stable | TRK-ST-1.1 |
| TRK-AUTH-02 | A "One" user attempting to sign in is blocked (backend 314) with a message directing them to the One app. | stable | TRK-ST-1.2 |
Today's schedule (TRK-SCHED)
| ID | Requirement | Status | Tests |
|---|
| TRK-SCHED-01 | The today pane lists the current week's scheduled and recurring workouts for the signed-in coach. | stable | TRK-ST-2.1 |
| TRK-SCHED-02 | Pull-to-refresh reloads the schedule. | stable | TRK-ST-2.2 |
| TRK-SCHED-03 | An empty day shows an explicit empty state; a failed load shows a "Try again" state that recovers on retry. | stable | TRK-ST-2.3, TRK-ST-2.4 |
Stations (TRK-STATION)
| ID | Requirement | Status | Tests |
|---|
| TRK-STATION-01 | The training shell supports multiple parallel stations: one full-viewport station on phones, up to three columns on tablets. | stable | TRK-ST-3.1 |
| TRK-STATION-02 | The user can open and close stations from the rail/spine sidebar; closing stations that no longer fit asks for confirmation. | stable | TRK-ST-3.2 |
| TRK-STATION-03 | The number of stations allowed to record is licensed via the device-session weight; over-limit stations show a "request another slot" overlay instead of recording. | stable | TRK-ST-3.3 |
| TRK-STATION-04 | An athlete-role user is limited to a single station. | stable | TRK-ST-3.4 |
Starting & editing workouts (TRK-WORKOUT)
| ID | Requirement | Status | Tests |
|---|
| TRK-WORKOUT-01 | From the FAB the user can start a scheduled workout, create a new workout from scratch, or start from a template via the Library. The Library is the FAB's only template entry — there is no second flat start picker. | stable | TRK-ST-4.1..4.3 |
| TRK-WORKOUT-02 | Before starting, the workout can be edited in the prep drawer: participants, tags, exercises and supersets, notes. | stable | TRK-ST-4.4 |
| TRK-WORKOUT-03 | A feedback-only (sensor-only, no plan) training can be started. | stable | TRK-ST-4.5 |
| TRK-WORKOUT-04 | A past workout can be logged after the fact (retrospective input): pick a source workout, fill in sets, upload through its own path. Flag: RETROSPECTIVE_INPUT (on). | flag | TRK-ST-4.6 |
| TRK-WORKOUT-05 | A licence-blocked athlete can be added to a workout and is shown as a participant, but no data is ever recorded for them: the athlete picker warns before they are added, their chip is badged, and they never appear in the in-session athlete switcher. A workout whose participants are all blocked can't be started. | stable | TRK-ST-4.7, TRK-ST-4.8 |
Template library & sharing (TRK-LIB)
Sharing model: sharing.md.
| ID | Requirement | Status | Tests |
|---|
| TRK-LIB-01 | The template Library opens as a drawer from the create FAB, the sidebar panel and the collapsed sidebar spine. It lists the coach's own workout templates and the ones colleagues share with them, and is the single template surface in the start flow (TRK-WORKOUT-01). | stable | |
| TRK-LIB-02 | A Mine / Internal / Public segmented picker scopes the list. It is shown only when the loaded feed can actually fill more than one segment — with nothing shared, the Library is a flat list of the user's own templates. | stable | |
| TRK-LIB-03 | A template the user does not own is marked with its reach glyph (building = internal, globe = public) and the author's name when the backend supplies one; without a name the badge degrades to icon-only. | stable | |
| TRK-LIB-04 | Search matches a template's name, its tags and the names of the exercises it contains, so a shared template can be found by its content rather than its title. An empty result offers "did you mean" suggestions. | stable | |
| TRK-LIB-05 | Tapping a template opens a read-only detail view: provenance, note, tags and the exercise list. Nothing on it is editable. | stable | |
| TRK-LIB-06 | The detail view's only action is Use template, which closes the Library and opens the normal prep drawer on an editable copy of it — deliberately not called "Start", since the actual start is the prep drawer's own button. There is no "Save a copy" — the tracking app never adds to the user's own template list; that is portal work. On a tablet, opening the Library from a station column prepares the workout in that column. | stable | |
| TRK-LIB-07 | A template that stops being shared while the detail view is open flips to a "No longer shared" notice with Start and Save disabled, instead of blanking or failing silently. | stable | |
| TRK-LIB-08 | Templates are not part of the offline snapshot: with no cached list and no connection the Library states that plainly; with a warm cache and a failed refresh it shows a staleness hint over a usable list. | stable | |
Sensors & live tracking (TRK-LIVE)
BLE integration details: ble.md.
| ID | Requirement | Status | Tests |
|---|
| TRK-LIVE-01 | The user can connect one or two enode SmartBar sensors to a station; pairing status is visible and a placement prompt guides sensor positioning. | stable | TRK-ST-5.1, TRK-ST-5.2 |
| TRK-LIVE-02 | During a set, reps are detected live from the sensor stream and shown as they happen (pending-rep overlay/flash). | stable | TRK-ST-5.3 |
| TRK-LIVE-03 | Live feedback shows the configured focus metric and a rest timer between sets. | stable | TRK-ST-5.4 |
| TRK-LIVE-04 | Completing a set opens the complete-set sheet with detected reps, load, measurement values, and rest target; values are editable before saving. | stable | TRK-ST-6.1 |
| TRK-LIVE-05 | The user can edit a participant's 1RM in-session, including bodyweight-based exercises. | stable | TRK-ST-6.2 |
| TRK-LIVE-06 | Sets can be moved/reordered within the session via drag & drop. | stable | TRK-ST-6.3 |
| TRK-LIVE-07 | The session can recommend switching exercise or stopping for rest based on performance. Flag: SWITCH_RECOMMENDATIONS. | flag | TRK-ST-6.4 |
| TRK-LIVE-08 | Rep feedback can be spoken aloud via text-to-speech, in both active training and feedback training. Switched on per device in the Local settings sheet. Flag-gated. | flag | TRK-ST-6.5, TRK-ST-6.8 |
| TRK-LIVE-11 | Exactly one station speaks at a time: a speaker symbol marks the station that owns the voice, tapping a muted one moves it, and the sole active station owns it without a tap. | stable | TRK-ST-6.8 |
| TRK-LIVE-09 | A muscle-quality body view visualizes muscle load quality during the session. | stable | TRK-ST-6.6 |
| TRK-LIVE-10 | Technique feedback mode shows the latest rep's sagittal + frontal bar path next to the focus-metric values, both over the camera and without it. Reps that carry no bar path (flywheel, or a missing raw-data stream) omit the trajectory instead of drawing an empty grid. | stable | TRK-ST-6.7 |
Video (TRK-VIDEO)
See video-recording.md.
| ID | Requirement | Status | Tests |
|---|
| TRK-VIDEO-01 | The user can record video clips of sets with the native camera overlay during a session. | stable | TRK-ST-5.5 |
| TRK-VIDEO-02 | Recorded clips can be reviewed in-session with a scrubbable player. | stable | TRK-ST-5.6 |
Insights (TRK-INSIGHT)
| ID | Requirement | Status | Tests |
|---|
| TRK-INSIGHT-01 | The insights sheet shows an Overview tab summarizing the session. | stable | TRK-ST-7.1 |
| TRK-INSIGHT-02 | The Performance tab charts per-metric / per-rep values for the session. | stable | TRK-ST-7.2 |
| TRK-INSIGHT-03 | The Technique tab shows orientation/velocity traces; 3D force vectors are flag-gated (FORCE_VECTORS). | flag | TRK-ST-7.3 |
| TRK-INSIGHT-04 | While history/metrics load, the insight tabs render placeholder skeletons (SKELETON_PREVIEW) — these are visual placeholders, not real data. | mocked | — (known behaviour) |
| TRK-INSIGHT-05 | The Technique tab opens on the most recently recorded set and follows every newly recorded set, so the split-view detail pane (tablet) stays on the set that just finished. | stable | TRK-ST-7.6 |
Finishing (TRK-FINISH)
| ID | Requirement | Status | Tests |
|---|
| TRK-FINISH-01 | Finishing a training opens the set-review overlay where results are confirmed. | stable | TRK-ST-7.4 |
| TRK-FINISH-02 | Confirmed results are persisted to the backend (queued offline if needed) and appear in history/portal afterwards. | stable | TRK-ST-7.5 |
| TRK-FINISH-03 | Finishing with no completed sets asks for confirmation first — it uploads nothing and tears the station down like a discard, and the workout composition is never persisted server-side, so it would otherwise be lost silently. | stable | TRK-ST-7.7 |
| TRK-FINISH-04 | The "Keep sensor connected?" prompt can always be backed out of (the corner close ✕, backdrop, Escape, hardware Back), returning to the training with nothing torn down. | stable | TRK-ST-7.8 |
Offline & recovery (TRK-OFFLINE)
See offline-and-sync.md and ADR
0002-offline-training-persistence.
| ID | Requirement | Status | Tests |
|---|
| TRK-OFFLINE-01 | Losing connectivity shows the offline banner; cached "offline-ready" day bundles let cached workouts start with no network. | stable | TRK-ST-8.1, TRK-ST-8.2 |
| TRK-OFFLINE-02 | Trainings completed offline are queued and uploaded automatically on launch, foreground, or reconnect; a pending-uploads indicator shows queued items. | stable | TRK-ST-8.3 |
| TRK-OFFLINE-03 | After a crash or force-kill mid-training, relaunching offers to resume the interrupted training with its state restored. | stable | TRK-ST-8.4 |
| TRK-OFFLINE-04 | Navigating back mid-training prompts a discard confirmation instead of silently leaving the session. | stable | TRK-ST-8.5 |
Settings (TRK-SET)
| ID | Requirement | Status | Tests |
|---|
| TRK-SET-01 | Settings and profile drawers are reachable from the station spine/header; the app version is displayed. | stable | TRK-ST-9.1 |
| TRK-SET-02 | Unit system and language switching per SHR-UNITS / SHR-I18N apply throughout the app. | stable | TRK-ST-9.2, TRK-ST-9.3 |
| TRK-SET-03 | A cross-app link to the enode Portal exists but is hidden. Flags: PORTAL_LINK_ENABLED = false, PORTAL_WEBVIEW_ENABLED = false. | flag (off) | — |
| ID | Requirement | Status | Tests |
|---|
| TRK-PLATFORM-01 | The screen stays awake during an active training session. | stable | TRK-ST-10.1 |
| TRK-PLATFORM-02 | The app runs as a standalone PWA / Capacitor app with iOS safe-area handling; API calls go through the native HTTP stack in the shell. | stable | TRK-ST-10.3 |
| TRK-PLATFORM-03 | Debug screens (/debug/*) are unavailable in production builds (NEXT_PUBLIC_ENABLE_DEBUG_VIEW off → 404). | stable | TRK-ST-10.4 |