Implementation Guide
Algorithm pseudocode, integration plan, and remaining tasks. Status: Planning - Research complete, implementation pending
Plan Generation Algorithm
High-Level Flow
async function generatePlan(userId: string, wizardData: WizardData): Promise<Plan> {
// Phase 1: Validate and prepare inputs
const input = validateAndPrepare(wizardData);
// Phase 2: Apply the 10 Pillars
const planParameters = applyPillars(input);
// Phase 3: Build structure
const structure = buildPlanStructure(planParameters);
// Phase 4: Select exercises
const sessions = await buildSessions(structure, input);
// Phase 5: Apply periodization
const periodizedPlan = applyPeriodization(sessions, input);
// Phase 6: Add deloads
const finalPlan = scheduleDeloads(periodizedPlan, input);
// Phase 7: Save to database
return await savePlan(userId, finalPlan);
}
Phase 2: Apply the 10 Pillars
interface PlanParameters {
weeklyVolume: number; // Pillar 1
intensityRange: [number, number]; // Pillar 2
frequency: number; // Pillar 3
restPeriods: RestConfig; // Pillar 4
exerciseOrder: 'compound_first' | 'pre_exhaust'; // Pillar 5
progressionModel: ProgressionModel; // Pillar 6
defaultTempo: string; // Pillar 7
periodizationType: PeriodizationType; // Pillar 8
deloadFrequency: number; // Pillar 9
recoveryNotes: string[]; // Pillar 10
}
function applyPillars(input: PlanGenerationInput): PlanParameters {
return {
// Pillar 1: Volume
weeklyVolume: calculateVolume(input.experience, input.goal, input.recovery),
// Pillar 2: Intensity
intensityRange: getIntensityRange(input.goal),
// Pillar 3: Frequency
frequency: input.frequency,
// Pillar 4: Rest Periods
restPeriods: {
compounds: input.goal === 'strength' ? 180 : 120,
isolation: 60,
autoRegulated: true,
},
// Pillar 5: Exercise Order
exerciseOrder: 'compound_first',
// Pillar 6: Progressive Overload
progressionModel: selectProgressionModel(input.experience),
// Pillar 7: Tempo
defaultTempo: getDefaultTempo(input.goal),
// Pillar 8: Periodization
periodizationType: selectPeriodization(input.experience, input.goal),
// Pillar 9: Deload
deloadFrequency: getDeloadFrequency(input.experience, input.recovery),
// Pillar 10: External Factors
recoveryNotes: generateRecoveryNotes(input.recovery, input.assessment),
};
}
Helper Functions
// Pillar 1: Volume Calculator
function calculateVolume(
experience: ExperienceLevel,
goal: Goal,
recovery: RecoveryCapacity
): number {
const baseVolume: Record<ExperienceLevel, number> = {
beginner: 10,
intermediate: 14,
advanced: 18,
returning: 12,
};
const recoveryMultiplier: Record<RecoveryCapacity, number> = {
low: 0.8,
moderate: 1.0,
high: 1.1,
};
const goalModifier: Record<Goal, number> = {
body_recomposition: 1.0,
hypertrophy: 1.1,
strength: 0.9,
fat_loss: 0.85,
};
return Math.round(
baseVolume[experience] *
recoveryMultiplier[recovery] *
(goalModifier[goal] || 1.0)
);
}
// Pillar 2: Intensity Range
function getIntensityRange(goal: Goal): [number, number] {
const ranges: Record<Goal, [number, number]> = {
body_recomposition: [65, 80],
hypertrophy: [65, 75],
strength: [80, 90],
power: [30, 60],
fat_loss: [50, 70],
};
return ranges[goal] || [65, 75];
}
// Pillar 6: Progression Model
function selectProgressionModel(experience: ExperienceLevel): ProgressionModel {
if (experience === 'beginner') {
return {
type: 'linear',
weeklyIncrease: 2.5, // lbs
deloadOnMiss: 10, // % reduction
};
}
return {
type: 'double_progression',
repRange: [8, 12],
loadIncreasePercent: 5,
};
}
// Pillar 7: Default Tempo
function getDefaultTempo(goal: Goal): string {
const tempos: Record<Goal, string> = {
hypertrophy: '3-1-2-0',
strength: '2-1-X-0',
power: '1-0-X-0',
metabolic: '2-0-2-0',
body_recomposition: '3-1-2-0',
};
return tempos[goal] || '3-1-2-0';
}
// Pillar 8: Periodization Type
function selectPeriodization(
experience: ExperienceLevel,
goal: Goal
): PeriodizationType {
if (experience === 'beginner') {
return 'linear';
}
if (goal === 'strength') {
return 'daily_undulating';
}
return 'weekly_undulating';
}
// Pillar 9: Deload Frequency
function getDeloadFrequency(
experience: ExperienceLevel,
recovery: RecoveryCapacity
): number {
const base: Record<ExperienceLevel, number> = {
beginner: 8,
intermediate: 5,
advanced: 4,
returning: 6,
};
// Reduce frequency if recovery is low
const adjustment = recovery === 'low' ? -1 : 0;
return base[experience] + adjustment;
}
Split Selection Logic
type SplitType = 'full_body' | 'upper_lower' | 'ppl' | 'pplul';
interface Split {
type: SplitType;
sessions: SessionTemplate[];
daysPerWeek: number;
}
function selectSplit(frequency: number, goal: Goal): Split {
// 3 days: Full body
if (frequency <= 3) {
return {
type: 'full_body',
daysPerWeek: frequency,
sessions: [
{ name: 'Full Body A', muscleGroups: ['chest', 'back', 'legs', 'shoulders'] },
{ name: 'Full Body B', muscleGroups: ['chest', 'back', 'legs', 'arms'] },
{ name: 'Full Body C', muscleGroups: ['chest', 'back', 'legs', 'shoulders'] },
].slice(0, frequency),
};
}
// 4 days: Upper/Lower (most recommended for recomp)
if (frequency === 4) {
return {
type: 'upper_lower',
daysPerWeek: 4,
sessions: [
{ name: 'Upper A', muscleGroups: ['chest', 'shoulders', 'triceps', 'back', 'biceps'] },
{ name: 'Lower A', muscleGroups: ['quads', 'hamstrings', 'glutes', 'calves'] },
{ name: 'Upper B', muscleGroups: ['back', 'biceps', 'chest', 'shoulders', 'triceps'] },
{ name: 'Lower B', muscleGroups: ['glutes', 'hamstrings', 'quads', 'calves'] },
],
};
}
// 5 days: PPLUL
if (frequency === 5) {
return {
type: 'pplul',
daysPerWeek: 5,
sessions: [
{ name: 'Push', muscleGroups: ['chest', 'shoulders', 'triceps'] },
{ name: 'Pull', muscleGroups: ['back', 'biceps', 'rear_delts'] },
{ name: 'Legs', muscleGroups: ['quads', 'hamstrings', 'glutes', 'calves'] },
{ name: 'Upper', muscleGroups: ['chest', 'back', 'shoulders', 'arms'] },
{ name: 'Lower', muscleGroups: ['quads', 'hamstrings', 'glutes', 'calves'] },
],
};
}
// 6 days: PPL
return {
type: 'ppl',
daysPerWeek: 6,
sessions: [
{ name: 'Push A', muscleGroups: ['chest', 'shoulders', 'triceps'] },
{ name: 'Pull A', muscleGroups: ['back', 'biceps', 'rear_delts'] },
{ name: 'Legs A', muscleGroups: ['quads', 'hamstrings', 'glutes', 'calves'] },
{ name: 'Push B', muscleGroups: ['shoulders', 'chest', 'triceps'] },
{ name: 'Pull B', muscleGroups: ['back', 'biceps', 'rear_delts'] },
{ name: 'Legs B', muscleGroups: ['hamstrings', 'glutes', 'quads', 'calves'] },
],
};
}
Periodization Implementation
interface Phase {
name: string;
weekStart: number;
weekEnd: number;
volumeMultiplier: number;
intensityMultiplier: number;
rpeTarget: number;
focus: string;
}
function buildPeriodization(
totalWeeks: number,
type: PeriodizationType,
goal: Goal
): Phase[] {
if (type === 'linear') {
return buildLinearPeriodization(totalWeeks);
}
if (type === 'daily_undulating') {
return buildDUP(totalWeeks);
}
// Block periodization for body recomp
if (goal === 'body_recomposition') {
return buildRecompPeriodization(totalWeeks);
}
return buildWeeklyUndulating(totalWeeks);
}
function buildRecompPeriodization(totalWeeks: number): Phase[] {
// 16-week recomp structure from research
return [
{
name: 'Foundation',
weekStart: 1,
weekEnd: 4,
volumeMultiplier: 0.8,
intensityMultiplier: 0.9,
rpeTarget: 6.5,
focus: 'Build work capacity, establish baseline',
},
{
name: 'Accumulation',
weekStart: 5,
weekEnd: 8,
volumeMultiplier: 1.1,
intensityMultiplier: 1.0,
rpeTarget: 7.5,
focus: 'Maximize muscle stimulus, initiate fat loss',
},
{
name: 'Intensification',
weekStart: 9,
weekEnd: 12,
volumeMultiplier: 1.0,
intensityMultiplier: 1.1,
rpeTarget: 8.5,
focus: 'Strength expression, accelerate fat loss',
},
{
name: 'Realization',
weekStart: 13,
weekEnd: totalWeeks,
volumeMultiplier: 0.8,
intensityMultiplier: 0.95,
rpeTarget: 7.5,
focus: 'Lock in gains, recover, assess progress',
},
];
}
Implementation Order
Phase 1: Database (Week 1)
- Create Drizzle schema for exercise database
- Run migrations
- Create seed data for ~50 initial exercises
- Create seed data for intensity techniques
Phase 2: Core Algorithm (Week 2)
- Implement
calculateVolume()function - Implement
selectSplit()function - Implement exercise selection logic
- Implement session builder
Phase 3: Periodization (Week 3)
- Implement periodization builder
- Implement deload scheduler
- Implement progression model
Phase 4: API Endpoints (Week 4)
-
/api/v1/plans/generate- Generate plan options -
/api/v1/plans/[planId]/sessions- Get session details -
/api/v1/exercises- Exercise CRUD -
/api/v1/exercises/[exerciseId]/modes- Execution modes
Phase 5: UI Integration (Week 5)
- Step 7: Summary & Confirmation UI
- Step 8: Coach Collaboration UI
- Step 9: Full Session Preview UI
- Exercise detail modal
Completed Research
- The 10 Pillars of science-based plan design
- Body recomposition in depth (timeline, nutrition, training)
- Execution modes (20+ modes and techniques)
- Tempo and time under tension
- Volume guidelines by experience level
- Intensity/RPE/RIR research
- Training frequency and MPS
- Rest period optimization
- Exercise selection and order
- Progressive overload methods
- Periodization models comparison
- Deload protocols and triggers
- External factors (sleep, nutrition, stress)
- Push:pull ratio and muscle balance
Remaining Tasks
Database
- Finalize complete exercise list (~100 exercises)
- Determine video/image sources for exercise demos
- Define intensity technique compatibility matrix
- Create seed data for all tables
Algorithm
- Implement all pillar functions
- Implement split selection
- Implement session builder
- Implement periodization
- Add workout progression tracking
API
- Plan generation endpoints
- Exercise management endpoints
- Session detail endpoints
UI
- Step 7-9 redesign
- Exercise detail components
- Coach collaboration streaming
Related Documents
- 01-flow-and-ui.md - Planning flow and UI
- 02-ten-pillars.md - Science-based plan design
- 05-exercise-database.md - Database schema
Last Updated: 2025-12-08