# backend/app/crud.py from sqlalchemy.orm import Session from uuid import uuid4 from . import models, schemas, logic # --- HELPER --- def _rebuild_bracket(db: Session, t: models.Tournament): """ Internal helper to regenerate matches, refresh the bracket logic, and update the schedule. Used whenever teams or type changes. """ db.refresh(t) current_team_names = [team.name for team in t.teams] match_data = logic.generate_structure(current_team_names, t.type) t.matches = [models.Match(**m, tournament_id=t.id) for m in match_data] # 4. Run Logic logic.refresh_bracket(t) logic.update_schedule(t) # --- TOURNAMENTS --- def get_tournaments(db: Session): return db.query(models.Tournament).all() def get_tournament(db: Session, tournament_id: str): return ( db.query(models.Tournament) .filter(models.Tournament.id == tournament_id) .first() ) def create_tournament(db: Session, data: schemas.TournamentCreate): t_id = str(uuid4())[:8] new_t = models.Tournament( id=t_id, name=data.name, code=data.code, timestamp=data.timestamp, duration=data.duration, type=data.type, ) new_t.teams = [models.Team(name=n) for n in data.teams] new_t.courts = [models.Court(name=n) for n in data.courts] match_data = logic.generate_structure(data.teams, data.type) new_t.matches = [models.Match(**m, tournament_id=t_id) for m in match_data] logic.refresh_bracket(new_t) logic.update_schedule(new_t) db.add(new_t) db.commit() db.refresh(new_t) return new_t def delete_tournament(db: Session, tournament_id: str) -> bool: t = get_tournament(db, tournament_id) if not t: return False db.delete(t) db.commit() return True def update_tournament_details( db: Session, tournament_id: str, data: schemas.TournamentUpdate ): t = get_tournament(db, tournament_id) if not t: return None update_data = data.model_dump(exclude_unset=True) incoming_type = update_data.get("type") type_changed = incoming_type and incoming_type != t.type for key, value in update_data.items(): setattr(t, key, value) if type_changed: _rebuild_bracket(db, t) else: logic.update_schedule(t) db.commit() db.refresh(t) return t def update_tournament_teams(db: Session, tournament_id: str, new_team_names: list[str]): t = get_tournament(db, tournament_id) if not t: return None current_team_names = [team.name for team in t.teams] if new_team_names == current_team_names: return t t.teams = [models.Team(name=n, tournament_id=t.id) for n in new_team_names] db.flush() _rebuild_bracket(db, t) db.commit() db.refresh(t) return t def update_tournament_courts( db: Session, tournament_id: str, new_court_names: list[str] ): t = get_tournament(db, tournament_id) if not t: return None current_court_names = [c.name for c in t.courts] if set(new_court_names) == set(current_court_names): return t t.courts = [models.Court(name=c, tournament_id=t.id) for c in new_court_names] logic.update_schedule(t) db.commit() db.refresh(t) return t def get_tournament_matches(db: Session, tournament_id: str): return ( db.query(models.Match) .filter(models.Match.tournament_id == tournament_id) .order_by(models.Match.timestamp, models.Match.court_name) .all() ) def get_match(db: Session, tournament_id: str, match_id: str): return ( db.query(models.Match) .filter(models.Match.tournament_id == tournament_id) .filter(models.Match.id == match_id) .first() ) # --- TEAMS --- def get_teams(db: Session, tournament_id: str): return ( db.query(models.Team).filter(models.Team.tournament_id == tournament_id).all() ) def create_team(db: Session, tournament_id: str, team_data: schemas.TeamCreate): t = get_tournament(db, tournament_id) if not t: return None new_team = models.Team(name=team_data.name, tournament_id=tournament_id) db.add(new_team) db.flush() _rebuild_bracket(db, t) db.commit() db.refresh(new_team) return new_team def delete_team(db: Session, tournament_id: str, team_id: int): t = get_tournament(db, tournament_id) if not t: return None team = db.get(models.Team, team_id) if not team or team.tournament_id != tournament_id: return None db.delete(team) db.flush() _rebuild_bracket(db, t) db.commit() return True # --- COURTS --- def get_courts(db: Session, tournament_id: str): return ( db.query(models.Court).filter(models.Court.tournament_id == tournament_id).all() ) def create_court(db: Session, tournament_id: str, court_data: schemas.CourtCreate): t = get_tournament(db, tournament_id) if not t: return None new_court = models.Court(name=court_data.name, tournament_id=tournament_id) db.add(new_court) db.flush() db.refresh(t) logic.update_schedule(t) db.commit() db.refresh(new_court) return new_court def delete_court(db: Session, tournament_id: str, court_id: int): t = get_tournament(db, tournament_id) if not t: return None court = db.get(models.Court, court_id) if not court or court.tournament_id != tournament_id: return None db.delete(court) db.flush() db.refresh(t) logic.update_schedule(t) db.commit() return True