#!/usr/bin/env python3 """ RTSport Database Seeder — v0.3 unified API seed data Creates one school, four roles (parent/at/coach/admin), 8+ athletes across sports, and 5 active cases with milestones. Usage: rm -f rtsport.db && python3 seed_data.py """ import os import sys from datetime import datetime, timedelta # Ensure app module is importable sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # Force DB to rtsport.db (absolute path) for consistent location _DB_DIR = os.path.dirname(os.path.abspath(__file__)) os.environ["DATABASE_URL"] = f"sqlite:///{os.path.join(_DB_DIR, 'rtsport.db')}" from app.database import init_db, SessionLocal from app.models import School, User, Athlete, Case, Milestone from app.auth import hash_password from app.utils.id_generator import generate_id def seed_database(): print("Initializing database...") init_db() db = SessionLocal() try: # =================================================================== # 1. School # =================================================================== school = School( id="schl_001", name="Preble High School", domain="preble.k12.wi.us", config={ "primary_color": "#0f766e", "logo_url": "/school/preble/logo.svg", "sport_names": { "Football": "Varsity Football", "Soccer": "Boys Soccer", "Basketball": "Varsity Basketball" } }, created_at=datetime.utcnow(), updated_at=datetime.utcnow() ) db.add(school) db.commit() print(f"Created school: {school.name}") # =================================================================== # 2. Users (ALL password: testpass123, bcrypt-hashed) # =================================================================== hashed = hash_password("testpass123") users = [ User( id="usr_parent001", school_id="schl_001", email="parent@example.com", hashed_password=hashed, role="parent", first_name="Jennifer", last_name="Smith", is_active=True, assigned_sports=[], assigned_teams=[], created_at=datetime.utcnow(), updated_at=datetime.utcnow() ), User( id="usr_coach001", school_id="schl_001", email="coach@preble.k12.wi.us", hashed_password=hashed, role="coach", first_name="Mike", last_name="Andrews", is_active=True, assigned_sports=["Football"], assigned_teams=[], created_at=datetime.utcnow(), updated_at=datetime.utcnow() ), User( id="usr_at001", school_id="schl_001", email="at@preble.k12.wi.us", hashed_password=hashed, role="at", first_name="Lisa", last_name="Johnson", is_active=True, assigned_sports=[], assigned_teams=[], created_at=datetime.utcnow(), updated_at=datetime.utcnow() ), User( id="usr_admin001", school_id="schl_001", email="admin@preble.k12.wi.us", hashed_password=hashed, role="admin", first_name="David", last_name="Reynolds", is_active=True, assigned_sports=[], assigned_teams=[], created_at=datetime.utcnow(), updated_at=datetime.utcnow() ), ] for u in users: db.add(u) db.commit() print(f"Created {len(users)} users") # =================================================================== # 3. Athletes (8+, per spec) # =================================================================== athletes_data = [ ("ath_001", "Jake", "Larson", 12, ["Football"], "Varsity", []), ("ath_002", "Marcus", "Johnson", 11, ["Football"], "Varsity", []), ("ath_003", "Tyler", "Wilson", 10, ["Football"], "Varsity", []), ("ath_004", "Derek", "Lee", 11, ["Football"], "Varsity", []), ("ath_005", "Cameron", "Davis", 10, ["Football"], "JV", []), ("ath_006", "Ethan", "Brooks", 11, ["Football"], "Varsity", []), ("ath_007", "Emma", "Larson", 9, ["Soccer"], "JV", []), ("ath_008", "Ryan", "Miller", 12, ["Basketball"], "Varsity", []), ] created_athletes = {} for aid, first, last, grade, sports, team, parent_ids in athletes_data: athlete = Athlete( id=aid, school_id="schl_001", first_name=first, last_name=last, grade=grade, sports=sports, team=team, parent_ids=parent_ids, current_status="cleared", # updated per case below active_case_ids=[], created_at=datetime.utcnow(), updated_at=datetime.utcnow() ) db.add(athlete) created_athletes[aid] = athlete db.commit() print(f"Created {len(created_athletes)} athletes") # =================================================================== # 4. Cases (5 active, per spec) # =================================================================== # Jake → out (ankle sprain) # Marcus → out (ACL) # Tyler → modified (knee) # Derek → modified (shoulder) # Cameron → out (hamstring) # Ethan → cleared (no case — stays cleared) # Emma → cleared (no case) # Ryan → out (basketball injury) now = datetime.utcnow() cases_data = [ ("case_001", "ath_001", "Right ankle sprain", "moderate", "active_rehab", "active"), ("case_002", "ath_002", "ACL tear — left knee", "severe", "initial_assessment", "active"), ("case_003", "ath_003", "Knee injury — left", "mild", "return_to_play", "active"), ("case_004", "ath_004", "Shoulder injury — left", "moderate", "return_to_play", "active"), ("case_005", "ath_005", "Hamstring strain — right", "moderate", "initial_assessment", "active"), ] status_map = { "case_001": "out", "case_002": "out", "case_003": "modified", "case_004": "modified", "case_005": "out", "ath_006": "cleared", # Ethan "ath_007": "cleared", # Emma "ath_008": "out", # Ryan (no case but should be out) } # Add a 6th case for Ryan Miller (basketball) to make him "out" cases_data.append( ("case_006", "ath_008", "Right wrist fracture", "moderate", "active_rehab", "active") ) created_cases = {} for i, (cid, aid, title, severity, phase, status) in enumerate(cases_data): opened_at = now - timedelta(days=21) case = Case( id=cid, school_id="schl_001", athlete_id=aid, title=title, severity=severity, attention_level="stable", status=status, opened_at=opened_at, resolved_at=None, primary_at_id="usr_at001", created_at=opened_at, updated_at=now ) db.add(case) created_cases[cid] = case # Update athlete status athlete = created_athletes.get(aid) if athlete: athlete.current_status = status_map.get(cid, "out") if status == "active" else "cleared" athlete.active_case_ids = [cid] db.commit() # Update Ryan Miller's status (case_006 makes him out) ryan = created_athletes.get("ath_008") if ryan: ryan.current_status = "out" ryan.active_case_ids = ["case_006"] # Ethan and Emma stay cleared for eid in ["ath_006", "ath_007"]: a = created_athletes.get(eid) if a: a.current_status = "cleared" a.active_case_ids = [] db.commit() print(f"Created {len(created_cases)} cases") # =================================================================== # 5. Milestones (4 per case, per spec) # =================================================================== milestone_defs = [ ("Initial Assessment", 0), ("Active Rehab", 7), ("Return to Play", 14), ("Full Clearance", 21), ] milestones_created = 0 for cid, case_obj in created_cases.items(): opened = case_obj.opened_at for j, (m_title, offset_days) in enumerate(milestone_defs): target_date = opened + timedelta(days=offset_days) # Determine status based on elapsed time if target_date < now - timedelta(days=1): m_status = "achieved" achieved_at = target_date elif target_date < now + timedelta(days=7): m_status = "pending" achieved_at = None else: m_status = "pending" achieved_at = None milestone = Milestone( id=f"mil_{cid}_{j+1}", school_id="schl_001", case_id=cid, title=m_title, target_date=target_date, status=m_status, achieved_at=achieved_at, created_at=datetime.utcnow(), updated_at=datetime.utcnow() ) db.add(milestone) milestones_created += 1 db.commit() print(f"Created {milestones_created} milestones") # =================================================================== # Summary # =================================================================== print("\n" + "=" * 60) print(" ✅ Database seeding complete!") print("=" * 60) print(f"\n DB path: rtsport.db") print(f"\n Users (password: testpass123):") print(f" parent@example.com → parent") print(f" coach@preble.k12.wi.us → coach (Football)") print(f" at@preble.k12.wi.us → at") print(f" admin@preble.k12.wi.us → admin") print(f"\n Athletes: {len(created_athletes)}") print(f" Cases: {len(created_cases)}") print(f" Milestones: {milestones_created}") print(f"\n Athlete Status:") for aid in ["ath_001","ath_002","ath_003","ath_004","ath_005","ath_006","ath_007","ath_008"]: a = created_athletes.get(aid) if a: print(f" {a.id}: {a.first_name} {a.last_name} ({a.sports[0]}/{a.team}) → {a.current_status}") except Exception as e: db.rollback() print(f"ERROR seeding database: {e}") raise finally: db.close() if __name__ == "__main__": seed_database()