Workout assignments — code map
API
Base path: /organizations/:orgId/assignments
Routes
| Route | Method | Service method |
|---|---|---|
GET /coach-overview | KPIs + roster + sparkline | getCoachOverview |
GET /my-week | Member’s published week | findMyWeek |
GET /today | Member’s published day | findMyToday |
PATCH /publish | Set published on listed ids; programId asserts ownership. Returns rows written | setPublished |
POST /bulk-preview | Filter → count + 10 samples | bulkPreview |
POST /bulk-delete | Filter → soft-delete + audit | bulkDelete |
POST /bulk-publish | Filter → publish drafts + audit | bulkPublish |
POST /personal | Bulk assign to athletes | assignPersonal |
POST /program-day/replace | Atomically replace one program date for all active enrollees | replaceProgramDay |
POST /program-day/remove | Soft-delete one program date without touching other scopes | removeProgramDay |
POST /program-day/preview | Count the rows a replace or remove would touch | previewProgramDay |
POST /feed | Insert workout_feed_posts row | assignFeed |
POST /schedule | Insert class_sessions + workout link | assignSchedule |
GET / | ?weekStart&userId&programId; both ids intersect | findByUserWeek / findByProgramWeek |
POST / | Legacy single-athlete create | create |
PATCH /:id | Update; ?programId asserts ownership when the caller knows it | update |
DELETE /:id | Soft delete; ?programId asserts ownership when the caller knows it | remove |
POST /:id/complete | Status → completed | complete |
POST /:id/skip | Status → skipped | skip |
GET /:id | Single by id (member-scoped) | findMyOne |
Controller: apps/api/src/workout-assignments/workout-assignments.controller.ts
Service: apps/api/src/workout-assignments/workout-assignments.service.ts (~1391 lines)
Module: apps/api/src/workout-assignments/workout-assignments.module.ts
NestJS first-match-wins: literal routes (coach-overview, my-week, today, publish, bulk-*, program-day/replace, program-day/remove, program-day/preview, personal, feed, schedule) are declared above :id in the controller for routing precedence.
Cross-feature exports
forkSnapshotIfNeeded(assignmentId) is the canonical entry point for lazy-fork. Used by:
apps/api/src/workouts/workouts.service.ts—resolveEditTargetandupdateMovementPrescription.apps/api/src/workout-results/workout-results.service.ts—create(anchor result to snapshot id).
DTOs (apps/api/src/workout-assignments/dto/)
create-assignment.dto.ts— legacy single-athlete create.update-assignment.dto.ts.assign-personal.dto.ts—{ workoutId?, kind?, note?, programId?, date, athleteIds[], drip:'now'|'morning_of' }.assign-feed.dto.ts—{ trackId, workoutId, publishAt, note? }.assign-schedule.dto.ts—{ workoutId, classTypeId, slots:[{startAt, capacity}] }.set-published.dto.ts— bulk by id list.bulk-filter.dto.ts—WorkoutAssignmentsBulkPreviewDto,BulkDeleteDto,BulkPublishDto;WorkoutAssignmentsBulkFilterschema inlibs/shared.replace-program-day.dto.ts—{ programId, workoutId, date:'YYYY-MM-DD' }.remove-program-day.dto.ts—{ programId, date:'YYYY-MM-DD' }.program-assignment-scope.ts— shared coaching-program and active-recipient validation for personal, legacy and template assignment creation. Program-day writes call it for program validation before touching the roster, so a foreignprogramIdreports the program, not an empty roster.
Web
Routes
| Path | File |
|---|---|
| Member whiteboard (today + week) | apps/web/src/app/[lang]/(protected)/(member)/whiteboard/page.tsx |
| Member program (assigned workouts) | apps/web/src/app/[lang]/(protected)/(member)/program/page.tsx |
| Coach overview | apps/web/src/app/[lang]/(protected)/dashboard/overview/page.tsx |
| Program week grid | apps/web/src/app/[lang]/(protected)/dashboard/programs/[id]/week/[date]/page.tsx |
| Members tab in week | apps/web/src/app/[lang]/(protected)/dashboard/programs/[id]/week/[date]/members/page.tsx |
| Single member day | apps/web/src/app/[lang]/(protected)/dashboard/programs/[id]/week/[date]/members/[memberId]/page.tsx |
| Member day edit | apps/web/src/app/[lang]/(protected)/dashboard/programs/[id]/week/[date]/members/[memberId]/edit/page.tsx |
Components
apps/web/src/components/overview/programming/— the coaching program views:member-week-grid.tsx— data, cell menus (workout/rest/note, publish toggle, chat), day-wide menu (assign/rest/note/replace/remove), the workout picker and bulk-actions sheets; renders its rows × 7 days grid through the sharedweek-grid.tsx(WeekGrid), the same component the daily-programming board uses — see daily-programming/code-map.md for the shared grid’s shape.bulk-coaching-actions-sheet.tsx— bulk preview + delete + publish UIfeed-programming-view.tsx,client-compliance-view.tsx,program-enrollments-tab.tsx,program-comments-tab.tsx,program-class-types-tab.tsxworkout-picker-sheet.tsx— paste-first increatemode (paste → parse →StructureReviewDialog→ assign, same as workout-parse’s other embedded entry points); picking a saved workout and “Build from scratch” are the secondary/adjust paths. Edit mode unchanged (no paste section).week-navigation-bar.tsx,member-avatar.tsx,empty-state.tsx
apps/web/src/components/shared/program-grid/— reusable cell shell + menusapps/web/src/components/member/workouts/workout-detail-drawer.tsx— member’s view of one assignment’s snapshotapps/web/src/components/member/session-card.tsx,apps/web/src/components/member/day-selector-strip.tsx
DB
libs/db/src/lib/schema/workouts.ts:
workout_assignments— seedata-model.md.workout_feed_posts— feed broadcast row (lives inscheduling.ts).
Shared
libs/shared/src/lib/schemas/workout.schema.ts:
workoutAssignmentResponseSchema— response shape.assignmentStatusValues—assigned/completed/skipped.workoutAssignmentsBulkFilterSchema,workoutAssignmentsBulkPreviewResponseSchema,workoutAssignmentsBulkDeleteInputSchema/ResponseSchema,workoutAssignmentsBulkPublishInputSchema/ResponseSchema.
Tests
| File | Type |
|---|---|
apps/api/src/workout-assignments/workout-assignments.service.unit.spec.ts | Unit — service core |
apps/api/src/workout-assignments/workout-assignments.bulk.unit.spec.ts | Unit — bulk preview/delete/publish |
apps/api/src/workout-assignments/workout-assignments.service.driver.ts | Test driver |
apps/web/e2e/specs/coaching-grid.spec.ts | E2E — coaching program grid |
apps/web/e2e/specs/lazy-fork.spec.ts | E2E — lazy-fork lifecycle |
apps/web/e2e/specs/member-workout.spec.ts | E2E — member day view |