feat: Rebuild as Court Manager Dashboard v2
- Complete rewrite for single Court Manager user - Feature 1: Player Management (CRUD, ELO, skill level) - Feature 2: Court Reservation (timeline, override) - Feature 3: Match Event Builder (3-step wizard) - Step 1: Event setup with player selection + stage calculator - Step 2: Stage configurator (Open/Skill/RR/Tournament) - Step 3: Auto bracket generation - Feature 4: Live Court View (main dashboard, 2x2 grid) - Event Control: score entry, bracket advancement, court assignment - Screen view: TV display per court (/screen/:id) - Seed: 8 players, 4 courts, 1 completed + 1 active event - Routes: / players courts events events/new events/:id screen/:id
This commit is contained in:
163
backend/app/schemas.py
Normal file
163
backend/app/schemas.py
Normal file
@@ -0,0 +1,163 @@
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
# Player schemas
|
||||
class PlayerCreate(BaseModel):
|
||||
name: str
|
||||
contact: Optional[str] = None
|
||||
skill_level: str = "Beginner"
|
||||
|
||||
class PlayerUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
contact: Optional[str] = None
|
||||
skill_level: Optional[str] = None
|
||||
|
||||
class PlayerOut(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
contact: Optional[str]
|
||||
skill_level: str
|
||||
matches_played: int
|
||||
wins: int
|
||||
losses: int
|
||||
elo: float
|
||||
created_at: datetime
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# Court schemas
|
||||
class CourtCreate(BaseModel):
|
||||
name: str
|
||||
court_type: str = "Sport Court"
|
||||
|
||||
class CourtStatusUpdate(BaseModel):
|
||||
status: str # available/in_use/reserved/maintenance
|
||||
|
||||
class ReservationCreate(BaseModel):
|
||||
player_id: Optional[int] = None
|
||||
group_name: Optional[str] = None
|
||||
start_time: datetime
|
||||
end_time: datetime
|
||||
notes: Optional[str] = None
|
||||
|
||||
class ReservationOut(BaseModel):
|
||||
id: int
|
||||
court_id: int
|
||||
player_id: Optional[int]
|
||||
group_name: Optional[str]
|
||||
start_time: datetime
|
||||
end_time: datetime
|
||||
notes: Optional[str]
|
||||
player: Optional[PlayerOut] = None
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
class CourtOut(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
court_type: str
|
||||
status: str
|
||||
reservations: List[ReservationOut] = []
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# Event schemas
|
||||
class EventCreate(BaseModel):
|
||||
name: str
|
||||
format: str = "Singles"
|
||||
courts_count: int = 1
|
||||
|
||||
class EventUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
format: Optional[str] = None
|
||||
courts_count: Optional[int] = None
|
||||
|
||||
class EventPlayerAdd(BaseModel):
|
||||
player_id: int
|
||||
skill_level_override: Optional[str] = None
|
||||
|
||||
class EventPlayerOut(BaseModel):
|
||||
id: int
|
||||
player_id: int
|
||||
skill_level_override: Optional[str]
|
||||
player: PlayerOut
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# Stage schemas
|
||||
class StageCreate(BaseModel):
|
||||
name: str
|
||||
match_type: str # Open/Skill-Based/Round Robin/Tournament
|
||||
rounds: int = 1
|
||||
advance_count: int = 0
|
||||
order: int = 0
|
||||
|
||||
class StageUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
match_type: Optional[str] = None
|
||||
rounds: Optional[int] = None
|
||||
advance_count: Optional[int] = None
|
||||
|
||||
class StageOut(BaseModel):
|
||||
id: int
|
||||
event_id: int
|
||||
name: str
|
||||
match_type: str
|
||||
rounds: int
|
||||
advance_count: int
|
||||
status: str
|
||||
order: int
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# Match schemas
|
||||
class MatchScoreUpdate(BaseModel):
|
||||
score1: int
|
||||
score2: int
|
||||
|
||||
class MatchCourtAssign(BaseModel):
|
||||
court_id: Optional[int]
|
||||
|
||||
class MatchOut(BaseModel):
|
||||
id: int
|
||||
stage_id: int
|
||||
court_id: Optional[int]
|
||||
round_number: int
|
||||
match_number: int
|
||||
player1_id: Optional[int]
|
||||
player2_id: Optional[int]
|
||||
team1_players: Optional[List[int]]
|
||||
team2_players: Optional[List[int]]
|
||||
score1: Optional[int]
|
||||
score2: Optional[int]
|
||||
winner_id: Optional[int]
|
||||
winner_team: Optional[int]
|
||||
status: str
|
||||
bracket_position: Optional[str]
|
||||
next_winner_match_id: Optional[int]
|
||||
next_loser_match_id: Optional[int]
|
||||
scheduled_time: Optional[datetime]
|
||||
started_at: Optional[datetime]
|
||||
completed_at: Optional[datetime]
|
||||
player1: Optional[PlayerOut] = None
|
||||
player2: Optional[PlayerOut] = None
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# Dashboard schema
|
||||
class DashboardCourtData(BaseModel):
|
||||
court: CourtOut
|
||||
current_match: Optional[MatchOut] = None
|
||||
elapsed_seconds: Optional[int] = None
|
||||
|
||||
class DashboardData(BaseModel):
|
||||
courts: List[DashboardCourtData]
|
||||
upcoming_matches: List[MatchOut]
|
||||
active_event: Optional[dict] = None
|
||||
Reference in New Issue
Block a user