from datetime import datetime from sqlalchemy import Column, Integer, String, Float, Boolean, DateTime, ForeignKey, JSON, Text from sqlalchemy.orm import relationship from .database import Base class Player(Base): __tablename__ = "players" id = Column(Integer, primary_key=True, index=True) name = Column(String(100), nullable=False) contact = Column(String(100), nullable=True) skill_level = Column(String(20), nullable=False, default="Beginner") # Beginner/Intermediate/Advanced/Elite matches_played = Column(Integer, default=0) wins = Column(Integer, default=0) losses = Column(Integer, default=0) elo = Column(Float, default=1000.0) created_at = Column(DateTime, default=datetime.utcnow) event_players = relationship("EventPlayer", back_populates="player") class Court(Base): __tablename__ = "courts" id = Column(Integer, primary_key=True, index=True) name = Column(String(100), nullable=False) court_type = Column(String(100), default="Sport Court") status = Column(String(20), default="available") # available/in_use/reserved/maintenance created_at = Column(DateTime, default=datetime.utcnow) reservations = relationship("CourtReservation", back_populates="court") matches = relationship("Match", back_populates="court") class CourtReservation(Base): __tablename__ = "court_reservations" id = Column(Integer, primary_key=True, index=True) court_id = Column(Integer, ForeignKey("courts.id"), nullable=False) player_id = Column(Integer, ForeignKey("players.id"), nullable=True) group_name = Column(String(100), nullable=True) start_time = Column(DateTime, nullable=False) end_time = Column(DateTime, nullable=False) notes = Column(Text, nullable=True) created_at = Column(DateTime, default=datetime.utcnow) court = relationship("Court", back_populates="reservations") player = relationship("Player") class Event(Base): __tablename__ = "events" id = Column(Integer, primary_key=True, index=True) name = Column(String(200), nullable=False) format = Column(String(20), default="Singles") # Singles/Doubles courts_count = Column(Integer, default=1) status = Column(String(20), default="setup") # setup/active/completed current_stage_id = Column(Integer, nullable=True) created_at = Column(DateTime, default=datetime.utcnow) started_at = Column(DateTime, nullable=True) completed_at = Column(DateTime, nullable=True) event_players = relationship("EventPlayer", back_populates="event", cascade="all, delete-orphan") stages = relationship("Stage", back_populates="event", order_by="Stage.order", cascade="all, delete-orphan") class EventPlayer(Base): __tablename__ = "event_players" id = Column(Integer, primary_key=True, index=True) event_id = Column(Integer, ForeignKey("events.id"), nullable=False) player_id = Column(Integer, ForeignKey("players.id"), nullable=False) skill_level_override = Column(String(20), nullable=True) event = relationship("Event", back_populates="event_players") player = relationship("Player", back_populates="event_players") class Stage(Base): __tablename__ = "stages" id = Column(Integer, primary_key=True, index=True) event_id = Column(Integer, ForeignKey("events.id"), nullable=False) name = Column(String(100), nullable=False) match_type = Column(String(30), nullable=False) # Open/Skill-Based/Round Robin/Tournament rounds = Column(Integer, default=1) advance_count = Column(Integer, default=0) # 0 = all advance status = Column(String(20), default="pending") # pending/active/completed order = Column(Integer, default=0) created_at = Column(DateTime, default=datetime.utcnow) event = relationship("Event", back_populates="stages") matches = relationship("Match", back_populates="stage", cascade="all, delete-orphan") class Match(Base): __tablename__ = "matches" id = Column(Integer, primary_key=True, index=True) stage_id = Column(Integer, ForeignKey("stages.id"), nullable=False) court_id = Column(Integer, ForeignKey("courts.id"), nullable=True) round_number = Column(Integer, default=1) match_number = Column(Integer, default=1) # Singles: player1_id, player2_id # Doubles: team1_players and team2_players are JSON lists player1_id = Column(Integer, ForeignKey("players.id"), nullable=True) player2_id = Column(Integer, ForeignKey("players.id"), nullable=True) team1_players = Column(JSON, nullable=True) # [player_id, player_id] team2_players = Column(JSON, nullable=True) score1 = Column(Integer, nullable=True) score2 = Column(Integer, nullable=True) winner_id = Column(Integer, ForeignKey("players.id"), nullable=True) # for singles winner_team = Column(Integer, nullable=True) # 1 or 2 for doubles status = Column(String(20), default="scheduled") # scheduled/in_progress/completed/bye bracket_position = Column(String(20), nullable=True) # winners/losers next_winner_match_id = Column(Integer, nullable=True) next_loser_match_id = Column(Integer, nullable=True) scheduled_time = Column(DateTime, nullable=True) started_at = Column(DateTime, nullable=True) completed_at = Column(DateTime, nullable=True) stage = relationship("Stage", back_populates="matches") court = relationship("Court", back_populates="matches") player1 = relationship("Player", foreign_keys=[player1_id]) player2 = relationship("Player", foreign_keys=[player2_id]) winner = relationship("Player", foreign_keys=[winner_id])