Complete technical specification and flow diagram
┌─────────────────────────────────────────────────────────────────────┐
│ STUDIO ONBOARDING FLOW │
└─────────────────────────────────────────────────────────────────────┘
START
│
▼
┌──────────────────────┐
│ STEP 1: ACCOUNT │ Required: Studio name, owner name, email
│ Account Creation │ Optional: Phone, website, address
└──────────────────────┘ Validation: Email format, name length
│
├─► Validates all required fields
├─► Checks email uniqueness
│
▼
┌──────────────────────┐
│ STEP 2: BRAND │ Upload: Logo (PNG/JPG/SVG, max 5MB)
│ Brand Setup │ Select: Primary & secondary colors
└──────────────────────┘ Choose: Brand voice (fun/serious/luxury/energetic/calm)
│
├─► Uploads logo to cloud storage
├─► Generates live preview
│
▼
┌──────────────────────┐
│ STEP 3: REWARDS │ Configure: Member reward (what members earn)
│ Referral Program │ Configure: New client offer (what leads get)
└──────────────────────┘ Define: Trigger (when rewards are given)
│ Optional: Set monthly/per-member limits
├─► Validates reward values
├─► Calculates estimated costs
│
▼
┌──────────────────────┐
│ STEP 4: MEMBERS │ Method 1: CSV upload (bulk import)
│ Member Import │ Method 2: Manual entry (one-by-one)
└──────────────────────┘ Method 3: Invite link (share later)
│
├─► CSV: Parses file, validates emails
├─► Manual: Real-time validation
├─► Generates unique referral codes
│
▼
┌──────────────────────┐
│ STEP 5: ASSETS │ Templates filtered by business type
│ Asset Library │ Auto-branded with logo & colors
└──────────────────────┘ Selectable: Instagram, Facebook, Email, etc.
│
├─► Applies brand to templates
├─► Prepares shareable assets
│
▼
┌──────────────────────┐
│ STEP 6: REVIEW │ Shows summary of all settings
│ Review & Activate │ Readiness checklist
└──────────────────────┘ One-click activation
│
├─► Creates Organization record
├─► Creates Studio record
├─► Updates User role to studio_owner
├─► Creates default Campaign
├─► Bulk creates Member records
├─► Generates referral codes
├─► Creates AuditLog entry
│
▼
┌──────────────────────┐
│ SUCCESS! 🎉 │ Redirects to Studio Dashboard
│ Program Active │ Shows next steps guide
└──────────────────────┘ Sends welcome email
END
Studio Name
Minimum 2 characters, maximum 100 characters
Valid email format (regex: ^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$)
Phone (optional)
US format: (XXX) XXX-XXXX or XXX-XXX-XXXX
Website (optional)
Must start with http:// or https://
ZIP Code (optional)
5 digits or 5+4 format (XXXXX or XXXXX-XXXX)
Logo File
Accepted: PNG, JPG, SVG | Max size: 5MB | Recommended: Square, transparent background
Colors
Valid hex format (#RRGGBB)
Reward Values
Must be positive integers (minimum: 1)
Reward Trigger
Default: "paid_member" (recommended to prevent fraud)
CSV Format
Required columns: name, email | Optional: phone
Email Validation
Checks for duplicates and valid format before import
{
"onboardingData": {
"account": {
"studioName": "string (required, 2-100 chars)",
"ownerName": "string (required, 2-100 chars)",
"email": "string (required, valid email)",
"phone": "string (optional, US format)",
"website": "string (optional, valid URL)",
"address": {
"street": "string (optional)",
"city": "string (optional)",
"state": "string (optional)",
"zip": "string (optional, 5 or 9 digits)"
},
"businessType": "enum (required): gym | yoga_studio | martial_arts | pilates | crossfit | dance | boutique_fitness | other"
},
"brand": {
"logoUrl": "string (optional, uploaded file URL)",
"primaryColor": "string (required, hex format)",
"secondaryColor": "string (required, hex format)",
"brandVoice": "enum (required): fun | serious | luxury | energetic | calm"
},
"program": {
"memberRewardType": "enum (required): free_class | free_month | gift_card | merchandise | cash | discount",
"memberRewardValue": "number (required, min: 1)",
"newClientRewardType": "enum (required): free_trial | discount | free_week | free_class | waived_fee",
"newClientRewardValue": "number (required, min: 1)",
"rewardTrigger": "enum (required): lead | trial | paid_member",
"maxRewardsPerMonth": "number | null (optional)",
"maxRewardsPerMember": "number | null (optional)"
},
"members": [
{
"name": "string (required)",
"email": "string (required, valid email)",
"phone": "string (optional)"
}
],
"selectedAssets": [
"string (asset IDs)"
]
}
}✓ "Logo uploaded successfully!"
✓ "Member added!"
✓ "Imported 15 members!"
✓ "🎉 Studio activated successfully!"
Step 1: "Create Your Studio Account" → "Tell us about your fitness business"
Step 2: "Brand Your Experience" → "Make the referral program feel like yours"
Step 3: "Design Your Referral Program" → "Set rewards that motivate members to share"
Step 4: "Import Your Members" → "Add existing members to start your referral program"
Step 5: "Choose Your Marketing Assets" → "Select pre-made templates your members can share"
Step 6: "Review & Activate" → "Confirm your settings and launch your referral program"
💡 Logo tip: "Use a square logo with transparent background for best results"
💡 Reward trigger: "Studios that reward on 'Paid Membership' see 73% fewer fraudulent referrals"
💡 CSV import: "Required columns: name, email | Optional: phone"
💡 Assets: "All assets will automatically include your logo and brand colors"
Navigation: "Continue" → "Back" → "Activate Program"
Brand Voice: Fun: "Share the Love" | Serious: "Refer a Colleague" | Luxury: "Extend an Invitation"
Member Import: "Add Member" | "Clear All" | "Choose CSV File" | "Download Template"
Assets: "Select All" | "Deselect All"
• All onboarding data stored in local component state
• No persistence until final activation (prevents incomplete records)
• Future: Save to localStorage for "resume later" functionality
• Activation is atomic: all creates happen in sequence
• If any step fails, previous steps remain (no automatic rollback yet)
• AuditLog created for compliance tracking
• User role updated last to ensure permissions align
• File uploads validated for type and size
• Email addresses validated client-side and server-side
• Referral codes generated cryptographically random
• Future: Add rate limiting on activation attempts