Source code for app.db.models.reference

from __future__ import annotations

from typing import TYPE_CHECKING

from advanced_alchemy.base import orm_registry
from advanced_alchemy.types import GUID
from sqlalchemy import (
    Column,
    ForeignKey,
    Index,
    SmallInteger,
    String,
    Table,
)
from sqlalchemy.orm import (
    Mapped,
    mapped_column,
    relationship,
)

from app.db.models.base import SmallIntPKBase

if TYPE_CHECKING:
    from .exercise import Exercise

# --- Association Tables ---


exercise_primary_muscles = Table(
    "exercise_primary_muscles",
    orm_registry.metadata,
    Column(
        "exercise_id",
        ForeignKey("exercises.id", ondelete="CASCADE"),
        primary_key=True,
        type_=GUID,
    ),
    Column(
        "muscle_group_id",
        ForeignKey("muscle_groups.id", ondelete="CASCADE"),
        primary_key=True,
        type_=SmallInteger,
    ),
    Index("idx_ex_primary_muscle_id", "muscle_group_id"),
    comment="M2M: Link between exercises and their prime mover muscle groups",
)
"""Association table linking exercises to their primary target muscle groups."""


exercise_secondary_muscles = Table(
    "exercise_secondary_muscles",
    orm_registry.metadata,
    Column(
        "exercise_id",
        ForeignKey("exercises.id", ondelete="CASCADE"),
        primary_key=True,
        type_=GUID,
    ),
    Column(
        "muscle_group_id",
        ForeignKey("muscle_groups.id", ondelete="CASCADE"),
        primary_key=True,
        type_=SmallInteger,
    ),
    Index("idx_ex_secondary_muscle_id", "muscle_group_id"),
    comment="M2M: Link between exercises and their synergist/stabilizer muscle groups",
)
"""Association table linking exercises to their secondary (synergist) muscle groups."""


exercise_equipment = Table(
    "exercise_equipment",
    orm_registry.metadata,
    Column(
        "exercise_id",
        ForeignKey("exercises.id", ondelete="CASCADE"),
        primary_key=True,
        type_=GUID,
    ),
    Column(
        "equipment_id",
        ForeignKey("equipment.id", ondelete="CASCADE"),
        primary_key=True,
        type_=SmallInteger,
    ),
    Index("idx_ex_equipment_id", "equipment_id"),
    comment="M2M: Link between exercises and required equipment",
)
"""Association table linking exercises to the required equipment."""


exercise_tag_map = Table(
    "exercise_tag_map",
    orm_registry.metadata,
    Column(
        "exercise_id",
        ForeignKey("exercises.id", ondelete="CASCADE"),
        primary_key=True,
        type_=GUID,
    ),
    Column(
        "tag_id",
        ForeignKey("exercise_tags.id", ondelete="CASCADE"),
        primary_key=True,
        type_=SmallInteger,
    ),
    Index("idx_ex_tag_map_tag_id", "tag_id"),
    comment="M2M: Link between exercises and functional/biomechanical tags",
)
"""Association table linking exercises to system-defined metadata tags."""

# --- Models ---


[docs] class MuscleGroup(SmallIntPKBase): """Anatomical muscle group used to categorize exercises and track targeting.""" __tablename__ = "muscle_groups" __table_args__ = ({"comment": "Anatomical muscle groups for exercise targeting (e.g., biceps, triceps)"},) name: Mapped[str] = mapped_column(String(100), unique=True) """Normalized lowercase name of the muscle group.""" # ------------ # ORM Relationships # ------------ primary_exercises: Mapped[list[Exercise]] = relationship( secondary=exercise_primary_muscles, back_populates="primary_muscles", lazy="noload", viewonly=True, ) """Exercises where this muscle is the prime mover (read-only).""" secondary_exercises: Mapped[list[Exercise]] = relationship( secondary=exercise_secondary_muscles, back_populates="secondary_muscles", lazy="noload", viewonly=True, ) """Exercises where this muscle acts as a synergist or stabilizer (read-only)."""
[docs] class Equipment(SmallIntPKBase): """Physical tools or machines required to perform specific exercises.""" __tablename__ = "equipment" __table_args__ = ({"comment": "Training equipment and machines (e.g., barbell, dumbbell, cable)"},) name: Mapped[str] = mapped_column(String(100), unique=True) """Normalized lowercase name of the equipment.""" # ------------ # ORM Relationships # ------------ exercises_using: Mapped[list[Exercise]] = relationship( secondary=exercise_equipment, back_populates="equipment", lazy="noload", viewonly=True, ) """Collection of exercises that utilize this equipment (read-only)."""
[docs] class ExerciseTag(SmallIntPKBase): """Flexible metadata labels used for grouping and filtering exercises.""" __tablename__ = "exercise_tags" __table_args__ = ({"comment": "Functional, environmental, and biomechanical exercise tags"},) name: Mapped[str] = mapped_column(String(100), unique=True) """Normalized lowercase tag name.""" # ------------ # ORM Relationships # ------------ tagged_exercises: Mapped[list[Exercise]] = relationship( secondary=exercise_tag_map, back_populates="tags", lazy="noload", viewonly=True, ) """Collection of exercises associated with this metadata tag (read-only)."""