Files

144 lines
4.7 KiB
Python

# backend/app/models.py
from datetime import datetime
from typing import Optional
from sqlalchemy import JSON, DateTime, Table, Column
from sqlalchemy import Enum as SqlEnum
from sqlalchemy import ForeignKey, Integer, String
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .constants import MatchStatus, TournamentTypes, BracketTypes
from .database import Base
tournament_courts = Table(
"tournament_courts",
Base.metadata,
Column(
"tournament_id",
String(8),
ForeignKey("tournaments.id", ondelete="CASCADE"),
primary_key=True,
),
Column(
"court_id",
Integer,
ForeignKey("courts.id", ondelete="CASCADE"),
primary_key=True,
),
)
class Court(Base):
__tablename__ = "courts"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String, nullable=False, unique=True)
tournaments: Mapped[list["Tournament"]] = relationship(
"Tournament", secondary=tournament_courts, back_populates="courts"
)
class Tournament(Base):
__tablename__ = "tournaments"
id: Mapped[str] = mapped_column(String(8), primary_key=True, index=True)
name: Mapped[str] = mapped_column(String, nullable=False)
code: Mapped[str] = mapped_column(String, nullable=True)
timestamp: Mapped[datetime] = mapped_column(DateTime, nullable=False)
duration: Mapped[int] = mapped_column(Integer, default=30)
type: Mapped[TournamentTypes] = mapped_column(SqlEnum(TournamentTypes))
teams: Mapped[list["Team"]] = relationship(
"Team", back_populates="tournament", cascade="all, delete-orphan"
)
courts: Mapped[list["Court"]] = relationship(
"Court", secondary=tournament_courts, back_populates="tournaments"
)
matches: Mapped[list["Match"]] = relationship(
"Match", back_populates="tournament", cascade="all, delete-orphan"
)
@property
def team_count(self) -> int:
return len(self.teams)
@property
def court_count(self) -> int:
return len(self.courts)
class Team(Base):
__tablename__ = "teams"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String, nullable=False)
tournament_id: Mapped[str] = mapped_column(ForeignKey("tournaments.id"))
tournament: Mapped["Tournament"] = relationship(back_populates="teams")
class Match(Base):
__tablename__ = "matches"
id: Mapped[str] = mapped_column(String, primary_key=True)
tournament_id: Mapped[str] = mapped_column(ForeignKey("tournaments.id"))
match_number: Mapped[int] = mapped_column(Integer)
round_number: Mapped[int] = mapped_column(Integer, default=1)
bracket_type: Mapped[BracketTypes] = mapped_column(SqlEnum(BracketTypes))
court_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("courts.id"), nullable=True
)
start_time: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
status: Mapped[MatchStatus] = mapped_column(
SqlEnum(MatchStatus), default=MatchStatus.SCHEDULED
)
p1_team_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("teams.id"), nullable=True
)
p2_team_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("teams.id"), nullable=True
)
ref_team_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("teams.id"), nullable=True
)
ref_label: Mapped[Optional[str]] = mapped_column(String, nullable=True)
sets: Mapped[list[dict]] = mapped_column(JSON, default=list)
winner_team_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("teams.id"), nullable=True
)
winner_next_match_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("matches.id"), nullable=True
)
winner_next_match_slot: Mapped[Optional[int]] = mapped_column(
Integer, nullable=True
)
loser_next_match_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("matches.id"), nullable=True
)
loser_next_match_slot: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
tournament: Mapped["Tournament"] = relationship(back_populates="matches")
court: Mapped[Optional["Court"]] = relationship()
p1_team: Mapped["Team"] = relationship("Team", foreign_keys=[p1_team_id])
p2_team: Mapped["Team"] = relationship("Team", foreign_keys=[p2_team_id])
ref_team: Mapped[Optional["Team"]] = relationship(
"Team", foreign_keys=[ref_team_id]
)
winner_next_match: Mapped["Match"] = relationship(
"Match", remote_side=[id], foreign_keys=[winner_next_match_id]
)
loser_next_match: Mapped["Match"] = relationship(
"Match", remote_side=[id], foreign_keys=[loser_next_match_id]
)