Class Types
What is this
A class type is a reusable template that names a class (e.g. “CrossFit WOD”, “Open Gym”, “Pilates Reformer”), pins it to a parent program, and supplies sensible defaults that class_sessions inherit at creation time (defaultDurationMin, defaultCapacity, color). It also carries a hasWorkout flag — used to mark non-workout classes like “Open Gym” so the schedule UI knows not to demand programming for them.
Class types are studio-configured (owners/admins) and are the schedule’s vocabulary: every class_session row points at exactly one class_type, and every class_type points at exactly one program (which carries organizationId).
Who uses it
| Persona | Why |
|---|---|
| Owner | Creates/edits class types; sets defaults the schedule reuses. |
| Admin | Same as owner. |
| Coach | Read-only — selects a class type when creating a session. |
| Member | Reads the class type name + color when browsing the schedule. No mutation. |
Persona impact
- Owner/admin edit-only via
/dashboard/settingsand/dashboard/scheduletabs (see i18nschedule.classTypes,schedule.classTypesTab). - Coach picks a class type at session-create time; if the class type’s
hasWorkout=falsethe UI hides workout-attachment controls. - Member never interacts directly; sees the name and color in the calendar.
High-level capabilities
- CRUD — create, list, get, update, deactivate. Soft “deactivate” via
isActive=false; rows are never hard-deleted. - Program scoping — every class type belongs to a single program; the program (not the class type) is what carries the
organizationId. - Defaults inheritance — when
POST /sessionsruns without explicitcapacity, the session inheritsclassType.defaultCapacity.defaultDurationMinandcolorare UI hints. - No-workout marker —
hasWorkout=falseopts the class type out of the “this session needs programming” UX; used for Open Gym, drop-ins, etc.
Relationship to other features
- scheduling-bookings — every
class_sessions.class_type_idFKs here. - organizations — org boundary lives on
programs.organization_id; class types sit one level below. - Daily programming (
daily_programmingtable) — keys by(class_type_id, date)so the same daily workout flows into every session of that class type on that day (unless the session has explicitclass_session_workouts).
Current status
Shipped and stable. The hasWorkout flag is the most recent addition (i18n key schedule.classTypeSheet.hasWorkoutHelper: “Off for class types like Open Gym that don’t carry programmed workouts — only sessions are generated.”).
Known gaps
findAllfilters in JS after fetching all active class types (filters byprogram.organizationIdpost-query). Acceptable at current scale but inefficient — should push the org filter into SQL via join. (Seeclass-types.service.ts:60-79.)- No “duplicate class type” affordance; owners re-type defaults if they want a sibling type.