Coverage for models/playoffs.py: 100.00%

38 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2026-04-12 14:12 +0000

1""" 

2Playoff bracket Pydantic models. 

3""" 

4 

5from pydantic import BaseModel 

6 

7 

8class BracketTierConfig(BaseModel): 

9 """Configuration for a single bracket tier.""" 

10 

11 name: str # e.g., "Gold", "Silver" 

12 start_position: int # 1 for positions 1-4, 5 for positions 5-8 

13 end_position: int # 4 for positions 1-4, 8 for positions 5-8 

14 

15 

16class PlayoffBracketSlot(BaseModel): 

17 """A single position in the playoff bracket, with denormalized match data.""" 

18 

19 id: int 

20 league_id: int 

21 season_id: int 

22 age_group_id: int 

23 round: str 

24 bracket_position: int 

25 bracket_tier: str | None = None 

26 match_id: int | None = None 

27 home_seed: int | None = None 

28 away_seed: int | None = None 

29 home_source_slot_id: int | None = None 

30 away_source_slot_id: int | None = None 

31 # Denormalized from linked match 

32 home_team_name: str | None = None 

33 away_team_name: str | None = None 

34 home_score: int | None = None 

35 away_score: int | None = None 

36 match_status: str | None = None 

37 match_date: str | None = None 

38 scheduled_kickoff: str | None = None 

39 

40 

41class GenerateBracketRequest(BaseModel): 

42 """Request to generate a playoff bracket from current standings.""" 

43 

44 league_id: int 

45 season_id: int 

46 age_group_id: int 

47 division_a_id: int 

48 division_b_id: int 

49 start_date: str # ISO date string for QF matches (e.g., "2026-02-15") 

50 tiers: list[BracketTierConfig] # e.g., [{"name": "Gold", ...}, ...] 

51 

52 

53class AdvanceWinnerRequest(BaseModel): 

54 """Request to advance the winner of a completed bracket slot.""" 

55 

56 slot_id: int 

57 

58 

59class ForfeitMatchRequest(BaseModel): 

60 """Request to declare a forfeit on a playoff match.""" 

61 

62 slot_id: int 

63 forfeit_team_id: int