Fitness (GYM)

Fitness (GYM) - Structural Topology & Domain Modeling

Physical club topology, Aggregate Roots, Entities, Value Objects, and hierarchical relationships governing the Fitness (GYM) domain.

Structural Topology & Domain Modeling

The Fitness (GYM) domain organizes its tactical architecture around two interconnected foundations: the physical and operational club topology (branches, zones, studios, access points, and staff) and the tactical Domain-Driven Design (DDD) aggregate hierarchy governing memberships, bookings, access events, training credits, and member progress.


1. Club & Facility Physical Topology

The facility topology models the physical infrastructure of a single studio or a multi-branch fitness chain:

Fitness Club Network / Enterprise
└── Club Branch (Facility)
    ├── Access Points (Entry & Exit Control)
    │   ├── Main Turnstile Row (QR / RFID / Biometric)
    │   ├── Studio Zone Secondary Gates
    │   └── Front Desk Manual Override Terminal
    ├── Training Zones
    │   ├── Main Gym Floor (Cardio & Strength Equipment)
    │   ├── Group Class Studios (Studio A / Studio B / Cycling Room)
    │   ├── Pool & Wet Areas
    │   └── Recovery Zone (Sauna / Steam / Massage)
    └── Staff Resource Pool
        ├── Certified Personal Trainers
        ├── Group Class Instructors
        └── Front Desk / Membership Consultants

Topology Levels Explained

LevelDescriptionKey Attributes
Club BranchThe physical facility operating under one legal entity.Branch code, address, operating hours, peak-hour definitions, time zone.
Access PointA controlled entry or exit device enforcing access decisions.Access point ID, direction (entry/exit), supported credential types, offline cache capability.
Training ZoneAn entitlement-controlled physical area within the branch.Zone ID, zone category (Floor, Studio, Pool, Recovery), minimum tier required, occupancy limit.
Studio RoomA bookable space hosting scheduled class sessions.Studio ID, equipment-derived capacity ceiling, ventilation and safety limits.
Staff PoolThe human resources deliverable against schedules.Trainer certifications, instructor class category qualifications, availability windows.

2. Aggregate Roots & Tactical Hierarchy

The tactical domain model partitions fitness responsibilities into six sovereign Aggregate Roots, ensuring transactional consistency, boundary protection, and invariant enforcement:

flowchart TD
    subgraph MembershipBoundary["Membership Contract Boundary"]
        MA["MembershipAgreement (Aggregate Root)"]
        FP["FreezePeriod (Entity)"]
        PCR["PlanChangeRecord (Entity)"]
        PS["PlanSnapshot (Value Object)"]
        BCA["BillingCycleAnchor (Value Object)"]
        CT["CancellationTerms (Value Object)"]

        MA --> FP
        MA --> PCR
        MA --> PS
        MA --> BCA
        MA --> CT
    end

    subgraph SchedulingBoundary["Class Scheduling & Booking Boundary"]
        SCS["ScheduledClassSession (Aggregate Root)"]
        CB["ClassBooking (Entity)"]
        WE["WaitlistEntry (Entity)"]
        CP["CapacityPolicy (Value Object)"]
        BW["BookingWindow (Value Object)"]
        CC["CancellationCutoff (Value Object)"]

        SCS --> CB
        SCS --> WE
        SCS --> CP
        SCS --> BW
        SCS --> CC
    end

    subgraph AccessBoundary["Access & Attendance Boundary"]
        MAE["MemberAccessEvent (Aggregate Root)"]
        AD["AccessDecision (Value Object)"]
        CPS["CredentialPresentation (Value Object)"]
        APS["AccessPointSnapshot (Value Object)"]

        MAE --> AD
        MAE --> CPS
        MAE --> APS
    end

    subgraph CreditBoundary["PT Credit Boundary"]
        PCP["PtCreditPackage (Aggregate Root)"]
        CLE["CreditLedgerEntry (Entity)"]
        CBAL["CreditBalance (Value Object)"]

        PCP --> CLE
        PCP --> CBAL
    end

    subgraph PtBoundary["PT Appointment Boundary"]
        PSA["PtSessionAppointment (Aggregate Root)"]
        TA["TrainerAllocation (Value Object)"]
        SS["SessionSlot (Value Object)"]
        SO["SessionOutcome (Value Object)"]

        PSA --> TA
        PSA --> SS
        PSA --> SO
    end

    subgraph EngagementBoundary["Member Engagement Boundary"]
        WPA["WorkoutProgramAssignment (Aggregate Root)"]
        PR["ProgressRecord (Entity)"]
        WSL["WorkoutSessionLog (Entity)"]

        WPA --> PR
        WPA --> WSL
    end

    MA -.->|Entitles Booking & Access| SCS
    MA -.->|Validates Entry Decision| MAE
    PCP -.->|Funds Session Confirmation| PSA
    SCS -.->|Attendance Verified At| MAE

3. Detailed Aggregate Specifications

Aggregate Root 1: MembershipAgreement

  • Role: Sovereign custodian of the contractual relationship between the member and the club over time.
  • Root Entity: MembershipAgreement (Identified by MembershipAgreementId, references MemberId and PlanId).
  • Internal Entities:
    • FreezePeriod: A time-bounded suspension window with FreezeStartDate, ScheduledEndDate, ActualEndDate, and ConsumedQuotaDays. Multiple freeze periods may exist per contract year within quota limits.
    • PlanChangeRecord: An audit entity capturing upgrades and downgrades: FromPlanId, ToPlanId, EffectiveDate, ProrationIntent, and the requesting actor.
  • Value Objects:
    • PlanSnapshot: Immutable copy of plan terms captured at activation or plan change — price, billing frequency, access tier, freeze quota, advance booking window, and commitment period — ensuring historical agreements remain interpretable even after catalog prices change.
    • BillingCycleAnchor: The fixed calendar day anchoring recurring billing periods, preserved across renewals.
    • CancellationTerms: The notice period, commitment end date, and early termination penalty rules governing voluntary exit.

Aggregate Root 2: ScheduledClassSession

  • Role: Transaction boundary for capacity, booking, and waitlist consistency of one dated class occurrence.
  • Root Entity: ScheduledClassSession (Identified by ScheduledClassSessionId, references ClassTemplateId, StudioId, and InstructorId).
  • Internal Entities:
    • ClassBooking: A member’s seat reservation identified by ClassBookingId, tracking status (Confirmed, EarlyCancelled, LateCancelled, NoShow, CheckedIn, Completed) and the booking timestamp that determines waitlist ordering.
    • WaitlistEntry: An ordered demand placeholder with ArrivalPosition, OfferState (Pending, Offered, Accepted, Expired, Skipped), and offer expiry timestamp.
  • Value Objects:
    • CapacityPolicy: The hard ceiling of confirmed seats, derived from studio equipment count and safety limits; never overridable by staff without a formal capacity change event.
    • BookingWindow: The per-tier advance booking rules defining the earliest moment a member may book this session.
    • CancellationCutoff: The deadline separating free early cancellation from penalized late cancellation.

Aggregate Root 3: MemberAccessEvent

  • Role: Immutable record of every credential presentation and its deterministic outcome.
  • Root Entity: MemberAccessEvent (Identified by AccessEventId).
  • Value Objects:
    • CredentialPresentation: The presented token type (QR, RFID, Biometric), token reference, and presentation timestamp.
    • AccessDecision: The evaluated outcome — Granted or Denied — with an explicit DenialReason (MembershipExpired, MembershipFrozen, PaymentSuspended, ZoneNotEntitled, PeakHoursRestricted, CredentialRevoked, DayPassInvalid).
    • AccessPointSnapshot: The access point identity, direction, and branch context at evaluation time, preserving forensic accuracy even if hardware is later relocated.

Aggregate Root 4: PtCreditPackage

  • Role: Governs the purchase, consumption, refund, and expiry of pre-paid personal training credits.
  • Root Entity: PtCreditPackage (Identified by PtCreditPackageId, references MemberId).
  • Internal Entities:
    • CreditLedgerEntry: An append-only entry recording every balance mutation: Purchased, Consumed, Restored, Forfeited, Expired, with quantity, timestamp, and the originating session reference.
  • Value Objects:
    • CreditBalance: The derived, always-consistent view of remaining credits, computed exclusively from ledger entries — never stored as a mutable counter.
    • PackageValidity: The purchase date and expiry date bounding credit usability.

Aggregate Root 5: PtSessionAppointment

  • Role: Transaction boundary for one-to-one training appointments between a member and a trainer.
  • Root Entity: PtSessionAppointment (Identified by PtSessionAppointmentId, references MemberId, TrainerId, and PtCreditPackageId).
  • Value Objects:
    • TrainerAllocation: The assigned trainer, their certification tags, and any substitution history.
    • SessionSlot: The reserved start time, duration, and training zone or studio placement.
    • SessionOutcome: The completion record — attended, member late-cancelled, member no-show, or trainer-cancelled — driving credit restoration or forfeiture.

Aggregate Root 6: WorkoutProgramAssignment

  • Role: Tracks member engagement, program adherence, and measurable progress over time.
  • Root Entity: WorkoutProgramAssignment (Identified by ProgramAssignmentId, references MemberId and WorkoutProgramId).
  • Internal Entities:
    • WorkoutSessionLog: A dated record of a completed training session against the assigned program, capturing completed exercises and perceived exertion.
    • ProgressRecord: A periodic measurement entry — body composition metrics, strength benchmarks, or attendance streak snapshots — supporting retention conversations and goal reviews.

Our Premium Sponsors

Obelaw is proudly open-source. Continued development, bug fixes, and community support are made possible by the generosity of our sponsors.

Sponsor Obelaw