# Recovery & Exercise Catalog APIs

High-level reference for endpoints added for recovery content, exercise/video filtering by muscle group or equipment, and instructional videos on reference data.

All paths are under `/api/v1`.

---

## Feature flags

Enable these on the partner (client) in Admin → Partners → Enabled Features:

| Feature key | Gates |
|-------------|--------|
| `workout_builder` | Client exercise catalog + instructional videos |
| `recovery_videos` | Client recovery video catalog |

Admin routes use admin JWT auth (collection may still show `X-API-Key` for legacy tooling).

---

## Client APIs

### Exercise catalog (`workout_builder`)

| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/exercises` | List exercises. Query: `page`, `limit`, `search`, `equipmentId`, `bodyPartId`, `levelId`, `hasVideo` |
| `GET` | `/exercises/:id` | Single exercise with equipment, level, body parts |
| `GET` | `/exercises/videos` | Exercise demo videos only. Query: `page`, `limit`, `equipmentId`, `bodyPartId` |
| `GET` | `/exercises/instructional-videos` | Instructional clips on equipment / body parts. Query: `type=all\|equipment\|bodyPart`, `equipmentId`, `bodyPartId` |

Auth: `X-API-Key` + `workout_builder` enabled.

### Recovery videos (`recovery_videos`)

| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/recovery` | Active recovery videos. Query: `page`, `limit`, `search`, `bodyPartId`, `equipmentId` |
| `GET` | `/recovery/:id` | Single active recovery video with body parts + equipment |

Auth: `X-API-Key` + `recovery_videos` enabled.

### Studio player (device token)

Recovery kiosk mode (`config.mode = "recovery"`). Requires `studio_player` + `recovery_videos`.

| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/player/recovery-content` | Recovery videos grouped by body part (honours `visibleBodyPartIds` / `visibleEquipmentIds` / `focusBodyPartId`) |
| `GET` | `/player/recovery-video/:id` | Playback URLs for a recovery video |

Partner portal mode options: **Classes** (`browse`), **Live**, **Scheduled** (`ondemand`), **Recovery**. Recovery mode is shown when the partner has `recovery_videos` enabled.

Partner picker helpers: `GET /studio-body-parts`, `GET /studio-equipment` (under partner studio routes).

---

## Admin APIs

### Recovery videos

| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/admin/recovery` | List (filters: `search`, `bodyPartId`, `equipmentId`, `active`, pagination) |
| `GET` | `/admin/recovery/:id` | Get one |
| `POST` | `/admin/recovery` | Create (`title`, `description`, `video`, `image`, `isVimeo`, `active`, `minutes`, `seconds`, `bodyPartIds[]`, `equipmentIds[]`) |
| `PUT` | `/admin/recovery/:id` | Update (+ reassign junctions) |
| `DELETE` | `/admin/recovery/:id` | Delete one |
| `POST` | `/admin/recovery/batch-delete` | Body: `{ "ids": number[] }` |
| `GET` | `/admin/recovery/export` | CSV export |
| `POST` | `/admin/recovery/import` | Bulk import mapped rows; auto-creates missing body parts / equipment by title |

CSV multi-value fields use pipe `|` (or comma) for `bodyParts` / `equipment` titles.

### Exercises (filter extensions)

| Method | Path | Change |
|--------|------|--------|
| `GET` | `/admin/exercises` | Added query: `bodyPartId`, `hasVideo` (existing: `equipmentId`, `levelId`, `search`) |

### Reference data — instructional video + CSV

Body parts and equipment now accept optional `video` (instructional clip) on create/update.

Per-resource export/import:

| Resource | Export | Import |
|----------|--------|--------|
| Goals | `GET /admin/reference/goals/export` | `POST /admin/reference/goals/import` |
| Levels | `GET /admin/reference/levels/export` | `POST /admin/reference/levels/import` |
| Body parts | `GET /admin/reference/body-parts/export` | `POST /admin/reference/body-parts/import` |
| Equipment | `GET /admin/reference/equipment/export` | `POST /admin/reference/equipment/import` |
| Meal types | `GET /admin/reference/meal-types/export` | `POST /admin/reference/meal-types/import` |

Import body shape: `{ "rows": [ { ...fields } ] }`. Upsert by `id` when present.

CSV columns:

| Resource | Columns |
|----------|---------|
| Goals | `id,title,image` |
| Levels | `id,title,rate,image` |
| Body parts | `id,title,image,video` |
| Equipment | `id,title,image,video` |
| Meal types | `id,name` |

---

## Data model (recovery)

```
recovery_videos
  ├── recovery_video_body_parts  → body_parts (many)
  └── recovery_video_equipment   → equipment (many)
```

Body parts / equipment also store optional `video` for standalone instructional media (surfaced via `/exercises/instructional-videos`).

---

## Postman

Updated collections (repo root):

- `FytOS_Admin_API.postman_collection.json` — Recovery folder, reference export/import, exercise filters
- `FytOS_Client_API.postman_collection.json` — Exercise Catalog + Recovery Videos folders  
  (synced copy: `apps/docs/FytOS_Client_API.postman_collection.json`)

Re-import those files into Postman to pick up the new requests.
