- 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
326 lines
12 KiB
Python
326 lines
12 KiB
Python
"""
|
|
Seed data for ServeSync Demo
|
|
- 8 players with varied skills
|
|
- 4 courts
|
|
- 1 completed event (Spring Singles Open)
|
|
- 1 in-progress event (Summer Tournament - Round 2)
|
|
- Sample court reservations
|
|
"""
|
|
import os
|
|
import sys
|
|
from datetime import datetime, timedelta
|
|
|
|
sys.path.insert(0, "/app")
|
|
os.environ.setdefault("DATABASE_URL", "postgresql://servesync:servesync@db:5432/servesync")
|
|
|
|
from app.database import engine, SessionLocal
|
|
from app.models import Base, Player, Court, CourtReservation, Event, EventPlayer, Stage, Match
|
|
|
|
Base.metadata.create_all(bind=engine)
|
|
db = SessionLocal()
|
|
|
|
# Clear existing data
|
|
print("Clearing existing data...")
|
|
db.query(Match).delete()
|
|
db.query(Stage).delete()
|
|
db.query(EventPlayer).delete()
|
|
db.query(Event).delete()
|
|
db.query(CourtReservation).delete()
|
|
db.query(Court).delete()
|
|
db.query(Player).delete()
|
|
db.commit()
|
|
|
|
# ─── PLAYERS ────────────────────────────────────────────────────────────────
|
|
print("Creating players...")
|
|
players_data = [
|
|
{"name": "Marco Reyes", "contact": "marco@example.com", "skill_level": "Elite", "elo": 1852, "matches_played": 48, "wins": 38, "losses": 10},
|
|
{"name": "Ana Santos", "contact": "ana@example.com", "skill_level": "Advanced", "elo": 1645, "matches_played": 35, "wins": 24, "losses": 11},
|
|
{"name": "Carlos Tan", "contact": "carlos@example.com", "skill_level": "Advanced", "elo": 1583, "matches_played": 30, "wins": 20, "losses": 10},
|
|
{"name": "Diana Flores", "contact": "diana@example.com", "skill_level": "Intermediate", "elo": 1402, "matches_played": 22, "wins": 13, "losses": 9},
|
|
{"name": "Tony Garcia", "contact": "tony@example.com", "skill_level": "Intermediate", "elo": 1281, "matches_played": 18, "wins": 9, "losses": 9},
|
|
{"name": "Lisa Cruz", "contact": "lisa@example.com", "skill_level": "Intermediate", "elo": 1318, "matches_played": 15, "wins": 8, "losses": 7},
|
|
{"name": "Jake Torres", "contact": "jake@example.com", "skill_level": "Beginner", "elo": 883, "matches_played": 8, "wins": 3, "losses": 5},
|
|
{"name": "Maria Lim", "contact": "maria@example.com", "skill_level": "Beginner", "elo": 947, "matches_played": 10, "wins": 4, "losses": 6},
|
|
]
|
|
|
|
players = []
|
|
for pd in players_data:
|
|
p = Player(**pd)
|
|
db.add(p)
|
|
players.append(p)
|
|
db.commit()
|
|
for p in players:
|
|
db.refresh(p)
|
|
print(f" Created {len(players)} players")
|
|
|
|
# ─── COURTS ─────────────────────────────────────────────────────────────────
|
|
print("Creating courts...")
|
|
courts_data = [
|
|
{"name": "Court A", "court_type": "Sport Court Premium", "status": "available"},
|
|
{"name": "Court B", "court_type": "Sport Court Premium", "status": "available"},
|
|
{"name": "Court C", "court_type": "Cushioned Tournament Grade", "status": "in_use"},
|
|
{"name": "Court D", "court_type": "Cushioned Tournament Grade", "status": "in_use"},
|
|
]
|
|
courts = []
|
|
for cd in courts_data:
|
|
c = Court(**cd)
|
|
db.add(c)
|
|
courts.append(c)
|
|
db.commit()
|
|
for c in courts:
|
|
db.refresh(c)
|
|
print(f" Created {len(courts)} courts")
|
|
|
|
# ─── RESERVATIONS ───────────────────────────────────────────────────────────
|
|
print("Creating reservations...")
|
|
now = datetime.utcnow()
|
|
today_2pm = now.replace(hour=6, minute=0, second=0, microsecond=0) + timedelta(hours=8) # 2pm PHT = 6am UTC
|
|
today_4pm = today_2pm + timedelta(hours=2)
|
|
tomorrow_10am = (now + timedelta(days=1)).replace(hour=2, minute=0, second=0, microsecond=0)
|
|
tomorrow_12pm = tomorrow_10am + timedelta(hours=2)
|
|
|
|
reservations = [
|
|
CourtReservation(court_id=courts[0].id, player_id=players[5].id,
|
|
group_name="Lisa Cruz Group", start_time=today_2pm, end_time=today_4pm,
|
|
notes="Training session"),
|
|
CourtReservation(court_id=courts[1].id, group_name="Maintenance Crew",
|
|
start_time=tomorrow_10am, end_time=tomorrow_12pm,
|
|
notes="Net replacement and floor inspection"),
|
|
]
|
|
for r in reservations:
|
|
db.add(r)
|
|
db.commit()
|
|
|
|
# ─── EVENT 1: SPRING SINGLES OPEN (Completed) ────────────────────────────────
|
|
print("Creating completed event...")
|
|
event1 = Event(
|
|
name="Spring Singles Open",
|
|
format="Singles",
|
|
courts_count=2,
|
|
status="completed",
|
|
created_at=now - timedelta(days=7),
|
|
started_at=now - timedelta(days=7, hours=2),
|
|
completed_at=now - timedelta(days=7),
|
|
)
|
|
db.add(event1)
|
|
db.commit()
|
|
db.refresh(event1)
|
|
|
|
# Add all 8 players to event1
|
|
for p in players:
|
|
ep = EventPlayer(event_id=event1.id, player_id=p.id, skill_level_override=p.skill_level)
|
|
db.add(ep)
|
|
db.commit()
|
|
|
|
# Stage 1 - Open Stage (completed)
|
|
stage1_e1 = Stage(event_id=event1.id, name="Open Stage", match_type="Open",
|
|
rounds=2, advance_count=4, status="completed", order=0)
|
|
db.add(stage1_e1)
|
|
db.commit()
|
|
db.refresh(stage1_e1)
|
|
|
|
# Stage 2 - Tournament (completed)
|
|
stage2_e1 = Stage(event_id=event1.id, name="Finals Tournament", match_type="Tournament",
|
|
rounds=3, advance_count=0, status="completed", order=1)
|
|
db.add(stage2_e1)
|
|
db.commit()
|
|
db.refresh(stage2_e1)
|
|
|
|
# Create completed open stage matches
|
|
open_matches = [
|
|
(players[0], players[7], 21, 8), # Marco vs Maria
|
|
(players[1], players[6], 21, 14), # Ana vs Jake
|
|
(players[2], players[5], 21, 11), # Carlos vs Lisa
|
|
(players[3], players[4], 21, 18), # Diana vs Tony
|
|
# Round 2
|
|
(players[0], players[6], 21, 10), # Marco vs Jake
|
|
(players[1], players[4], 21, 16), # Ana vs Tony
|
|
(players[2], players[7], 21, 9), # Carlos vs Maria
|
|
(players[3], players[5], 18, 21), # Diana vs Lisa (Lisa wins!)
|
|
]
|
|
completed_at_base = now - timedelta(days=7, hours=1, minutes=30)
|
|
for i, (p1, p2, s1, s2) in enumerate(open_matches):
|
|
winner = p1 if s1 > s2 else p2
|
|
m = Match(
|
|
stage_id=stage1_e1.id,
|
|
court_id=courts[i % 2].id,
|
|
round_number=1 if i < 4 else 2,
|
|
match_number=(i % 4) + 1,
|
|
player1_id=p1.id, player2_id=p2.id,
|
|
score1=s1, score2=s2,
|
|
winner_id=winner.id,
|
|
status="completed",
|
|
bracket_position="main",
|
|
started_at=completed_at_base + timedelta(minutes=i * 20),
|
|
completed_at=completed_at_base + timedelta(minutes=i * 20 + 18),
|
|
)
|
|
db.add(m)
|
|
db.commit()
|
|
|
|
# Tournament bracket for event 1 (QF, SF, Final)
|
|
# Top 4 by round wins: Marco, Ana, Carlos, Lisa
|
|
top4 = [players[0], players[1], players[2], players[5]] # Marco, Ana, Carlos, Lisa
|
|
|
|
# QF matches
|
|
qf1 = Match(stage_id=stage2_e1.id, court_id=courts[0].id, round_number=1, match_number=1,
|
|
player1_id=top4[0].id, player2_id=top4[3].id, score1=21, score2=13,
|
|
winner_id=top4[0].id, status="completed", bracket_position="winners",
|
|
started_at=now - timedelta(days=7, minutes=90),
|
|
completed_at=now - timedelta(days=7, minutes=72))
|
|
qf2 = Match(stage_id=stage2_e1.id, court_id=courts[1].id, round_number=1, match_number=2,
|
|
player1_id=top4[1].id, player2_id=top4[2].id, score1=21, score2=19,
|
|
winner_id=top4[1].id, status="completed", bracket_position="winners",
|
|
started_at=now - timedelta(days=7, minutes=90),
|
|
completed_at=now - timedelta(days=7, minutes=70))
|
|
db.add(qf1); db.add(qf2); db.commit()
|
|
db.refresh(qf1); db.refresh(qf2)
|
|
|
|
# Final
|
|
final = Match(stage_id=stage2_e1.id, court_id=courts[2].id, round_number=2, match_number=1,
|
|
player1_id=top4[0].id, player2_id=top4[1].id, score1=21, score2=17,
|
|
winner_id=top4[0].id, status="completed", bracket_position="winners",
|
|
started_at=now - timedelta(days=7, minutes=45),
|
|
completed_at=now - timedelta(days=7, minutes=25))
|
|
db.add(final); db.commit()
|
|
|
|
# Link bracket
|
|
qf1.next_winner_match_id = final.id
|
|
qf2.next_winner_match_id = final.id
|
|
event1.current_stage_id = stage2_e1.id
|
|
db.commit()
|
|
|
|
print(f" Completed event created: {event1.name}")
|
|
|
|
# ─── EVENT 2: SUMMER TOURNAMENT (In Progress, Round 2) ───────────────────────
|
|
print("Creating in-progress event...")
|
|
event2 = Event(
|
|
name="Summer Tournament",
|
|
format="Singles",
|
|
courts_count=2,
|
|
status="active",
|
|
created_at=now - timedelta(hours=3),
|
|
started_at=now - timedelta(hours=2),
|
|
)
|
|
db.add(event2)
|
|
db.commit()
|
|
db.refresh(event2)
|
|
|
|
# Add 8 players
|
|
for p in players:
|
|
ep = EventPlayer(event_id=event2.id, player_id=p.id)
|
|
db.add(ep)
|
|
db.commit()
|
|
|
|
# Stage 1: Open Stage (completed)
|
|
stage1_e2 = Stage(event_id=event2.id, name="Open Stage", match_type="Open",
|
|
rounds=1, advance_count=4, status="completed", order=0)
|
|
db.add(stage1_e2)
|
|
db.commit()
|
|
db.refresh(stage1_e2)
|
|
|
|
# Stage 1 completed matches
|
|
s1_matches = [
|
|
(players[0], players[7], 21, 6, "completed"),
|
|
(players[1], players[6], 21, 11, "completed"),
|
|
(players[2], players[5], 21, 15, "completed"),
|
|
(players[3], players[4], 21, 19, "completed"),
|
|
]
|
|
for i, (p1, p2, s1, s2, status) in enumerate(s1_matches):
|
|
winner = p1 if s1 > s2 else p2
|
|
m = Match(
|
|
stage_id=stage1_e2.id,
|
|
court_id=courts[i % 2].id,
|
|
round_number=1, match_number=i + 1,
|
|
player1_id=p1.id, player2_id=p2.id,
|
|
score1=s1, score2=s2, winner_id=winner.id,
|
|
status=status, bracket_position="main",
|
|
started_at=now - timedelta(hours=2, minutes=30),
|
|
completed_at=now - timedelta(hours=1, minutes=45),
|
|
)
|
|
db.add(m)
|
|
db.commit()
|
|
|
|
# Stage 2: Tournament (Active, Round 2 in progress)
|
|
stage2_e2 = Stage(event_id=event2.id, name="Finals Tournament", match_type="Tournament",
|
|
rounds=3, advance_count=0, status="active", order=1)
|
|
db.add(stage2_e2)
|
|
db.commit()
|
|
db.refresh(stage2_e2)
|
|
event2.current_stage_id = stage2_e2.id
|
|
|
|
# Tournament bracket - 8 players → QF (R1), SF (R2), Final (R3)
|
|
# QF: Round 1 (all completed)
|
|
qf_matches = [
|
|
(players[0], players[7], 21, 8, "completed", courts[0].id),
|
|
(players[1], players[6], 21, 13, "completed", courts[1].id),
|
|
(players[2], players[5], 21, 16, "completed", None),
|
|
(players[3], players[4], 19, 21, "completed", None), # Tony beats Diana!
|
|
]
|
|
|
|
# SF: Round 2 (2 in progress, 0 completed)
|
|
sf_matches = [
|
|
(players[0], players[1], None, None, "in_progress", courts[2].id), # Marco vs Ana - LIVE
|
|
(players[2], players[4], None, None, "in_progress", courts[3].id), # Carlos vs Tony - LIVE
|
|
]
|
|
|
|
# Final: Round 3 (scheduled)
|
|
final_e2 = Match(
|
|
stage_id=stage2_e2.id, court_id=None,
|
|
round_number=3, match_number=1,
|
|
player1_id=None, player2_id=None,
|
|
status="scheduled", bracket_position="winners",
|
|
)
|
|
db.add(final_e2); db.flush(); db.refresh(final_e2)
|
|
|
|
# Create QF matches
|
|
qf_db = []
|
|
for i, (p1, p2, s1, s2, status, court_id) in enumerate(qf_matches):
|
|
winner = p1 if (s1 and s1 > s2) else p2
|
|
m = Match(
|
|
stage_id=stage2_e2.id, court_id=court_id,
|
|
round_number=1, match_number=i + 1,
|
|
player1_id=p1.id, player2_id=p2.id,
|
|
score1=s1, score2=s2, winner_id=winner.id if status == "completed" else None,
|
|
status=status, bracket_position="winners",
|
|
started_at=now - timedelta(hours=1, minutes=30),
|
|
completed_at=now - timedelta(hours=1) if status == "completed" else None,
|
|
)
|
|
db.add(m)
|
|
qf_db.append(m)
|
|
|
|
db.commit()
|
|
for m in qf_db:
|
|
db.refresh(m)
|
|
|
|
# Create SF matches
|
|
sf_db = []
|
|
for i, (p1, p2, s1, s2, status, court_id) in enumerate(sf_matches):
|
|
m = Match(
|
|
stage_id=stage2_e2.id, court_id=court_id,
|
|
round_number=2, match_number=i + 1,
|
|
player1_id=p1.id, player2_id=p2.id,
|
|
score1=s1, score2=s2,
|
|
status=status, bracket_position="winners",
|
|
started_at=now - timedelta(minutes=15) if status == "in_progress" else None,
|
|
next_winner_match_id=final_e2.id,
|
|
)
|
|
db.add(m)
|
|
sf_db.append(m)
|
|
db.commit()
|
|
|
|
# Link QF to SF
|
|
qf_db[0].next_winner_match_id = sf_db[0].id
|
|
qf_db[1].next_winner_match_id = sf_db[0].id
|
|
qf_db[2].next_winner_match_id = sf_db[1].id
|
|
qf_db[3].next_winner_match_id = sf_db[1].id
|
|
db.commit()
|
|
|
|
print(f" In-progress event created: {event2.name}")
|
|
|
|
db.close()
|
|
print("\n✅ Seed complete!")
|
|
print(f" Players: {len(players)}")
|
|
print(f" Courts: {len(courts)}")
|
|
print(f" Events: 2 (1 completed, 1 active)")
|
|
print(f" Courts C & D: in_use (live matches)")
|