Skip to main content

enode Tracking app — features & use cases

@enode/tracking is the coach-facing training app: the screen a strength & conditioning coach holds on the gym floor while athletes train with enode velocity sensors. It plans nothing and analyses nothing after the fact — that is the portal's job. This app owns the session: connect a sensor, watch reps arrive live, decide the next load, record the set, and get the result safely to the backend.

This page describes the product. For the testable, ID'd statement of the same scope see tracking app requirements; for the manual protocol that exercises it see tracking system tests.

At a glance

Who it is forStrength & conditioning coaches, team staff, testing/rehab practitioners, and individual athletes
PlatformsNative iOS and Android (Capacitor shell) and installable PWA — one codebase, static export
Hardwareenode velocity sensors over Bluetooth LE, including SmartBar dual-sensor pairs; also Apple Watch, phone, and pure manual entry
Works offlineYes — a downloaded training day starts, records and finishes with no network
BackendThe enode API; the app is a client, never a server

1. Core concepts

Five nouns explain most of the UI.

  • Workout — the plan: which exercises, in which order, for which athletes. It comes from the portal's schedule, from a template, or is built ad hoc.
  • Session — one athlete's execution of one workout item. Sessions key off the workout item, not the exercise, so the same exercise twice in a plan stays two independent slots.
  • Set — one bout of work: load, reps, measurement values, warm-up vs working, tracked side (bilateral / left / right), an optional video clip, a note, tags, and the copied prescription (intensity / exertion / rest).
  • Rep — one repetition as the sensor recorded it: concentric and optionally eccentric phase, each with a full raw trajectory from which every metric is derived, plus a validity flag.
  • Station — one training slot on screen: an athlete, an exercise, and optionally a sensor. A tablet runs up to three in parallel; a phone runs one.

Two rules shape a great deal of behaviour:

  • The focus metric is the single headline number per session, resolved from the exercise and equipment group — 1RM for strength, peak force for strength on a flywheel, top load for weightlifting, jump height for jumps. Live readouts, spoken feedback, charts and summaries all orient around it.
  • Invalid reps are always visible and never counted. A rep the validator or the coach rules out keeps its place and its number in every list, chart and timeline — muted — but contributes to no count, mean, estimate or export. See invalid reps.

2. Feature areas

2.1 Access, accounts and roles

  • Passwordless email + one-time-code sign-in. The code auto-submits on the last digit; a stored token means a returning coach lands straight in the session screen on cold start.
  • Sign-in and sign-up are separate flows so a typo cannot silently create a duplicate account; picking the wrong one offers a one-tap switch.
  • Pro-only deployment. A legacy One account is blocked at sign-in with a pointer to the One app. Registration (organisation name + email) works in-app, and legacy accounts can start a migration.
  • Roles — owner, administrator, coach, athlete. An athlete-role user is auto-selected as the sole participant, sees no athlete-editing affordances, and is pinned to one station.
  • Privilege-aware UI — the backend's privilege catalogue (data export, raw data, planner write, custom charts, firmware update, …) gates the affordances that need it.
  • Guided redirects. Device-session limits, pending invitations and incomplete onboarding are resolved through dedicated dialogs, not a raw error code.
  • OTP-protected account deletion from the profile drawer.

Use case — a coach picks up the gym's shared tablet, signs in with their email and the code from their inbox, and is on today's schedule in under a minute.

2.2 Today's schedule

The landing surface lists the week's workouts for the signed-in coach, bucketed by day with today labelled first, then sub-grouped by time of day ("all day" pinned ahead of the timed buckets). The workout closest to the current time is highlighted.

  • Pull to refresh, or the sidebar's Refresh row, picks up a workout just scheduled in the portal.
  • An empty day says so explicitly; a failed load offers Try again rather than a blank screen.
  • An offline-ready chip tells the coach, before they walk into a basement gym, whether that day will start without signal — and downloads it on tap.

2.3 Starting a training

From an empty station — the workout list, its menu and its actions — the coach can:

EntryWhat it is for
Start a scheduled workoutThe normal path — the plan the portal already holds
Create a new workoutNothing was planned; build it on the spot
Select a workout templateClone a saved session structure
Feedback trainingSensor-only work with no plan at all (§2.8)
Log past workoutRetrospective entry for a training that already happened (§2.12)

The prep drawer is where a workout is shaped before it starts: name it, pick athletes, add and reorder exercises, edit each item's blocks (volume, intensity, exertion, set count), multi-select several items and edit their blocks together, and add notes and tags. Mismatched selections are explained rather than silently merged — "can't edit together" for incompatible exercise groups, and a destructive confirm before shared blocks overwrite individual ones. Closing with unsaved edits prompts to discard.

Exercises are found with multi-token search plus a typo-tolerant "did you mean?" fallback, and can be starred as favourites.

Pressing Start verifies a recording slot is free, then commits the training view behind the drawer so the drawer's slide-out reveals it, instead of a hard screen cut.

Licence-aware participation. An athlete whose licence blocks recording can still be shown as a participant — the picker warns first, their chip is badged, and they never appear in the in-session athlete switcher, so no data is ever recorded for them. A workout whose participants are all blocked cannot be started. Athletes archived in the portal disappear from every live surface, and athletes whose exercises aren't cached are flagged before an offline start.

Use case — a scheduled team session runs, but two athletes swap in at the door. The coach opens the prep drawer, replaces the participants, adds a superset for the accessory block, and starts — the plan on the server is untouched.

2.4 Stations — one screen, several athletes

The training shell is device-aware:

  • Phone — one full-viewport station.
  • Tablet — up to three station columns side by side, each fully independent (own workout, own sensor, own drawers). Columns snap-scroll when they overflow, and columns that no longer fit are flagged with a guarded "close hidden stations?" action.
  • The last station can never be closed — it falls back to the schedule view.

A spine/rail sidebar collapses to icons and expands to a panel, holding Settings, Refresh, Open new station, Load workouts for offline, Manage stations, Pending uploads, Profile, and (in development builds) the debug area.

Recording slots are licensed. The device session carries a weight granting how many stations may record; the rest are feedback-only. An empty column past the limit offers Request station slot, and a station that becomes over-limit gets a blocking overlay with Request slot / Finish & save / Discard. Athletes are always pinned to one recording slot.

A sensor can be owned by the station rather than by a session, so it survives finishing one athlete and starting the next — the "keep connected?" prompt at finish defaults to keeping it.

Use case — three lifters rotate through a squat rack, a trap-bar deadlift and a jump station on one iPad. Each column tracks its own athlete; the coach taps between them without disconnecting anything.

2.5 Sensors, placement and calibration

Full technical detail lives in BLE & sensors.

One connect flow on every platform — Web Bluetooth in the browser, native CoreBluetooth/GATT on iOS and Android — with distinct Searching and Connecting phases, live signal strength where the platform allows it, and cancel at any point. Bluetooth being switched off is detected before scanning, so the sheet says "turn Bluetooth on" instead of timing out into "no sensor found".

What can be tracked from:

SourceNotes
Single enode sensorStreams motion at ~50 Hz plus a rep-end event per rep
SmartBar pairTwo sensors on one bar become one logical unit; sides assignable, swappable and removable; one sensor alone still works
Apple Watch / phoneAlternative tracking sources per exercise
Manual entryNo hardware at all

The connect sheet searches with a looping "bring your sensor to the device" animation that cross-fades into a live 3D view of the connected sensor, and from there the coach can see battery and calibration state, recalibrate, add a second SmartBar side, assign an already-connected sensor to this station, swap sides, stop an auto-reconnect, or disconnect. It opens both from an active training and from an empty station column, so pairing can happen before the workout does.

The connect pill shows state at a glance: the enode mark when nothing is paired, a sensor silhouette with battery for a single sensor, a bar badge with left/right battery for a SmartBar, and a red corner badge when the link is weak.

Where the sensor goes. A placement card is resolved from the exercise's equipment — barbell, bar-end sensor, wrist (dumbbell/kettlebell), body/hip (bodyweight), weight stack (cable/machine), flywheel — with an illustration and the sensor glowing in position, shown once per placement per workout. A bar sensor guard shows a non-dismissible "incompatible" card and stops rep capture when a SmartBar is on a non-barbell exercise.

Training modes. The sensor is configured per exercise: strength, weightlifting, flywheel, jump squat, counter-movement jump, drop jump, plus raw / science modes and a selectable low-pass filter.

What each mode measures:

ModePer-rep metrics
Strength / weightliftingDuration, distance, mean velocity, mean propulsive velocity, velocity of movement, peak velocity, peak power, peak RFD
FlywheelDuration, distance, mean & peak velocity, mean & peak power, mean & peak force
JumpsDuration, jump height, peak velocity, peak RFD, peak power; CMJ/squat jump add RSI-mod, drop jump adds RSI and contact time
Eccentric phaseDuration, distance, mean & peak velocity, peak RFD

Link health and recovery.

  • Auto-reconnect — an involuntary drop keeps the sensor in the pool as reconnecting and re-searches for the same device for 60 s, then re-wires the existing sensor so session state survives. A deliberate disconnect does not trigger it.
  • Weak-connection warning — per-sensor throughput is measured against the nominal 50 Hz; a sustained shortfall flags the link, so the coach knows the radio is saturated rather than guessing.
  • Live device readouts — battery, signal strength, temperature, firmware and hardware revisions, and an explicit "sensor API too new for this app" signal.
  • Reassignable without reconnecting — sensors live in a pool, so one (or a whole SmartBar pair) can move between stations mid-session.
  • Steady-state detection — the app knows when the bar is at rest, and drives a "sensor ready / wait after impact" state from it.
  • Durable rep buffering — unsaved reps are parked per station × item × athlete, so a crash or an athlete switch cannot lose them.

Calibration — a six-face routine with a live 3D sensor view that highlights the face currently pointing down and remembers which faces are done.

Use case — mid-set a sensor drops out of range. The station shows "reconnecting" rather than pretending to record; when it comes back the coach finishes the set with the reps that were captured.

2.6 The tracking view

Opening an exercise gives a per-exercise sheet with:

  • a sticky header card — exercise name, athlete avatar, focus-metric value and the rest timer;
  • the athlete switcher (tap the avatar) to rotate through everyone with a session for this item, and the exercise switcher (tap the title) to jump to another item keeping the current athlete;
  • the item note and session tags, and a per-side toggle for unilateral work;
  • the set list;
  • a floating card stack for recommendations, load advice and the load bar;
  • a camera button (bottom-left) and an Insights button (bottom-right);
  • an options menu.

The options menu holds: focus-metric selection, feedback mode (metric / muscle quality / technique, remembered per exercise group), a sensor distance threshold override, voice feedback, single-rep review, show eccentric reps, and the set-summary confirmation step.

Split detail mode. On a wide enough column, Insights renders inline beside the tracking pane instead of as a bottom sheet.

2.7 Live tracking

While a set is running:

  • Reps appear as they happen — a live overlay flashes each rep with its focus-metric value the instant the sensor reports it, over a stats row.
  • A live RIR / exertion readout estimates how close the athlete is to failure from the velocity trend, without needing a stored 1RM.
  • A set-end threshold indicator turns the card negative when the prescribed stop criterion (e.g. velocity loss) is met.
  • An inactivity countdown can auto-confirm the set; otherwise the coach ✓ commits or ✗ discards.
  • A rest timer counts down to the recommended rest target (from the block's prescription or the rest estimator) or up from the last set — tap to flip, and the choice is remembered. The countdown turns red at zero.
  • An optional set-summary step lets the coach review the draft set before it commits, invalidating or deleting reps first. A new rep arriving while the summary is open auto-commits and resumes recording, so hesitating loses nothing.

Feedback modes change what the athlete-facing body shows:

ModeShows
MetricA focus-metric grid — the latest value per metric and its drop from the set's best
Muscle qualityA stimulus ring splitting the set into power / hypertrophy / strength, a ranked list, a set-capacity bar and a per-rep bar chart
TechniqueSagittal and frontal bar path, two focus metrics, and a velocity/acceleration dual-axis chart

Spoken feedback (single-station only) reads each rep's focus-metric value aloud in the app's language — "0.45 meters per second", with the unit only on the first rep of a set. It respects the phone's silent switch and never delays a rep. See voice feedback.

The screen stays awake for as long as any station is live.

Use case — velocity-based training. The bar-speed target is 0.75 m/s; the coach hears the app call each rep and stops the set the moment the threshold indicator turns.

2.8 Feedback training — sensor-only, no plan

A separate flow for pure live feedback with no workout behind it: pick a configured feedback mode, connect a sensor, and train. The same live rep overlay drives capture; sets accumulate in a transient list (newest first, capped) and are never uploaded. Each station runs its own independent feedback flow, and it works even on a device with no recording slots left.

Use case — an athlete drops in for a quick jump test between sessions. The coach opens feedback training, taps CMJ, and reads the numbers off the screen — nothing is scheduled, nothing is stored.

2.9 Planned sets, warm-ups and progression

The app materialises the plan into concrete sets ahead of the athlete:

  • Prescribed sets are built from the block's normatives plus the athlete's known 1RM and shown as template rows, with velocity targets and the set-end stop criterion surfaced as cues.
  • Automatic warm-up ramp — a decaying step model climbs from the current or starting load to the first working set's load, and stops once working sets begin. Gated on the coach's warm-up-guidance setting.
  • Unilateral exercises expand one prescribed set into a Left slot then a Right slot; the pair counts once toward progress.
  • The set list shows a timeline — completed sets checked, the active set marked, templates hollow — with per-set focus-metric bars and a "schedule completed" banner once the prescribed working sets are done.
  • Initial load suggestion for a first-ever set, with dedicated paths for jump exercises and flywheel equipment and sensible floors for bodyweight and dumbbell work.
  • The scheme rebuilds automatically whenever the 1RM, the blocks or the unilateral setting change.

2.10 Completing and editing a set

Finishing a set opens the complete-set sheet, pre-filled with what the sensor detected: reps, load, exertion and the rest target, with a suggested RIR from the coaching engine. Everything is editable before saving; the same sheet edits an already-completed set.

  • A numeric metric keyboard built for the gym replaces the OS keyboard for every measurement field on touch devices — per-metric layouts for load, velocity, percentage, reps, RIR, drop and mm:ss times, the decimal key hidden where the metric is an integer, a "6+" overflow bucket for bounded metrics like RIR, and an accessory bar to step between grouped fields. Optional normatives (exertion, rest) can be cleared outright.
  • A velocity-profile strip inside the load keyboard shows the predicted velocity at a load, its %1RM placement, and the peak-power and peak-load zones — and doubles as a draggable load slider.
  • Load stepping — a floating − / + pill with a fine increment under 20 kg and a coarse one above; tapping the value types an exact load. Advised loads snap to increments a real barbell can be loaded to. Flywheel work takes an inertia value instead of a mass.
  • Bodyweight-relative loading — bodyweight exercises display and accept load as a delta ("BW", "BW +10 kg"), while storage stays absolute.
  • Per-rep control — expand the reps card, multi-select reps, and toggle them valid or delete them. The coach's override always beats the automatic validator.
  • 1RM editing in-session — tap the 1RM stat and the metric keyboard opens with a "reset to automatic value" action; an overridden value is marked.
  • Tags and notes at workout, session, set and rep level. Session-eligible tags cascade from the workout down and back out again when removed.
  • Move a set to another item and athlete (only where equipment and exercise group match); both source and destination schemes rebuild. Exchange the exercise mid-session, and the sessions re-point — 1RM baseline, models and set scheme follow; slots with completed sets only offer similar exercises.
  • Deleting a set also drops its recorded video.

2.11 Coaching intelligence

The coaching math runs on the device, ported from the iOS coaching core.

CapabilityWhat the coach gets
1RM estimationA confidence-fused estimate across the session's sets, a momentary 1RM from the latest set, and a synthetic pre-rep estimate from load, exertion and rep count that drives live load advice. Outlier reps are cleaned out first.
Exertion / RIRReps-in-reserve estimated three ways — from %1RM, from the load–velocity profile, and from a 1RM-independent mean-velocity exertion profile — then fused. Also powers the "target RIR reached, end the set" criterion.
Automatic rep validationAfter a tracked set, border reps that deviate in distance or velocity, and reps whose raw trajectory shape deviates from the set's mean (compared over vertical position, so it is tempo-invariant), are flagged — never deleted.
Capacity indexA "how hard was that set" score from velocity loss, rep count and estimated loading.
Muscle stimulusSplits the set into competing power / hypertrophy / strength scores — the Muscle-Quality feedback mode.
Rest recommendationA model over the last and next set's %1RM and the last RIR, clamped to a sane range, feeding the rest timer's target.
Technique analysisPer-rep phase segmentation (lowering / braking / pause / propulsive / deceleration for strength; unweighting / yielding / braking / propulsive / flight / falling for jumps), plus bar path, inclination/rotation, velocity, acceleration, power and force traces.
Dual-sensor fusionTwo SmartBar trajectories are resampled, rotated into a shared frame, validated against the bar geometry and merged — the result is indistinguishable from a single-sensor rep downstream.

Three recommendation cards surface this during a session, each dismissible and none of them ever acting on its own:

  • Load advice — the scheme's recommended load for the active set, shown only when it differs meaningfully from what is on the bar; tap to accept.
  • Rest / velocity stop — during rest, a soft "consider ending this exercise" when the velocity kill switch fires.
  • Switch recommendation — after each set, the next move: rotate to the next athlete, advance to the next exercise, a two-option choice inside supersets, an "exercise complete" card, or "workout finished".

Load and switch advice respect the coach's AI-guidance settings.

Use case — testing day. The coach works up in load; after each set the app posts an updated 1RM estimate and an RIR reading, and eventually recommends stopping before a genuine failure attempt.

2.12 Retrospective entry — logging a past workout

A separate, self-contained flow for a training that already happened: choose a source (a scheduled workout this week, a template, or a new one), set the start date and time, then fill in each exercise card. A per-exercise rest value drives the set timestamps, so one start time reconstructs a plausible session clock. Rows are seeded from the prescribed working sets and the athlete's 1RM, rounded to loadable bar increments, with inline reps / load / RIR cells, per-set notes, tags and removal, and independent entries per athlete. Upload builds the same wire payload as a live finish. Exiting with data prompts to discard.

2.13 Video

See set video recording.

  • Record a clip per set from a native camera overlay, with the live rep feedback cards drawn over the preview. Available while a sensor is connected; only one station can hold the camera at a time.
  • Front/back camera switchable before the first rep, and a shutter toggle between auto and a fast (1/500 s) exposure for crisp bar-path frames.
  • Frame-accurate sync. Each clip stores the wall-clock timestamp of its first frame, so every rep's raw trace lines up with the footage to the frame — scrubbing the chart seeks the video, playing the video drives the chart crosshair.
  • Automatic trimming to the working window (±2 s of context), so no dead time is stored or scrolled through.
  • Review in-session — the clip pins above the technique charts, loops the current rep's window, and goes full screen.
  • Full-screen set review — video plus a set timeline of per-rep eccentric/concentric segments, best-rep markers, the technique charts for the rep under the playhead, and chevrons stepping through the exercise's other reviewable sets. Phones get an edge-to-edge layout with a filmstrip timeline.
  • Saving a set does not wait for the trim/re-encode — the session keeps moving while the clip finishes in the background.
  • Storage is managed — a settings card shows cloud usage with a clear action; local files are only deleted once their upload is confirmed.

2.14 Insights

Insights opens as a bottom sheet from the chart button, or renders inline beside tracking in split mode, in three tabs:

  • Overview — seven session-summary cards (1RM, volume load, highest load, total reps, sets, average rest, total time), each with a trend and sparkline tinted by metric category, followed by the athlete's last completed sessions of this exercise.
  • Performance — a hero chart for the primary focus metric, a best-set breakdown, a load-response chart once more than one load was used, secondary focus-metric cards, and every remaining metric under "all performance metrics". Tapping a set highlights it across every chart.
  • Technique — a set and rep picker that auto-follows the newest recorded set, a shared crosshair scrubbed across dual-axis charts (power & force, velocity & acceleration), separate inclination and rotation charts with a barbell illustration that tilts to the scrubbed angle, a bar-path trajectory with force vectors, and the review video. Trajectory data can be flipped for barbell work.

2.15 Finishing a training

  • Finish training queues the upload locally first, then closes immediately and uploads in the background. A full-station lock overlay blocks interaction while it commits, and a blocking dialog with Retry / Keep training appears if the data could not even be queued.
  • Finishing with nothing recorded asks first — the workout composition is never stored server-side, so it would otherwise be lost silently.
  • Discard asks for confirmation too.
  • The "keep sensor connected?" prompt is always escapable (✕, backdrop, Escape, hardware back) and tears nothing down when backed out of.
  • Confirmed results appear in the portal's history afterwards.

2.16 Offline, durability and recovery

See offline & sync and ADR 0002.

  • Ambient connectivity signal — a soft offline banner and a brief "back online" confirmation. Ordinary API traffic doubles as the heartbeat, so nothing polls. The app distinguishes device offline from backend unreachable from planned maintenance.
  • Offline-ready days — the day's schedules, every athlete × exercise pair needed to start a session, and the global reference catalogues are cached, so the app cold-starts and trains with no network. Partial coverage is named, not hidden: "N athletes can't be started offline" lists who.
  • Durable in-session state — the live session tree is mirrored to IndexedDB as it changes, with raw rep data stored losslessly so charts survive a crash intact. Reps of a not-yet-completed set are parked separately; recovery re-presents them rather than auto-committing.
  • The shell survives too — each station's live draft (item order, supersets, participants, mid-session edits) is persisted and re-associated on recovery.
  • Crash resume — relaunching after a force-kill offers "resume interrupted training?", restoring stations and sessions, or discarding them along with the local videos.
  • Upload outbox — a finished workout's payload is queued before the network call, so finishing never blocks on signal. A floating indicator shows queued sessions, queued videos and their combined size, with a tap to retry and a near-quota storage warning. Videos queue separately, gated on their session having uploaded first, and one poisoned payload cannot wedge the rest.
  • Account-scoped storage — the offline database is stamped with the backend and user; switching account or environment wipes it rather than mixing data.
  • Leave guards — hardware back or an edge swipe mid-training raises a "leave training?" dialog; a hard navigation raises the browser's own warning.
  • Stale-but-usable beats empty — a view with cached data shows a subtle staleness hint; only a view with no usable data escalates to a real error. A reference catalogue the sensor configuration depends on failing to load produces an explicit, blocking "reload the app" dialog rather than a silently broken session.

Use case — a training camp in a gym with no Wi-Fi and no cell service. The coach loads the day on the hotel network in the morning, trains four sessions offline, and everything uploads by itself when the bus gets signal.

2.17 Broadcasting a session live

The tracking app is the producer for the Live Hub: when the device is assigned to a live session, every completed, edited or deleted set is pushed to the backend as it happens, and the portal renders it as a leaderboard, a weightlifting/powerlifting competition attempt board, or a chronological live stream on a gym display. A floating LIVE chip shows the broadcast state.

The push is best-effort by design — a failed broadcast is reported quietly and never disturbs the authoritative local session.

Use case — an in-house competition. Athletes lift; the screen in the corner updates the attempt board and rankings live, without anyone typing anything.

2.18 Settings & personalization

The Settings drawer buffers its edits and commits them on Save:

SectionContents
AccountProfile — name, email, licence plan (device limit, expiry, source), role, trainable flag, body weight/height, gender, birthdate; legal links; log out
App settingsLanguage, metric ↔ imperial system, beta-tester opt-in
In-training guidanceWarm-up guidance, load guidance, rest-period guidance
Focus metricsWhich metrics headline each exercise group
enode sensorSet timeout, distance threshold (with reset to default)
This deviceThe device session's name
Video storageCloud storage usage, with a clear action
Help & supportReport a problem, send diagnostics, help center, support & feedback
  • Units apply to every displayed weight, height and load immediately, with no reload. Seventeen measurement dimensions carry their own symbol, long name and precision; only mass and length actually differ between systems.
  • Language catalogs are delivered over the air, so a new translation ships without an app release, and the available languages come from the server. Server entity names (exercises, metrics, muscles) localize independently by id, and switching language re-fetches every localized catalogue in the background.
  • In-session preferences live in the tracking view's options menu (§2.6) and are remembered across launches.
  • The profile drawer shows the app version.

2.19 Reliability, support and platform behaviour

  • One error engine. Every failure is classified into offline / recoverable / redirect / blocking and routed to the matching surface — toast, inline alert beside the field, or blocking dialog — showing the backend's localized message where there is one, with Try again and Report on application errors. See error handling.
  • Support reports — a versioned diagnostics snapshot (app, OS, device, locale, connectivity, breadcrumbs; secrets excluded) can be sent from Settings, from a crash, or attached to feedback.
  • Native shell — iOS safe-area handling, zoom lock, native HTTP stack, and native Bluetooth, camera and realtime plugins.
  • Left-edge swipe back app-wide, like a native app, with training-exit opting out.
  • Installable PWA with the same feature set minus the native-only pieces (video capture and the native BLE transports).
  • Spotlight-tour infrastructure is mounted and completion state is stored per account, so a tour finished on one device stays finished everywhere — but no tracking-app tour is authored yet. Contextual manual sections are registered per screen; the button that surfaces them is currently disabled. See walkthroughs.

2.20 Developer & internal tooling

A /debug/* area is gated in one place and absent from production builds. It lets most of the app be exercised without hardware:

RoutePurpose
/debug/serverSwitch which backend the app talks to
/debug/errorsFire real endpoints (slow, abort, specific status codes) and watch each failure route through the production error surfaces
/debug/connectionEvery sensor-connection state, single sensor and SmartBar
/debug/sensor-placementEvery placement card with real copy and images, including the incompatible variants
/debug/recordingThe two live rep-feedback surfaces, with and without the camera, driven by mock reps
/debug/set-reviewThe full set-review surface with a sample video and synthetic reps
/debug/playerThe replay player in isolation — loaded, loading, unavailable
/debug/recommendationsThe recommendation-card layouts
/debug/metric-keyboardsThe metric keyboard across field types, plus the live keyboard-mode decision
/debug/performance-layoutA mock preview of the Performance section layout
/debug/sidebarThe station sidebar expanded and collapsed
/debug/styleguideThe design system as implemented
/debug/globalsDeveloper globals — detail mode, device-session weight override, licence and token inspection
/debug/screenshotsApp Store / Play Store marketing tiles rendered at exact export resolution from real captured sessions

3. Representative use cases

ScenarioWhat the app does
Velocity-based trainingLive per-rep velocity, spoken callouts, velocity-loss stop criterion, live RIR readout, load advice snapped to real plate increments
Team circuit on one tabletUp to three parallel stations, per-station sensors and athletes, athlete switcher for rotation, station-owned sensors across athlete changes
1RM / profiling test dayMomentary 1RM per set, fused exertion estimate, peak-power and peak-load zones in the load keyboard, switch/stop recommendations
Technique coachingCamera clip per set, frame-accurate bar-path overlay, sagittal + frontal trajectories, phase segmentation, scrub-linked chart and video
Jump and reactive-strength testingCMJ, squat-jump and drop-jump modes with jump height, RSI / RSI-mod and contact time
Flywheel / isoinertial trainingInertia-based loading, force- and power-oriented focus metrics, flywheel-specific charts
Unilateral / rehab workLeft/right slots expanded from one prescription, per-side tracking, manual entry where no sensor fits
Drop-in feedback sessionSensor-only feedback training with no plan and nothing persisted
Remote / offline campOffline-ready day bundles, durable in-session persistence, crash resume, automatic upload drain
In-house competitionLive broadcast of every set to the portal's attempt board and leaderboard on a gym display
Retrospective loggingReconstruct a training that already happened from a source workout and upload it

4. Known limits

  • Video capture is native-only — the web/PWA build cannot record; playback and review still work where a clip exists.
  • Rendered/shareable video export (clip plus animated metrics panel) is designed but not built — see video export.
  • No tracking-app spotlight tour is authored yet, and the in-app manual button is currently disabled, although both systems are wired.
  • Media and Lottie assets are not cached for offline; everything else in a downloaded day is.
  • Firmware-rejected reps are silent — a movement the sensor refuses outright creates no rep and, for now, no visible cue.
  • Invalid reps cannot be marked on the live broadcast — the live wire carries no validity field, so they are withheld rather than shown unmarked.
  • Bar-end sensor detection is not wired — the placement card exists, the detection does not.
  • Weightlifting-specific technique detectors from the iOS core are deliberately not ported.
  • The portal link from the tracking app exists but is intentionally hidden.

TopicDocument
Testable requirementsrequirements/tracking-app.md
Manual test protocoltesting/tracking-system-tests.md
Sensors & BLEble.md
Video capturevideo-recording.md
Offline & syncoffline-and-sync.md
Error handlingerror-handling.md
Invalid repsinvalid-reps.md
Live broadcastlive-performance-hub.md
Voice feedbacktext-to-speech.md
Product tourswalkthroughs.md
Auth flowauth.md
Translationsi18n.md