import { CardioPreference, GranularEquipment, LibraryExercise, MuscleGroup, RestTimerLength, SimplifiedMuscleGroup, StrictRepRange, TrainingGoal, TrainingLevel, WeeklyTrainingFrequency } from '..'; import type { TrainerExerciseCategory, TrainerWorkoutTemplateName, WorkoutDurationMinutes } from './constants'; export type exerciseId = string; export type TrainerLibraryExercise = Pick; export interface ExerciseSelectionCriteria { exerciseCategory: TrainerExerciseCategory | 'all'; equipments: GranularEquipment[]; workoutBarbellExerciseCount: number; level: TrainingLevel; goal: TrainingGoal; muscleGroup: MuscleGroup; frequency: WeeklyTrainingFrequency; } export interface ExerciseSelectionContext { programUsedExerciseIds?: Set; workoutUsedExerciseIds?: Set; excludedExerciseIds?: Set; } export interface ExerciseSelectionParams { sortedExercises: Record; handPickedExercises?: T[]; criteria: ExerciseSelectionCriteria; context: ExerciseSelectionContext; } export interface ExerciseSelectionTraceEntry { pass: 1 | 2 | 3 | 4 | 5 | 6; label: string; candidatePoolSize: number; selectedExerciseId?: string; } export interface ExerciseSelectionTrace { entries: ExerciseSelectionTraceEntry[]; selectedPass?: 1 | 2 | 3 | 4 | 5 | 6; } export interface ProgramGenerationParams { trainerAlgorithmSettings: TrainerAlgorithmSettings; frequency: WeeklyTrainingFrequency; goal: TrainingGoal; level: TrainingLevel; equipments: GranularEquipment[]; workoutDurationMinutes: WorkoutDurationMinutes; restTimerLength: RestTimerLength; exerciseStore: T[]; focusMuscle?: SimplifiedMuscleGroup; excludedExerciseIds?: Set; cardioPreference: CardioPreference; /** * When enabled, includes exercise selection trace breadcrumbs in the result * for debugging. Intended for troubleshooting on backoffice; keep off in * normal usage on the app. */ debugExerciseSelectionTrace?: boolean; } export interface TemplateExerciseSelectionTraceRecord { traceKind: 'template'; workoutTemplate: TrainerWorkoutTemplateName; prescriptionIndex: number; prescription: ExercisePrescription; resolvedMuscleGroup: MuscleGroup; criteria: ExerciseSelectionCriteria; selectedExerciseId?: string; trace: ExerciseSelectionTrace; } export interface CardioExerciseSelectionTraceRecord { traceKind: 'cardio'; workoutTemplate: TrainerWorkoutTemplateName; prescriptionIndex: number; selectedExerciseId?: string; equipments: GranularEquipment[]; level: TrainingLevel; trace: ExerciseSelectionTrace; } export type ProgramExerciseSelectionTraceRecord = TemplateExerciseSelectionTraceRecord | CardioExerciseSelectionTraceRecord; export type TrainerProgramAttemptWithTraces = TrainerProgramAttempt & { exerciseSelectionTraces: ProgramExerciseSelectionTraceRecord[]; }; export type FrequencyString = 'one_day' | 'two_days' | 'three_days' | 'four_days' | 'five_days' | 'six_days'; export type SetsPerGoal = { [key in TrainingGoal]: number; }; export type SetsPerFrequency = { [key in FrequencyString]: SetsPerGoal; }; export interface AlgorithmRepRange { rep_range_start: number; rep_range_end: number; } export type RepRangesPerCategory = { [key in TrainerExerciseCategory]: AlgorithmRepRange; }; export type RepRanges = { [key in TrainingGoal]: RepRangesPerCategory; }; export type RestTimersPerCategory = { [key in TrainerExerciseCategory]: number; }; export type CategoryPerRestTimerLength = { [key in RestTimerLength]: RestTimersPerCategory; }; export type RestTimers = { [key in TrainingGoal]: CategoryPerRestTimerLength; }; export type ExercisePriorities = { [key in MuscleGroup]: exerciseId[]; }; export type ExerciseNotes = { [key in exerciseId]: string; }; export interface ExercisePrescription { muscle_group: MuscleGroup | 'focus_muscle'; category: TrainerExerciseCategory; warmup_set_count?: number; min_workout_duration_limit?: WorkoutDurationMinutes; } export type ExerciseReplacements = { [key in exerciseId]: exerciseId[]; }; export interface WorkoutTemplate { exercises: ExercisePrescription[]; } export type Templates = { [key in TrainerWorkoutTemplateName]: WorkoutTemplate; }; export interface BackofficeTrainerPreset { id?: number; username: string; title?: string; is_default?: boolean; updated_at?: string; settings: TrainerAlgorithmSettings; } export interface TrainerAlgorithmSettings { sets: SetsPerFrequency; rep_ranges: RepRanges; rest_timers: RestTimers; templates: Templates; exercise_priorities: ExercisePriorities; exercise_notes: ExerciseNotes; exercise_replacements: ExerciseReplacements; } export interface TrainerProgramResistanceExercise { kind: 'resistance'; exercise_template: TrainerLibraryExercise; set_count: number; warmup_set_count: number; rep_range: StrictRepRange; rest_seconds: number; } export interface TrainerProgramCardioExercise { kind: 'cardio'; exercise_template: TrainerLibraryExercise; set_count: 1; duration_seconds: number; } export interface TrainerProgramOtherExercise { kind: 'other'; exercise_template: TrainerLibraryExercise; set_count: number; } export type TrainerProgramExercise = TrainerProgramResistanceExercise | TrainerProgramCardioExercise | TrainerProgramOtherExercise; export interface TrainerProgramWorkoutTemplate { name: TrainerWorkoutTemplateName; exercises: TrainerProgramExercise[]; } export interface GeneratedTrainerProgram { workoutTemplates: TrainerProgramWorkoutTemplate[]; } export interface ExercisePrescriptionError { type: 'exercise_not_found'; prescription: ExercisePrescription; muscleGroup: MuscleGroup; context: { goal: TrainingGoal; level: TrainingLevel; equipments: GranularEquipment[]; focusMuscle?: SimplifiedMuscleGroup; }; } export interface TrainerProgramResult { success: true; program: GeneratedTrainerProgram; } export interface TrainerProgramError { success: false; errors: ExercisePrescriptionError[]; partialProgram: GeneratedTrainerProgram; } export type TrainerProgramAttempt = TrainerProgramResult | TrainerProgramError;