Skip to main content

Database Schema

All MoPlan database tables.


Core Plan Tables

training_plans

Main plan configuration table.

training_plans
├── id (uuid, PK)
├── user_id (text, FK → users)
├── name (text) -- "12-Week Strength Program"
├── status (enum: draft, active, completed, paused)
├── periodization_model (enum: linear, undulating, block)
├── split_type (enum: full_body, upper_lower, push_pull_legs, push_pull, bro_split)
├── frequency_per_week (int) -- 3, 4, 5, 6
├── session_duration_minutes (int) -- 45, 60, 75, 90
├── start_date (date)
├── end_date (date)
├── current_week (int)
├── current_phase (text) -- "Accumulation", "Intensification", "Deload"
├── created_at (timestamp)
└── updated_at (timestamp)

plan_goals

What the user wants to achieve.

plan_goals
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── goal_type (enum: strength, hypertrophy, fat_loss, endurance, general_fitness, sport_specific)
├── priority (int) -- 1 = primary, 2 = secondary
├── target_metric (text) -- "bench_press_1rm", "body_weight"
├── current_value (decimal)
├── target_value (decimal)
├── unit (text) -- "lbs", "kg", "%"
├── deadline (date)
└── created_at (timestamp)

plan_constraints

User limitations and preferences.

plan_constraints
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── equipment_access (jsonb) -- ["barbell", "dumbbells", "cables"]
├── available_days (jsonb) -- ["monday", "tuesday", "thursday"]
├── preferred_time_of_day (enum: morning, afternoon, evening, flexible)
├── time_per_session_minutes (int)
├── excluded_exercises (jsonb) -- ["barbell back squat"]
├── preferred_exercises (jsonb) -- ["dumbbell bench press"]
├── injuries_limitations (text)
└── created_at (timestamp)

plan_assessments

Initial assessment data.

plan_assessments
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── experience_level (enum: beginner, intermediate, advanced, elite)
├── years_training (decimal)
├── current_weight (decimal)
├── current_body_fat (decimal)
├── estimated_1rm (jsonb) -- {"bench_press": 185, "squat": 275}
├── sleep_hours_avg (decimal)
├── stress_level (enum: low, moderate, high)
├── occupation_activity (enum: sedentary, light, moderate, active, very_active)
├── nutrition_adherence (enum: poor, fair, good, excellent)
└── created_at (timestamp)

Planning Tables

plan_phases

Training phases (mesocycles).

plan_phases
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── name (text) -- "Accumulation Phase 1"
├── phase_type (enum: accumulation, intensification, realization, deload, transition)
├── week_start (int)
├── week_end (int)
├── intensity_range_low (int) -- 65
├── intensity_range_high (int) -- 75
├── volume_modifier (decimal) -- 1.0, 0.5 for deload
├── rep_range_low (int)
├── rep_range_high (int)
├── focus (text) -- "Building work capacity"
└── created_at (timestamp)

plan_weekly_targets

Weekly volume targets per muscle group.

plan_weekly_targets
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── phase_id (uuid, FK → plan_phases)
├── muscle_group (enum: chest, back, shoulders, biceps, triceps, quads, hamstrings, glutes, calves, core, forearms)
├── target_sets (int) -- 12, 16, 20
├── priority (enum: maintain, grow, specialize)
└── created_at (timestamp)

plan_commitments

Mutual commitments between user and coaches.

plan_commitments
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── party (enum: user, coach)
├── coach_id (uuid, FK → coaches, nullable)
├── commitment_type (enum: attendance, logging, sleep, nutrition, check_in, adjustment, support)
├── description (text) -- "Train at least 4 days per week"
├── frequency (text) -- "daily", "weekly", "as_needed"
├── is_active (boolean)
└── created_at (timestamp)

plan_conversations

Store the planning conversation for context.

plan_conversations
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── phase (enum: goal_discovery, assessment, constraints, collaboration, generation, review)
├── messages (jsonb) -- Array of conversation messages
├── completed_at (timestamp)
└── created_at (timestamp)

Workout Session Tables

workout_sessions

Individual workout instances.

workout_sessions
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── user_id (text, FK → users)
├── scheduled_date (date)
├── started_at (timestamp, nullable)
├── completed_at (timestamp, nullable)
├── status (enum: scheduled, in_progress, completed, skipped, partial)
├── session_type (text) -- "Push Day", "Leg Day"
├── planned_duration_minutes (int)
├── actual_duration_minutes (int, nullable)
├── warmup_completed (boolean, default false)
├── cooldown_completed (boolean, default false)
├── notes (text, nullable)
├── created_at (timestamp)
└── updated_at (timestamp)

session_exercises

Exercises within a workout session.

session_exercises
├── id (uuid, PK)
├── session_id (uuid, FK → workout_sessions)
├── exercise_id (uuid, FK → exercises)
├── order_index (int) -- Exercise order in session
├── exercise_type (enum: warmup, main, cooldown)
├── target_sets (int)
├── target_reps (int)
├── target_weight (decimal, nullable)
├── target_rpe (decimal, nullable) -- 1-10
├── rest_seconds (int)
├── notes (text, nullable) -- Coach tips
└── created_at (timestamp)

session_sets

Individual set performance tracking.

session_sets
├── id (uuid, PK)
├── session_exercise_id (uuid, FK → session_exercises)
├── set_number (int)
├── set_type (enum: warmup, working, dropset, amrap)
├── target_reps (int)
├── completed_reps (int, nullable)
├── target_weight (decimal)
├── completed_weight (decimal, nullable)
├── rir (int, nullable) -- Reps in Reserve (0-5)
├── rpe (decimal, nullable) -- Rate of Perceived Exertion (1-10)
├── completed_at (timestamp, nullable)
├── notes (text, nullable)
└── created_at (timestamp)

session_feedback

Post-session user feedback.

session_feedback
├── id (uuid, PK)
├── session_id (uuid, FK → workout_sessions)
├── overall_energy (int) -- 1-10
├── perceived_difficulty (int) -- 1-10
├── satisfaction (int) -- 1-10
├── muscle_soreness (int) -- 1-10
├── mood_before (int) -- 1-10
├── mood_after (int) -- 1-10
├── notes (text, nullable)
└── created_at (timestamp)

Readiness & Recovery Tables

daily_readiness

Daily readiness check-in.

daily_readiness
├── id (uuid, PK)
├── user_id (text, FK → users)
├── date (date)
├── sleep_hours (decimal)
├── sleep_quality (int) -- 1-10
├── stress_level (int) -- 1-10
├── energy_level (int) -- 1-10
├── motivation_level (int) -- 1-10
├── muscle_soreness (int) -- 1-10
├── overall_score (int) -- Calculated 0-100
├── recommended_intensity (enum: full, reduced, light, rest)
├── coach_note (text, nullable) -- Sage's recommendation
└── created_at (timestamp)

muscle_freshness

Track muscle group recovery status.

muscle_freshness
├── id (uuid, PK)
├── user_id (text, FK → users)
├── muscle_group (enum: chest, back, shoulders, biceps, triceps, quads, hamstrings, glutes, calves, core, forearms)
├── last_trained_at (timestamp)
├── training_volume (int) -- Sets performed
├── training_intensity (decimal) -- Average %1RM
├── freshness_score (int) -- 0-100
└── updated_at (timestamp)

Personal Records Tables

personal_records

Track all types of personal records.

personal_records
├── id (uuid, PK)
├── user_id (text, FK → users)
├── pr_type (enum: weight, volume, streak, consistency, form)
├── exercise_id (uuid, FK → exercises, nullable)
├── rep_range (text, nullable) -- "8rm", "1rm"
├── value (decimal)
├── previous_value (decimal, nullable)
├── unit (text) -- "lbs", "kg", "days", "%"
├── achieved_at (timestamp)
├── session_id (uuid, FK → workout_sessions, nullable)
├── celebrated (boolean, default false)
└── created_at (timestamp)

pr_celebrations

Track PR celebration events.

pr_celebrations
├── id (uuid, PK)
├── pr_id (uuid, FK → personal_records)
├── user_id (text, FK → users)
├── celebration_type (enum: weight_pr, volume_pr, streak_pr, consistency_pr, form_pr)
├── message (text) -- Coach celebration message
├── coach_id (uuid, FK → coaches)
├── displayed_at (timestamp, nullable)
├── dismissed_at (timestamp, nullable)
└── created_at (timestamp)

Deload Tables

deload_periods

Track deload weeks.

deload_periods
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── trigger_type (enum: scheduled, performance, fatigue, stress, user_request)
├── start_date (date)
├── end_date (date)
├── volume_modifier (decimal) -- 0.5 = 50% volume
├── intensity_modifier (decimal) -- 0.6 = 60% intensity
├── focus (text) -- "Technique", "Mobility"
├── notes (text, nullable)
├── completed (boolean, default false)
└── created_at (timestamp)

Progress Tables

plan_progress_snapshots

Periodic progress tracking.

plan_progress_snapshots
├── id (uuid, PK)
├── plan_id (uuid, FK → training_plans)
├── week_number (int)
├── snapshot_date (date)
├── metrics (jsonb) -- {"weight": 180, "bench_1rm": 195, "compliance": 0.85}
├── user_feedback (text)
├── coach_notes (text)
├── energy_level (int) -- 1-10
├── recovery_quality (int) -- 1-10
├── adjustments_made (jsonb) -- [{"type": "volume", "change": "-2 sets chest"}]
└── created_at (timestamp)