Master Data — Core concepts
| Concept | Meaning |
|---|---|
| Enterprise | Top-level organization, may have custom URL and service-area policy. |
| BusinessUnit (BU) | Main data/config boundary: payment settings, billing settings, timezone, provider. |
| Org / Site | Physical location or site under a BU where programs/sessions run. |
| Account | Family/customer account; usually a container for account holder and attendee. |
| Account Holder / Contact | Contact representing the account. Avatar/profile image belongs to Contact, not Account. |
| Attendee | Child/participant referenced by booking/subscription/incident/finance. |
| Term | School term or the period during which a program runs. |
| ProgramCategory | Program type (Term Care, Holiday, Class, Camp); holds category-level rules (TypeId decides card/session behavior). |
| Program | Program template within a category; holds requirement metadata and SpecialTypeId (Term Care / Before-and-After-School-Care only). |
| TermProgramSet (TPS) | Offering/course within a term at a site/category; holds schedule, requirement summary, publish state, and capacity context. |
| TermProduct | Specific session/slot that booking selects or subscription schedule references; inherits sign method and requirements from Product. |
| TermProgramSetCapacity | TPS-level capacity per date (TermProgram.Date); source of ProgramCapacity on booking checks. |
| ProductSet | Product set assigned to attendee via Subscription Config; sourced from SubscriptionExtra.ProductSetId of the assigned Subscription. |
| Attendee_Subscription | Assigns exactly one active Subscription (same BU) to attendee; assigning another Subscription replaces the active row. |
| Attendee_ProductSet | Association enabling/disabling a ProductSet for an attendee; no active row = ProductSet disabled. |
| Subscription Config | Tab on Attendee Profile visible only to sys-admin in a BU TypeId = 99 (SuperAdmin); assigns Subscription and configures ProductSet. |
| Customization item | BU-level Reference_Enabled/_Text/_Required/_Options codes controlling display/label/required of attendee and requirement fields. |
| OrgProgramCategory | Site–program category link; StatusId Approved (500) = selected, Initialised (0) = unselected; IsActive stays true for the canonical row. |
| Employee / OrgEmployee | Staff + staff–site link; archived staff (StatusId = Archived) are excluded from link lists, roster, and shift selector. |
| TrackingCode | Code classifying shift/leave (TypeId Leave/Shift); colorCode shows a color swatch in lists. |
| System image | System asset or uploaded image used for avatar/course/activity, with crop policy. |
Entity hierarchy
Enterprise contains BU; BU contains site/org, account, and config. Account keeps relationships to account holder/contact and attendee. Program structure connects from term/category/program to TPS and term product.
Source entity vs runtime record
Master Data is usually source entity. Runtime records like TermBooking, Enrollment, Invoice, PaymentBatch only reference master data to know who, where, and which program.
Ownership summary
| Owner | Owns |
|---|---|
| Enterprise | Custom URL, enterprise-level service-area policy; HeightUnit/WeightUnit for measurement display. |
| BusinessUnit | BU-scoped settings, customization items, data boundary. |
| Contact | Account holder profile image/avatar. |
| Attendee | Attendee profile/measurements/requirement values/product config/subscription config. |
| Program/Term structure | Category/program/TPS/product setup and availability. |
Subscription Config — assign Subscription and ProductSet to attendee
- The
Subscription Configtab on Attendee Profile shows only for sys-admin in a BUTypeId = 99(SuperAdmin). Other users or sys-admin in a different BU do not see the tab and are blocked at the API. - The Subscription selector only lists Subscriptions in the same BU (
BusinessUnitId = CurrentBusinessUnitId),IsActive = true, ordered byName. Selecting another Subscription → replaces the current assignment (at most one activeAttendee_Subscription). - Candidate ProductSets come from the assigned Subscription's active
SubscriptionExtra(ProductSetIddistinct,ProductSet.IsActive = true, same BU). Attendee without an assigned Subscription → empty list. - A ProductSet not referenced by the Subscription → does not show even with an
Attendee_ProductSetrow. An old active row can still be disabled to avoid orphan config after switching Subscription. - Enable/Edit use a popup form. Enable creates an active
Attendee_ProductSet(one active per attendee/ProductSet pair); Disable soft-disables the row without changingProductSet. - Displayed columns: Name, Effective Start (month picker, saves first day of month), Effective End (optional, last day of month), Discount, Disc. Effective Date, Custom Price (NZD) optional. End must not precede start → blocks save + feedback.
Real-world example: Assign
Subscription "Swim 2026"toAttendee "Lily"in the SuperAdmin BU. → Scopes the valid product sets. → The selector lists only same-BU Subscriptions; selectingProductSet "Level 2 Kit"creates a new activeAttendee_ProductSetrow without a second row.
Requirement customization — School Year / Level / Swimming Competency
- Each reference
AttendeeSchoolYear,AttendeeLevel,AttendeeSwimmingCompetencyhas_Enabled(defaultFalse),_Text(default field name), and_Required(defaultFalse) customization. _Enabledis the display gate on every surface: Attendee Profile, Product setup (Session/Class/Enrichment), Term Planner summary, Booking UI, Reports. Hiding does not delete saved attendee/Product values._Textis the shared label on all surfaces; empty_Text→ falls back to the default label._Requiredonly blocks submit when the reference is_Enabled; it blocks bothBasicProfileCompletedand booking.AttendeeLevelpersists asint NULL; changes write entity event history likeSchoolYear.AttendeeSwimmingCompetency_Optionsis a JSON array (default["Non Swimmer","Learner","Competent"]) → single-select dropdown. Legacy values outside the options still display; save only accepts values in the options. Broken options → empty list, form does not break.
Real-world example: BU disables
AttendeeLevel_Enabled, changesAttendeeSchoolYear_TexttoGrade, and enablesAttendeeSwimmingCompetency_Required. → Drops the unused dimension and renames the label consistently. → No surface renders Level; theGradelabel appears everywhere; a booking for an attendee missing Swimming Competency is rejected.
Measurement customization — height/weight
Enterprise Setting.HeightUnit/WeightUnitis unit metadata for rendering height/weight. Empty → UI drops the label, field not blocked.AttendeeHeight_Enabled/_RequiredandAttendeeWeight_Enabled/_Requiredcontrol the attendee fields (persistHeight/Weightas nullable decimal).- Product
MinHeight/MaxHeight/MinWeight/MaxWeightare requirements, shown only when the corresponding measurement is enabled. Display metadata only; does not auto-enforce booking eligibility.
Real-world example: BU enables
AttendeeHeight_Enabledand disablesAttendeeWeight_Enabled. → Avoids asking for unused information. → Attendee form shows Height, hides Weight; product form shows only the Min/Max Height columns; booking is not blocked by height range.
Enrollment form customization — consent fields
CustomConsent1..3are BU-level consent fields withEnabled,Required,Text,Description(shaped likePhotoConsent).Text= label,Description= helper text (empty → no empty container rendered);Requiredapplies only whenEnabled.- Answers persist as a nullable boolean per attendee; empty payload → stays null, no Yes/No chosen.
MedicalDeclarationandTreatmentConsentsupportDescriptionmetadata likePhotoConsent.
Real-world example: BU enables
CustomConsent1withText "Chấp thuận chụp ảnh",Required true, and adds a Description. → Collects clear consent. → Enrollment form renders label + helper; submitting without selection → validation fails; after saveCustomConsent1 = truefor that attendee.