📄 seed_data.py 11,975 bytes Yesterday 02:03 📋 Raw

!/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()