Files
servesync-demo/backend/app/schemas.py
Nemo 4421f61c24 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
2026-03-19 07:35:51 +08:00

164 lines
3.7 KiB
Python

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