from __future__ import annotations from typing import Any, Literal from pydantic import BaseModel, Field, model_validator class ProfileUpdate(BaseModel): display_name: str | None = None height_inches: float | None = Field(default=None, gt=0) goal_weight_lbs: float | None = Field(default=None, gt=0) measurement_system: Literal['imperial'] | None = 'imperial' notes: str | None = None class WeightEntryCreate(BaseModel): recorded_at: str weight_lbs: float = Field(gt=0) body_fat_percent: float | None = Field(default=None, ge=0, le=100) notes: str | None = None class MeasurementEntryCreate(BaseModel): recorded_at: str waist_inches: float | None = Field(default=None, gt=0) hip_inches: float | None = Field(default=None, gt=0) chest_inches: float | None = Field(default=None, gt=0) neck_inches: float | None = Field(default=None, gt=0) notes: str | None = None @model_validator(mode='after') def validate_at_least_one_measurement(self) -> 'MeasurementEntryCreate': if not any( value is not None for value in [self.waist_inches, self.hip_inches, self.chest_inches, self.neck_inches] ): raise ValueError('At least one body measurement is required.') return self class ExerciseTemplateCreate(BaseModel): name: str primary_muscle: str | None = None equipment: str | None = None notes: str | None = None class RoutineExerciseCreate(BaseModel): exercise_name: str target_sets: int = Field(ge=1) target_reps: str notes: str | None = None class RoutineCreate(BaseModel): user_id: str name: str notes: str | None = None exercises: list[RoutineExerciseCreate] class WorkoutSetCreate(BaseModel): reps: int = Field(ge=1) weight_lbs: float | None = Field(default=None, ge=0) rpe: float | None = Field(default=None, ge=0) rest_seconds: int | None = Field(default=None, ge=0) notes: str | None = None class WorkoutExerciseCreate(BaseModel): exercise_name: str notes: str | None = None sets: list[WorkoutSetCreate] class WorkoutCreate(BaseModel): user_id: str performed_at: str routine_name: str notes: str | None = None exercises: list[WorkoutExerciseCreate] JSONDict = dict[str, Any]