User Accounts & Onboarding
Authentication, role selection, and multi-step onboarding flows for both trainers and clients. This feature covers the entire journey from first visit to fully completed profile.
Overview
User Accounts & Onboarding is the foundational feature of My Trainer Connect. Every user begins by creating an account via email, Google, or Facebook OAuth. During signup, users select their role — either trainer or client — which determines their entire platform experience, dashboard layout, and available features.
After authentication, users enter a role-specific multi-step onboarding flow. Clients complete a 4-step fitness assessment questionnaire covering goals, experience, training preferences, and profile details. Trainers complete a 5-step professional setup including profile information, credential uploads, intro video, services/pricing, and final verification.
The system uses Supabase Auth for identity management with Row Level Security (RLS) enforcing data isolation. Auth state is synced to React Query cache via a realtime listener, and protected routes redirect unauthenticated users to login. OAuth identity linking preserves existing roles when a user connects additional social providers.
User Stories
Client Stories
As a client, I want to sign up with my email or social account so that I can quickly create an account without friction.
As a client, I want to complete a fitness assessment during onboarding so that trainers understand my goals, experience level, and preferences.
As a client, I want to select and prioritize my fitness goals with drag-and-drop so that my top priorities are clear to matched trainers.
As a client, I want to specify my budget range, location, and preferred training format so that I'm matched with compatible trainers.
As a client, I want to update my profile information after onboarding so that my preferences stay current.
Trainer Stories
As a trainer, I want to create a professional profile with my bio, specialties, and experience so that clients can evaluate my expertise.
As a trainer, I want to upload my certifications and degrees so that clients can verify my credentials.
As a trainer, I want to record an intro video so that potential clients get a personal feel for my coaching style.
As a trainer, I want to set my rates for online, in-person, and monthly coaching so that clients know my pricing upfront.
As a trainer, I want to select add-on services (meal plans, form feedback, 24/7 support) so that I can differentiate my offerings.
Admin Stories
As an admin, I want to view all users with their roles and onboarding status so that I can monitor platform adoption.
As an admin, I want to manage the verification workflow for trainer profiles so that only qualified trainers display the verified badge.
Data Model
| Table | Key Columns | Description |
|---|---|---|
| users | id, name, email, role, avatar_url, stripe_customer_id | Synced from auth.users via trigger. Role enum: admin, member, trainer, client. |
| client_profiles | user_id, goals, experience_level, weekly_frequency, obstacles, training_format, gender_preference, communication_styles, budget_min, budget_max, location, focus_areas, languages, onboarding_step, onboarding_completed | Fitness assessment data from client onboarding. Includes PostGIS location column. |
| trainer_profiles | user_id, bio, headline, specialties, experience_years, certifications, degrees, intro_video_url, training_formats, online_rate, in_person_rate, monthly_coaching_rate, add_ons, session_duration_min, location, onboarding_step, onboarding_completed, is_verified | Professional profile with pricing, credentials, and verification status. Includes PostGIS location and tsvector search columns. |
Client Onboarding — 4 Steps
Fitness Goals
Select and prioritize goals with drag-and-drop ordering. Options: weight loss, muscle building, strength, endurance, general fitness, sport-specific, injury recovery, flexibility.
Schema: clientProfileStep1Schema — goals: string[] (min 1)
Experience & Challenges
Experience level (beginner/intermediate/advanced), weekly frequency (1-7), obstacles (motivation, time, form, nutrition, routine, injury prevention, plateaus, gym intimidation).
Schema: clientProfileStep2Schema — experience_level, weekly_frequency, obstacles[]
Training Preferences
Training format (online/in-person/hybrid), location (country/state/city via Geo API), gender preference, communication styles, budget range, session duration (15-180 min).
Schema: clientProfileStep3Schema — training_format, location_*, gender_preference, communication_styles[], budget_min/max
Profile Completion
Focus areas, language preferences, date of birth (DatePicker), biological sex, height (cm), weight (kg), additional info (max 2000 chars). Marks assessment_completed and onboarding_completed.
Schema: clientProfileStep4Schema — focus_areas[], languages[], date_of_birth, biological_sex, height_cm, weight_kg
Trainer Onboarding — 5 Steps
Profile
Name, bio (max 2000), headline (max 200), profile picture, experience years (0-50), specialties (min 1). 16+ specialty options from lookup_values.
Schema: trainerProfileStep1Schema
Credentials
Certifications (name, issuer, year, expiry, file upload) and degrees (institution, degree name, field, year). Supports NASM, ACSM, ACE, NSCA, ISSA, etc.
Schema: trainerProfileStep2Schema
Intro Video
Personal introduction video URL. Optional step — trainers can skip and add later. URL validated as valid URL format or empty string.
Schema: trainerProfileStep3Schema
Services & Pricing
Training formats (online/in-person/hybrid, min 1), rates (online, in-person, monthly coaching), session duration (15-180 min), location, add-ons (weekly check-ins, meal plans, form feedback, 24/7 support, etc.).
Schema: trainerProfileStep4Schema
Complete
Profile verification step. Sets onboarding_completed = true and records onboarding_completed_at timestamp. Redirects to trainer dashboard.
Triggers: onboarding_completed, onboarding_completed_at
Screens & Routes
| Route | File | Description |
|---|---|---|
| /login | src/routes/_auth/login.tsx | Email + password login, OAuth buttons (Google, Facebook), link to signup/forgot password |
| /signup | src/routes/_auth/signup.tsx | Name, email, password, confirm password, role selector (trainer/client), terms checkbox |
| /forgot-password | src/routes/_auth/forgot-password.tsx | Email input for password reset link |
| /reset-password | src/routes/_authed/reset-password.tsx | New password + confirm after OTP verification |
| /onboarding | src/routes/_authed/onboarding/ | Multi-step onboarding with role-specific flows (client vs trainer) |
| /settings | src/routes/_authed/_onboarded/settings.tsx | Profile editing, email change, password update |
| /profile | src/routes/_authed/_onboarded/profile.tsx | View own profile (trainer or client) |
Acceptance Criteria
API Surface
Server Functions
| Function | Method | Input Schema | Source |
|---|---|---|---|
| getUser | GET | none | src/api/auth/functions.ts |
| getSession | GET | none | src/api/auth/functions.ts |
| loginFn | POST | loginSchema | src/api/auth/functions.ts |
| signupFn | POST | signupSchema | src/api/auth/functions.ts |
| logoutFn | POST | none | src/api/auth/functions.ts |
| forgotPasswordFn | POST | forgotPasswordSchema | src/api/auth/functions.ts |
| resetPasswordFn | POST | resetPasswordSchema | src/api/auth/functions.ts |
| updateEmailFn | POST | updateEmailSchema | src/api/auth/functions.ts |
| updatePasswordFn | POST | updatePasswordSchema | src/api/auth/functions.ts |
| setUserRoleFn | POST | { role: 'trainer' | 'client' } | src/api/auth/functions.ts |
| exchangeOAuthCodeFn | GET | { code: string } | src/api/auth/functions.ts |
| verifyOtpFn | GET | { token_hash, type } | src/api/auth/functions.ts |
| verifyEmailChangeOtpFn | POST | verifyEmailChangeOtpSchema | src/api/auth/functions.ts |
| getClientProfile | GET | none | src/api/client-profile/functions.ts |
| upsertClientProfile | POST | upsertClientProfileSchema | src/api/client-profile/functions.ts |
| updateClientProfile | POST | updateClientProfileSchema | src/api/client-profile/functions.ts |
| getTrainerProfile | GET | none | src/api/trainer-profile/functions.ts |
| upsertTrainerProfile | POST | upsertTrainerProfileSchema | src/api/trainer-profile/functions.ts |
| updateTrainerProfile | POST | updateTrainerProfileSchema | src/api/trainer-profile/functions.ts |
React Query Hooks
| Hook | Type | Source |
|---|---|---|
| userQueryOptions | queryOptions | src/api/auth/hooks.ts |
| sessionQueryOptions | queryOptions | src/api/auth/hooks.ts |
| useLogin | useMutation | src/api/auth/hooks.ts |
| useSignup | useMutation | src/api/auth/hooks.ts |
| useLogout | useMutation | src/api/auth/hooks.ts |
| useForgotPassword | useMutation | src/api/auth/hooks.ts |
| useResetPassword | useMutation | src/api/auth/hooks.ts |
| useSetUserRole | useMutation | src/api/auth/hooks.ts |
| useUpdateEmail | useMutation | src/api/auth/hooks.ts |
| useUpdatePassword | useMutation | src/api/auth/hooks.ts |
| useAuthListener | effect hook | src/api/auth/hooks.ts |
| clientProfileQueryOptions | queryOptions | src/api/client-profile/hooks.ts |
| useUpsertClientProfile | useMutation | src/api/client-profile/hooks.ts |
| useUpdateClientProfile | useMutation | src/api/client-profile/hooks.ts |
| trainerProfileQueryOptions | queryOptions | src/api/trainer-profile/hooks.ts |
| useUpsertTrainerProfile | useMutation | src/api/trainer-profile/hooks.ts |
| useUpdateTrainerProfile | useMutation | src/api/trainer-profile/hooks.ts |
Current Status
- Email + password signup/login
- Google & Facebook OAuth
- Role selection (trainer/client)
- Forgot / reset password flow
- Client 4-step onboarding
- Trainer 5-step onboarding
- Profile update (settings)
- Email change with OTP
- Password change
- Auth state listener
- Route guards (protected + guest-only)
- OAuth identity linking
- Avatar upload to Supabase Storage
- Trainer verification workflow
- Email verification for new signups
- Account deletion
- Admin user management panel
- Deactivation / suspension