""" Pydantic Models for Mitai Jinkendo API Data validation schemas for request/response bodies. """ from typing import Optional from pydantic import BaseModel # ── Profile Models ──────────────────────────────────────────────────────────── class ProfileCreate(BaseModel): name: str avatar_color: Optional[str] = '#1D9E75' sex: Optional[str] = 'm' dob: Optional[str] = None height: Optional[float] = 178 goal_weight: Optional[float] = None goal_bf_pct: Optional[float] = None class ProfileUpdate(BaseModel): name: Optional[str] = None avatar_color: Optional[str] = None sex: Optional[str] = None dob: Optional[str] = None height: Optional[float] = None goal_weight: Optional[float] = None goal_bf_pct: Optional[float] = None quality_filter_level: Optional[str] = None # Issue #31: Global quality filter # ── Tracking Models ─────────────────────────────────────────────────────────── class WeightEntry(BaseModel): date: str weight: float note: Optional[str] = None class CircumferenceEntry(BaseModel): date: str c_neck: Optional[float] = None c_chest: Optional[float] = None c_waist: Optional[float] = None c_belly: Optional[float] = None c_hip: Optional[float] = None c_thigh: Optional[float] = None c_calf: Optional[float] = None c_arm: Optional[float] = None notes: Optional[str] = None photo_id: Optional[str] = None class CaliperEntry(BaseModel): date: str sf_method: Optional[str] = 'jackson3' sf_chest: Optional[float] = None sf_axilla: Optional[float] = None sf_triceps: Optional[float] = None sf_subscap: Optional[float] = None sf_suprailiac: Optional[float] = None sf_abdomen: Optional[float] = None sf_thigh: Optional[float] = None sf_calf_med: Optional[float] = None sf_lowerback: Optional[float] = None sf_biceps: Optional[float] = None body_fat_pct: Optional[float] = None lean_mass: Optional[float] = None fat_mass: Optional[float] = None notes: Optional[str] = None class ActivityEntry(BaseModel): date: str start_time: Optional[str] = None end_time: Optional[str] = None activity_type: str duration_min: Optional[float] = None kcal_active: Optional[float] = None kcal_resting: Optional[float] = None hr_avg: Optional[float] = None hr_max: Optional[float] = None distance_km: Optional[float] = None rpe: Optional[int] = None source: Optional[str] = 'manual' notes: Optional[str] = None training_type_id: Optional[int] = None # v9d: Training type categorization training_category: Optional[str] = None # v9d: Denormalized category training_subcategory: Optional[str] = None # v9d: Denormalized subcategory class NutritionDay(BaseModel): date: str kcal: Optional[float] = None protein_g: Optional[float] = None fat_g: Optional[float] = None carbs_g: Optional[float] = None # ── Auth Models ─────────────────────────────────────────────────────────────── class LoginRequest(BaseModel): email: str password: str class PasswordResetRequest(BaseModel): email: str class PasswordResetConfirm(BaseModel): token: str new_password: str class RegisterRequest(BaseModel): name: str email: str password: str # ── Admin Models ────────────────────────────────────────────────────────────── class AdminProfileUpdate(BaseModel): role: Optional[str] = None ai_enabled: Optional[int] = None ai_limit_day: Optional[int] = None export_enabled: Optional[int] = None