Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesClass TypesClass Types

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

PersonaWhy
OwnerCreates/edits class types; sets defaults the schedule reuses.
AdminSame as owner.
CoachRead-only — selects a class type when creating a session.
MemberReads the class type name + color when browsing the schedule. No mutation.

Persona impact

  • Owner/admin edit-only via /dashboard/settings and /dashboard/schedule tabs (see i18n schedule.classTypes, schedule.classTypesTab).
  • Coach picks a class type at session-create time; if the class type’s hasWorkout=false the UI hides workout-attachment controls.
  • Member never interacts directly; sees the name and color in the calendar.

High-level capabilities

  1. CRUD — create, list, get, update, deactivate. Soft “deactivate” via isActive=false; rows are never hard-deleted.
  2. Program scoping — every class type belongs to a single program; the program (not the class type) is what carries the organizationId.
  3. Defaults inheritance — when POST /sessions runs without explicit capacity, the session inherits classType.defaultCapacity. defaultDurationMin and color are UI hints.
  4. No-workout markerhasWorkout=false opts 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_id FKs here.
  • organizations — org boundary lives on programs.organization_id; class types sit one level below.
  • Daily programming (daily_programming table) — 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 explicit class_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

  • findAll filters in JS after fetching all active class types (filters by program.organizationId post-query). Acceptable at current scale but inefficient — should push the org filter into SQL via join. (See class-types.service.ts:60-79.)
  • No “duplicate class type” affordance; owners re-type defaults if they want a sibling type.