Architecture, API reference, and deployment documentation
Version: 1.0.0
Last Updated: 11 April 2026
Document Type: Comprehensive Technical Specification
Phoenix Suite is a multi-tenant Software-as-a-Service (SaaS) platform for managing gyms, dojos, martial arts schools, and fitness studios. It provides a complete business management solution including student/member management, class scheduling, attendance tracking, point of sale, subscription billing, marketing, public websites, grading/belt progression, exercise program design, accounting integration, and reporting.
The platform is built with a modular licensing architecture where organisations selectively purchase modules based on their needs, managed through a centralised license portal.
| Component | Technology | Port | Purpose |
| Database | PostgreSQL 16 | 5432 | Primary data store |
| API Server | Node.js + Express | 4000 | REST API backend |
| Admin Portal | React 18 | 3002 | Staff/admin web application |
| License Portal | React 18 | 3001 | Super-admin license management |
| Public Site | React 18 | 3003 | Per-org public websites |
Backend:
pg driver (no ORM)Frontend:
Every data table includes an org_id column referencing the organizations table. The scopeToOrg middleware extracts the org ID from the JWT token and attaches it to req.orgId. All queries filter by org_id to ensure complete data isolation between organisations.
Token Strategy:
User Roles:
super_admin: Platform owner, manages licenses across all orgsadmin: Organisation owner, full org managementstaff: Instructor/trainer, limited by permission tagsstudent: Member, self-service portal accessPermission Tags (staff_permissions table):
admin: Full organisation accesspersonal_trainer: Fitness programs, client managementdiscipline_instructor: Per-discipline class/grading managementAdditional Auth:
| Module | Enum Value | Description |
| Base | base | Always included. Students, classes, payments, messaging, contracts, forms, inventory, equipment |
| Martial Arts | martial_arts | Multi-discipline rank progression, gradings, syllabus, belt/sash/patch systems |
| Fitness | fitness | Exercise library, plan builder, programs, body metrics, training goals |
| Marketing | marketing | Email/SMS campaigns, events, templates, notification log |
| Website | website | Public-facing website CMS, blog, trial signup, contact forms |
Modules are gated by the requireModule(moduleType) middleware. The License Portal (super_admin) issues module licenses per organisation with configurable student/staff caps, pricing, and expiry dates.
The database evolves through numbered migration files (001-025) applied in order:
| Migration | Tables/Changes |
| 001 | Core: organizations, users, student_profiles, subscriptions, payments, account_ledger, classes, class_enrollments, class_attendance, belt_records, gradings, body_measurements, training_programs, access_tokens, equipment, inventory, conversations, messages, contracts, forms, licenses |
|---|---|
| 002 | Exercise library: exercises, exercise_plans, exercise_plan_sections, exercise_plan_items, student_exercise_plans, student_exercise_log |
| 003 | Class sessions: class_sessions, class_session_attendance, waitlist support on enrollments |
| 004 | Belt progression: belt_requirements, syllabus_items, student_syllabus_progress |
| 005 | Class plan history |
| 006 | Multi-discipline: martial_art_disciplines, discipline_ranks, student_disciplines. Renamed belt_records→rank_records, belt_requirements→rank_requirements. Dropped belt_rank enum. |
| 007 | Programs: programs, program_plans, program_assignments, practitioner_access |
| 008 | Exercise groups: exercise_item_groups (supersets, circuits) |
| 009 | Rank dan/bar field |
| 010 | Rank stripe field |
| 011 | Subscription plans: subscription_plans, plan_discount_rules |
| 012 | Plan-class linking: plan_classes, class enrollment source tracking |
| 013 | Staff permissions: staff_permissions with permission tags |
| 014 | Inventory variants: inventory_variants (size/stock breakdown) |
| 015 | Shop/POS: org_order_sequences, orders, order_items, refunds, refund_items. GST/account settings on org. |
| 016 | Grading invitations: testing_fee, invitation_status, payment linking |
| 017 | Tenancy hardening: added org_id to all join tables missing it |
| 018 | Per-org rate limiting settings |
| 019 | Attendance & metrics: student_preferences, kiosk_sessions, measurement_goals, enhanced body measurements |
| 020 | Stripe integration: Stripe config on org, payment references across tables |
| 021 | Public site: site_settings, blog_posts, trial_signups, contact_submissions, instructor_profiles |
| 022 | Marketing: notification_log, notification_templates, marketing_campaigns, special_events, event_bookings |
| 023 | Enhanced contracts: merge fields, witness/guardian, form field types |
| 024 | Contract/form assignments |
| 025 | Accounting: accounting_config, account_mappings, journal_entries, depreciation_schedules |
``
organizations
├── users (role: super_admin, admin, staff, student)
│ └── staff_permissions
├── student_profiles
│ ├── student_subscriptions → subscription_plans
│ ├── student_disciplines → martial_art_disciplines → discipline_ranks
│ ├── rank_records (progression history)
│ ├── class_enrollments → classes → class_sessions → class_session_attendance
│ ├── program_assignments → programs → program_plans → exercise_plans
│ ├── body_measurements, measurement_goals
│ ├── grading_candidates → gradings
│ ├── contract_signatures, form_submissions
│ ├── event_bookings → special_events
│ └── orders → order_items → inventory → inventory_variants
├── martial_art_disciplines → discipline_ranks
├── classes → class_sessions → class_session_attendance
├── subscription_plans → plan_discount_rules, plan_classes
├── programs → program_plans → exercise_plans → sections → groups → items → exercises
├── inventory → inventory_variants, inventory_transactions
├── marketing_campaigns → notification_log
├── site_settings, blog_posts, trial_signups, contact_submissions
├── accounting_config, account_mappings, journal_entries, depreciation_schedules
└── licenses (per-module with caps, pricing, expiry)
`
| File | Mount Point | Auth | Purpose |
| auth.js | /api/auth | Public/Auth | Login, register, refresh, logout, me |
| students.js | /api/students | Auth+Staff | Student CRUD with subscription management |
| resources.js | /api/* | Auth | Equipment, inventory, classes, contracts, forms, messages, payments, martial arts, fitness, org settings, staff management |
| exercises.js | /api/exercises, /api/exercise-plans | Auth | Exercise library, plan builder with sections/groups/items |
| disciplines.js | /api/disciplines | Auth+MA | Discipline and rank CRUD, student enrollment |
| belt-progression.js | /api/belt-progression | Auth+MA | Requirements, syllabus, eligibility, readiness, gradings with invitations |
| programs.js | /api/programs | Auth | Program CRUD, plan linking, student assignment |
| subscription-plans.js | /api/subscription-plans | Auth | Plan templates, discount rules, class linking, price calculation |
| shop.js | /api/shop | Auth | POS orders, products, refunds, receipts, account balance |
| stripe.js | /api/stripe | Auth/Webhook | Checkout sessions, subscription billing, customer portal, webhooks |
| checkin.js | /api/checkin | Auth/Kiosk | Kiosk management, photo-tap check-in, token scan, self check-in, attendance dashboard, access tokens, body metrics, measurement goals, student preferences |
| marketing.js | /api/marketing | Auth+Mkt | Campaigns, events, bookings, templates, notification log, quick send |
| public.js | /api/public | Public | Site data, blog, trial signup, contact forms |
| site-admin.js | /api/site-admin | Auth+Web | CMS content, blog CRUD, trial leads, contacts, instructors |
| contracts-forms.js | /api/cf | Auth | Contract signing with merge fields, form submission with field validation, assignments, outstanding tracking, template seeding |
| reports.js | /api/reports | Auth+Admin | 7 report types, CSV export, PDF export |
| accounting.js | /api/accounting | Auth+Admin | Config, mappings, journal generation, sync, depreciation |
| practitioner-auth.js | /api/practitioner | Public/Auth | Code generation, practitioner login, therapeutic program access |
| licenses.js | /api/licenses | SuperAdmin | License management across all organisations |
— Security headers — Configurable CORS origins — JSON body parsing (10MB limit) — Request logging — Per-org rate limiting, scopeToOrg, requireRole(), requireModule()| Page | Route | Description |
| DashboardPage | /dashboard | Overview stats and quick actions |
| StudentsPage | /students | Student list with plan-based subscription picker |
| StudentDetailPage | /students/:id | Profile, rank history, syllabus checklist, body metrics, subscriptions |
| PaymentsPage | /payments | Overview, subscription plans manager, subscriptions, transaction history |
| MessagesPage | /messages | 2-way messaging with auto-refresh |
| ContractsPage | /contracts | Contract templates with merge fields, signing, assignments |
| FormsPage | /forms | Form builder with 11 field types, submissions, review |
| ClassesPage | /classes | Class CRUD, weekly schedule, sessions, enrollment, attendance, workout assignment |
| ExerciseLibraryPage | /exercises | Searchable exercise catalog |
| MartialArtsPage | /martial-arts/* | Multi-discipline: ranks, readiness, gradings, syllabus, requirements, plans |
| FitnessPage | /fitness/* | Programs, exercise plans, body metrics |
| EquipmentPage | /equipment | Equipment lifecycle management |
| InventoryPage | /inventory | Stock with colour/brand/size variants |
| ShopPage | /shop | POS with cart, checkout, orders, refunds |
| ReportsPage | /reports | 7 report types with CSV/PDF export |
| AccountingPage | /accounting | Xero/MYOB/QBO/CSV, account mapping, journals, depreciation |
| MarketingPage | /marketing/* | Campaigns, events, templates, send log |
| WebsitePage | /website | CMS: branding, content, SEO, blog, instructors, leads |
| SettingsPage | /settings | Org details, GST, Stripe, email, SMS, attendance, rate limits, kiosk devices, staff management with permissions |
| Page | Route | Description |
| StudentDashboard | /student | Overview |
| StudentClasses | /student/classes | Schedule, enrolled classes with self check-in, attendance history |
| StudentGradings | /student/gradings | Grading invitations, fee payment, results |
| StudentPrograms | /student/programs | Assigned exercise programs, practitioner access codes |
| StudentStore | /student/store | Browse/purchase inventory with cart |
| StudentDocuments | /student/documents | Pending contracts (sign with canvas), forms (fill with field types), submission history |
| StudentProfile | /student/profile | Personal details |
| StudentMessages | /student/messages | 2-way messaging with staff |
| StudentBilling | /student/billing | Payment history |
| Page | Route | Description |
| LoginPage | /login | Email/password login |
| KioskPage | /kiosk | Photo-tap/RFID check-in screen |
| WorkoutDisplayPage | /workout-display | Group workout display + Tabata/AMRAP/EMOM/countdown timers |
`
Exercise Library (shared catalog)
└── Exercise Plans
└── Sections (Warmup, Main, Cooldown)
├── Exercise Groups (superset, circuit, straight)
│ ├── Group config: rounds, rest between rounds, timed/reps
│ └── Exercises: sets, reps, duration, rest, weight notes
└── Standalone Exercises
Programs (containers)
├── Type: personal, group, therapeutic
├── Linked Plans via program_plans (day labels)
└── Assigned to students via program_assignments
`
5 containers: db (PostgreSQL 16), api (Node.js), frontend (Nginx), license-portal (Nginx), public-site (Nginx)
`
DATABASE_URL, JWT_SECRET, JWT_EXPIRY, CORS_ORIGIN, PORT,
LICENSE_MASTER_KEY, XERO_CLIENT_ID, XERO_CLIENT_SECRET,
MYOB_CLIENT_ID, MYOB_CLIENT_SECRET, QBO_CLIENT_ID, QBO_CLIENT_SECRET
`
2GB RAM, 2 vCPU, 20GB SSD. Estimated cost: $12-24/month on DigitalOcean/Vultr.
`
phoenix-suite/
├── docker-compose.yml
├── .env.example
├── docs/
│ ├── TECHNICAL_SPECIFICATION.md
│ └── USER_GUIDE.md
├── backend/
│ ├── Dockerfile
│ ├── package.json
│ ├── migrations/ (001-025)
│ └── src/
│ ├── index.js
│ ├── config/db.js
│ ├── middleware/
│ │ ├── auth.js
│ │ ├── errors.js
│ │ └── rateLimiter.js
│ ├── routes/
│ │ ├── auth.js, students.js, resources.js
│ │ ├── exercises.js, disciplines.js, belt-progression.js
│ │ ├── programs.js, subscription-plans.js
│ │ ├── shop.js, stripe.js
│ │ ├── checkin.js, marketing.js
│ │ ├── public.js, site-admin.js
│ │ ├── contracts-forms.js, reports.js, accounting.js
│ │ ├── practitioner-auth.js, licenses.js
│ │ └── ...
│ └── utils/
│ ├── discount-calculator.js
│ ├── plan-enrollment.js
│ ├── stripe-client.js
│ ├── email-service.js
│ ├── sms-service.js
│ ├── journal-generator.js
│ └── accounting-client.js
├── frontend/
│ ├── Dockerfile, nginx.conf, package.json
│ ├── public/ (PhoenixLogo.png, favicons, index.html)
│ └── src/
│ ├── index.js, App.js, api.js, responsive.css
│ ├── context/ (AuthContext.js, ThemeContext.js)
│ ├── components/ (UI.js, PlanBuilder.js, SubscriptionPlansManager.js, WeeklySchedule.js)
│ └── pages/
│ ├── AdminLayout.js, StudentLayout.js, LoginPage.js
│ ├── AdminPages.js (Payments, Messages, Contracts, Forms, Inventory, Equipment, Classes, MartialArts, Fitness, Settings)
│ ├── DashboardPage.js, StudentsPage.js, StudentDetailPage.js
│ ├── ExerciseLibraryPage.js, ShopPage.js, ReportsPage.js
│ ├── AccountingPage.js, MarketingPage.js, WebsitePage.js
│ ├── KioskPage.js, WorkoutDisplayPage.js
│ └── student/ (Dashboard, Classes, Gradings, Programs, Store, Documents, Profile, Messages, Billing)
├── license-portal/ (separate React app)
│ └── src/ (App.js, api.js)
└── public-site/ (separate React app)
└── src/ (App.js with template engine + SEO)
``
This document describes the complete system as built. For usage instructions, see the User Guide.