"""Service layer for exercise, warmup, and workout day data access. All exercise-related database operations go through this service. """ from typing import Optional import structlog from sqlmodel import Session, select from app.models.exercise import Exercise from app.models.warmup import Warmup from app.models.workout_day import WorkoutDay logger = structlog.get_logger(__name__) class ExerciseService: """Handles read operations for exercises, warmups, and workout days. Args: session: An active SQLModel Session. """ def __init__(self, session: Session) -> None: self._session = session def list_exercises( self, workout_day: Optional[str] = None, muscle_group: Optional[str] = None, ) -> list[Exercise]: """List exercises with optional filtering. Args: workout_day: Filter by workout day name (e.g., "Push"). muscle_group: Filter by muscle group (e.g., "Chest"). Returns: List of matching Exercise records. """ statement = select(Exercise) if workout_day: statement = statement.where(Exercise.workout_day == workout_day) if muscle_group: statement = statement.where(Exercise.muscle_group == muscle_group) return list(self._session.exec(statement).all()) def get_exercise_by_id(self, exercise_id: int) -> Optional[Exercise]: """Retrieve an exercise by primary key. Args: exercise_id: The exercise ID. Returns: The Exercise record, or None if not found. """ return self._session.get(Exercise, exercise_id) def get_exercise_by_name(self, name: str) -> Optional[Exercise]: """Retrieve an exercise by exact name match. Args: name: The exercise name to look up. Returns: The Exercise record, or None if not found. """ statement = select(Exercise).where(Exercise.name == name) return self._session.exec(statement).first() def list_warmups(self) -> list[Warmup]: """List all warmups in display order. Returns: List of Warmup records sorted by sort_order. """ statement = select(Warmup).order_by(Warmup.sort_order) return list(self._session.exec(statement).all()) def list_workout_days(self) -> list[WorkoutDay]: """List all workout days in order. Returns: List of WorkoutDay records sorted by day_number. """ statement = select(WorkoutDay).order_by(WorkoutDay.day_number) return list(self._session.exec(statement).all())