Skip to content

Exercise Library Feature

Video library of exercises with taxonomy, instructions, and equipment requirements.

What this enables

Video exercise catalog: Browse hundreds of PT exercises by body region (shoulder, knee, lumbar spine) with video demos and step-by-step instructions.

Shared vs. custom: Use platform exercises ("Bird Dog", "Wall Slide") or clone and customize them for your clinic protocols.

Assign to treatment plans: Build telerehab programs from library exercises—"Day 1: 3x Shoulder External Rotation, 2x Wall Slide".

Track patient adherence: See which exercises patients complete, how many reps, if they're struggling.

Clinical taxonomy: Organize by category (stretching, strengthening, balance), body region, equipment needed, and clinical contraindications.

How it works

  1. Browse library: Admin searches for "shoulder" → sees 50+ shoulder exercises
  2. Create treatment plan: Builds 8-week program by adding library exercises
  3. Assign to patient: Patient gets treatment plan → telerehab app shows video demos
  4. Patient does exercises: Logs sets/reps → system tracks adherence
  5. Custom exercises (optional): Clone "Wall Slide" → customize instructions for your clinic's technique
  6. Analytics: See which exercises patients struggle with, which get best results

Technical Reference

Overview

The exercise library is a global + organization-scoped video exercise database for telerehabilitation. Organizations browse, search, and assign exercises to treatment plans. Exercises contain a video demonstration, text/image instructions, and full clinical taxonomy metadata.

Core Concept

Exercise Library = What exercises exist (content domain)
Treatment Plans  = How exercises are prescribed (clinical domain)  → See treatment-plans/
Telemetry        = How exercises are tracked (Layer 2 ingest pipeline)  → See ../../telemetry/

An exercise defines:

  • What it is (name, description, difficulty, taxonomy)
  • How to perform it (video + ordered instruction steps)
  • What's needed (equipment, contraindications)

An exercise does NOT define:

  • Sets, reps, or duration (that's configured per-exercise in treatment plan sessions)
  • Who should do it (that's on treatment plans → patient enrollment)
  • Tracking data (that's in patient_exercise_logs + the Layer 2 Telemetry ingest path)

Dual-Scope Model: Global + Organization

┌─────────────────────────────────────────┐
│         GLOBAL LIBRARY                  │
│  (organization_id IS NULL)              │
│  Platform-curated by superadmins        │
├─────────────────────────────────────────┤
│  exercises                              │
│  ├── Shoulder External Rotation         │
│  ├── Wall Slide                         │
│  ├── Bird Dog                           │
│  └── Clamshell                          │
└─────────────────────────────────────────┘
          ↓ visible to all orgs
┌─────────────────────────────────────────┐
│         ORG LIBRARY                     │
│  (organization_id = org.id)             │
│  Created by org admins                  │
├─────────────────────────────────────────┤
│  exercises                              │
│  ├── Custom Knee Protocol Step 1        │
│  ├── Post-ACL Warm-up (cloned)         │
│  └── Balance Board Series               │
└─────────────────────────────────────────┘

Visibility rules:

  • All authenticated users see global exercises (published)
  • Org staff see global + their org's exercises
  • Patients see published exercises only (through their treatment plans)
  • Only superadmins can create/modify global exercises
  • Org admins can create/modify their org's exercises
  • Org admins can clone global exercises into their org library for customization

Key Tables

TablePurpose
exercisesMain entity — video, metadata, taxonomy. Global (org_id NULL) or org-scoped.
exercise_categoriesTaxonomy categories (stretching, strengthening, balance). Hierarchical via parent_id.
exercise_body_regionsBody part tags (shoulder, knee, lumbar spine). Grouped by body_area.
exercise_equipmentEquipment catalog (resistance band, yoga mat, dumbbell).
exercise_tagsPolymorphic M:M junction — links exercises to categories, body regions, and equipment.
exercise_instructionsOrdered text/image instruction steps per exercise.
exercise_contraindicationsClinical warnings/restrictions per exercise — severity is 'warning' (proceed with caution) or 'contraindicated' (do not perform).

Taxonomy

Exercises are tagged with three independent taxonomies. Each taxonomy is also dual-scoped (global + org):

Categories (Hierarchical)

Stretching
├── Static Stretching
├── Dynamic Stretching
└── PNF Stretching
Strengthening
├── Isometric
├── Isotonic
└── Plyometric
Balance & Proprioception
Mobility
Breathing & Relaxation

Body Regions (Grouped by Area)

Upper Body
├── Shoulder
├── Elbow
├── Wrist / Hand
└── Cervical Spine

Core
├── Lumbar Spine
├── Thoracic Spine
└── Abdominals

Lower Body
├── Hip
├── Knee
├── Ankle / Foot
└── Glutes

Full Body

Equipment

No Equipment (bodyweight)
Resistance Band
Yoga Mat
Dumbbell
Swiss Ball
Foam Roller
Balance Board
TheraBand

Filtering

The GET /v1/exercises endpoint supports multi-taxonomy filtering:

GET /v1/exercises?category_id=5&body_region_id=3&difficulty=beginner&equipment_id=2&status=published&q=plank&sort=-created_at

Video Storage

Section superseded by the compositional model

The "single video_url column per exercise" model below predates the platform's move to composed videos per prescription. Exercises no longer have one canonical video — they have a bundle of raw filming primitives in S3, from which the exercise-composer service renders one MP4 per (exercise, prescription, language) tuple. Bunny video IDs are cached in exercise_renders (landing with F9.1), not stored as a column on exercises.

For the current model, see composition.md and P56 Exercise Video Composition Pipeline.

Exercises store video via a CDN-agnostic design (historical model — see above):

sql
video_url               TEXT        -- CDN URL (Bunny Stream, S3, etc.)
video_provider          TEXT        -- 'bunny_stream' | 's3'
video_thumbnail_url     TEXT        -- poster frame
video_duration_seconds  INT         -- cached duration

Why CDN-agnostic: The platform supports Bunny Stream (EU-first CDN with built-in HLS transcoding) or S3 + CloudFront. The video_provider field allows the upload/playback layer to adapt without schema changes.

See video-upload.md for the full upload flow and adaptive streaming design.

Instructions Model

Each exercise has ordered, manually written instruction steps. Whoever creates the exercise (the platform team for global exercises, or clinic staff for clinic exercises) writes each step by hand through the admin UI. Instructions are typed by role:

Exercise: Shoulder External Rotation
├── [preparation] "Lie on your side with a towel roll under your arm"
├── [step] "Rotate your forearm upward, keeping elbow at 90°"
├── [form_cue] "Keep your elbow pinned to your side"
├── [breathing] "Exhale as you rotate up, inhale on return"
└── [safety] "Stop if you feel sharp pain in the shoulder joint"

Instruction types: preparation, step, form_cue, breathing, safety

Each instruction can have an optional image (S3 upload) for visual demonstration. When cloning an exercise, all instructions (including images) are copied and can be freely edited.

Contraindications

Each exercise can have clinical contraindications — warnings tied to specific medical conditions. Stored in exercise_contraindications:

Exercise: Shoulder External Rotation
├── [warning]          "Shoulder Impingement" — reduce range of motion, stop if sharp pain
└── [contraindicated]  "Acute Rotator Cuff Tear" — do not perform until cleared by physician

Severity levels:

  • warning — exercise can be performed with modifications or caution
  • contraindicated — exercise should not be performed by patients with this condition

Who manages contraindications:

  • Platform exercises — contraindications are pre-written and maintained by the RestartiX team. Clinics cannot edit them directly (clone the exercise first).
  • Clinic exercises — the clinic's specialists and admins manage contraindications. When cloning from the platform library, all contraindications are copied and can then be freely edited, added, or removed.

Display, not enforcement: Contraindications are shown as clinical guidance when a specialist prescribes an exercise. The platform does not automatically block assignment based on contraindications — the prescribing specialist makes the clinical judgment.

Cloning

Org admins can clone exercises from the global library (or from their own library) to create customized variants:

http
POST /v1/exercises/{id}/clone

What gets cloned:

  • All exercise fields (name, description, taxonomy, difficulty)
  • All instructions (with images)
  • All contraindications
  • All tags

What changes:

  • New UUID
  • organization_id set to current org
  • cloned_from_id set to source exercise ID
  • status reset to draft

The clone is fully independent — editing the source does not affect the clone.

Soft Delete

Exercises use soft delete (deleted_at timestamp) because they may be referenced by active treatment plans. A soft-deleted exercise:

  • Is hidden from library search/browse
  • Remains visible in existing treatment plans (with a "discontinued" indicator)
  • Cannot be added to new plans
  • The exercises.id FK in treatment_plan_session_exercises uses ON DELETE RESTRICT as a safety net

Exercise Status

draft → published → archived
  • draft: Only visible to admins/superadmins. Work in progress.
  • published: Visible to all authorized users. Can be used in treatment plans.
  • archived: Hidden from new plan creation but remains in existing plans.

Integration Points

With Treatment Plans Feature

  • Exercises are added to treatment_plan_session_exercises with per-plan configuration (sets, reps, duration, rest)
  • Exercise data (video, instructions) is always "live" — updates to an exercise are immediately visible in all plans
  • Plan version snapshots capture exercise IDs (not exercise content), so the current exercise state is always shown

With Telemetry API (Layer 2 feature)

  • Video engagement: When a patient watches an exercise video, the Patient Portal sends the standard media event lifecycle (session_start, heartbeat, buffering_start/end, milestone, session_end) to POST /v1/media/events on the Telemetry API. Server-side aggregation writes media_session_metrics + media_buffering_events (Postgres, monthly partitioned). See ../../telemetry/media-events.md for the event spec. Consent: analytics per-purpose flag.
  • Pose tracking: If enabled, MediaPipe landmark frames are batched (binary float32 + gzip, 1-sec batches) and sent to POST /v1/pose/frames (separate endpoint). Server-side aggregation at session_end produces pose_session_metrics + pose_rep_metrics (Postgres) + a replay blob in S3 at s3://restartix-telemetry/{org_id}/{session_id}.bin.gz. Consent: biometric per-purpose flag.
  • Errors: off-the-shelf (Sentry-equivalent) when needed; not part of telemetry. The earlier POST /v1/errors/report endpoint has been removed.

With S3/CDN

  • Exercise videos: {org_id}/exercises/{exercise_id}/video/{filename} (org) or global/exercises/{exercise_id}/video/{filename} (global)
  • Instruction images: {org_id}/exercises/{exercise_id}/instructions/{sort_order}/{filename}
  • Thumbnails: {org_id}/exercises/{exercise_id}/thumbnail/{filename}

API Endpoints

See api.md for full API documentation.

Key endpoints:

  • GET /v1/exercises — Browse/search with taxonomy filters
  • POST /v1/exercises — Create exercise (admin: org, superadmin: global)
  • GET /v1/exercises/{id} — Full details with instructions, tags, contraindications
  • POST /v1/exercises/{id}/clone — Clone to org library
  • POST /v1/exercises/{id}/video — Upload video

Design Principles

  1. Dual-scope by design — Global library is platform-curated, org libraries are private. Both use the same tables with organization_id IS NULL vs IS NOT NULL.
  2. CDN-agnostic — Video storage abstracted behind video_url + video_provider. No vendor lock-in.
  3. Exercises are content, not configuration — No sets/reps/duration on exercises. That's treatment plan config.
  4. Mutable, not versioned — Exercises update in-place. If you need variants, clone them.
  5. Soft delete for safety — Referenced exercises can't be hard-deleted (RESTRICT FK + soft delete).
  6. Multi-tenant by design — All tables have org-scoped RLS. Global exercises get a special organization_id IS NULL SELECT policy.