---
path: /studio/aja/fitness-pipeline
surface: studio
domain: aja
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/aja/fitness-pipeline/page.tsx
status: walked + e2e-covered
last_walked:
  '2026-07-04 focused real-dev-infra Playwright route walk — anonymous redirect,
  Aja-admin smoothness catalog, exact seeded jerky and edited clean fitness
  motions through the real BFF, local/BFF validation, malformed/transport
  failures, loading/403/503/malformed catalog states, pending controls, Metis
  links, route-map + quick-action affordances, mobile/touch/axe, and direct BFF
  auth/schema gates. Evidence:
  WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md §289.'
---

# Studio Aja · Fitness Pipeline

## Purpose

Admin lane console for exercise-motion smoothness analysis. Its operations lane
wires `@aja/motion-quality` `analyzeSmoothness` via
`/v1/admin/aja/fitness-pipeline`: score each joint by the magnitude of its jerk
(third derivative; lower is smoother) and flag the frames whose jerk exceeds a
threshold as discontinuities, returning the smoothness score, average/peak jerk,
per-joint scores, and discontinuity frames. A preserved Metis
embodied-instruction panel bridges the `fitness` domain into structured
learning.

## Entry points

- **Direct URL / bookmark** — `/studio/aja/fitness-pipeline`; metadata sets
  `alternates.canonical`.
- **Linked from `/studio`** Domain-bridge studios section (Aja sub-area).
- **Quick action** — "Open Aja Yoga Pipeline workspace"
  (`/studio/aja/yoga-pipeline`).

## Layout regions

`page.tsx` renders inside `<ShellLayout active="studio">`:

- **Workspace** `StudioAjaFitnessPipelineWorkspace` — `<h1>` "Aja Fitness
  Pipeline Workspace" + summary (`data-aja-fitness-pipeline-summary`), the Metis
  panel (`data-aja-fitness-pipeline-metis-panel`, `domain="fitness"`), then the
  **Smoothness Operations Lane** (`data-aja-fitness-pipeline-operations-lane`).
- **Route Map panel** (`data-aja-fitness-pipeline-route-map`, `<h2>`) — 5
  entries from `STUDIO_AJA_FITNESS_PIPELINE_ROUTE_MAP` exposed with
  `data-aja-fitness-pipeline-route-map-entry` / `data-route-path`.
- **Quick-action lane** (`data-aja-fitness-pipeline-quick-actions`) — two
  `Link.quickAction` anchors: yoga-pipeline and `/studio`.

## States

The lane fetches `GET /v1/admin/aja/fitness-pipeline` on mount.

- [x] **Loading** — `data-aja-fp-loading` "Loading smoothness analyzer...".
- [x] **Unauthorized (gated)** — `data-aja-fp-unauthorized` on 401/403; admin
      scope message ("Aja workspace scope required to analyze movement
      smoothness.").
- [x] **Error** — `data-aja-fp-error` on non-OK / malformed / network failure.
- [x] **Ready (form)** — `data-aja-fp-form`, catalog attributes
      (`data-aja-fp-analyzer`, default jerk threshold, report count and
      `data-aja-fp-report` spans), and idle submit state.
- [x] **Result** — `data-aja-fp-result` with stable score / average-jerk /
      peak-jerk / discontinuity-count attributes, `data-aja-fp-headline`,
      `data-aja-fp-jerk`, `data-aja-fp-discontinuities` / `data-aja-fp-clean`,
      and typed `data-aja-fp-joint-row` attributes.
- [x] **Validation error** — `data-aja-fp-analyze-error` (e.g. "Provide at least
      one joint id." / "Jerk threshold must be a positive number.").
- [x] **Mobile/touch containment** — form controls and route actions remain at
      least 44 px tall with no horizontal overflow.
- [x] **Empty** — N/A; catalog + Metis panel are constant.

## Interactions

### Smoothness form (`data-aja-fp-form`)

- [x] **Joint ids** — input `data-aja-fp-joints` (default `j`); comma-separated,
      at least one.
- [x] **Frames** — textarea `data-aja-fp-frames`; JSON array of
      `{ positions: { jointId: { x, y, z } } }`, at least 4 frames.
- [x] **Jerk threshold** — input `data-aja-fp-threshold`; positive number.
- [x] **Analyze smoothness** — submit `data-aja-fp-submit`; fires
      `POST /v1/admin/aja/fitness-pipeline/analyze` with
      `{ joints, frames, jerkThreshold }`; locked with
      `data-aja-fp-submit-state="analyzing"` while the real request is pending.

### Metis embodied-instruction panel

- [x] **Relationship cards** (`data-aja-fitness-pipeline-metis-summary` +
      `data-aja-fitness-pipeline-metis-card`) — links bridge the `fitness`
      domain into Metis study moments and expose stable hrefs.

### Route Map panel

- [x] **5 entries** — non-interactive listing with exact path ordering.

### Quick-action lane

- [x] **"Open Aja Yoga Pipeline workspace"** → `/studio/aja/yoga-pipeline`
- [x] **"Back to Studio workspace index"** → `/studio`

## Data & contracts

- **Reads**: `GET /v1/admin/aja/fitness-pipeline` (catalog: `analyzer`,
  `summary`, `defaultJerkThreshold`, `reports`) on mount, `cache: 'no-store'`,
  `buildBffAuthHeaders()`; client fails closed unless the expected `smoothness`
  analyzer and all five report keys are present.
- **Writes**: `POST /v1/admin/aja/fitness-pipeline/analyze` →
  `{ score, averageJerk, peakJerk, perJointScores, discontinuityFrames }`;
  client fails closed unless the result, per-joint scores, and discontinuity
  frame list have the expected typed fields.
- **Realtime**: none.
- **Caching**: client fetch on mount (no-store); SSR shell.
- **Auth/role check**: BFF endpoints admin-scoped, fail-closed (401/403 →
  unauthorized render); route gated signed-in + studio via the proxy.

## Cross-references

- Parent: [`../../studio-overview.md`](../../studio-overview.md)
- Sibling routes:
  [`./studio-aja-yoga-pipeline.md`](./studio-aja-yoga-pipeline.md)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioAjaFitnessPipelineWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioAjaFitnessPipelineRouteMap.ts`
  - `apps/oshun/web/src/components/studio/StudioAjaMetisEmbodiedInstructionPanel.tsx`

## Verification evidence

- `apps/oshun/web/e2e/studio-aja-fitness-pipeline.spec.ts` runs against the real
  Next Studio shell and local BFF, forwarding browser bearer auth rather than
  mocking the smoothness contract.
- The spec covers anonymous redirect, Aja-admin catalog load, exact default
  jerky `j` motion, edited clean constant-velocity motion, local validation with
  no POST, BFF validation details, malformed result, transport failure, loading
  / 503 / malformed / non-admin states, pending form locking, Metis bridge
  links, mobile no-overflow + 44px controls, scoped axe, and direct BFF
  401/403/400/200 gates.

## Open questions / known gaps

- [ ] Route Map lists `scenes`/`exports`/`revisions`/`governance` child routes
      that are not yet implemented as pages.
