# SPEC: RTSport API Unification + Seed Data + Auth Guard > Build Date: 2026-05-08 | Agent Collaboration Protocol v1.5.1 ## Overview Unify RTSport's two parallel API systems, seed real test data, add auth guards to all dashboards, and remove hardcoded credentials. This is a backend-only build — frontend changes are limited to ~10-line JS additions per dashboard. ## Contract | Field | Value | |-------|-------| | API Base | Port 8001 (RTSport API) — localhost only | | Proxy Base | Port 8000 (HoffDesk) → /api/v1/ → 8001 | | Auth | JWT Bearer, bcrypt passwords, role-based access | | DB | SQLite at `shared/build-20260501/backend/rtsport.db` | ## Blockers to Resolve ### Blocker 1: Unify APIs **Current state:** Coach/parent dashboard JS calls endpoints at port 8000 which hit mock Python dicts (rtsport_coach_api.py, rtsport_parent_api.py). The real API at 8001 has identical endpoints with real DB + role guards, but they're excluded from the proxy (LOCAL_PATHS). **Fix:** In `rtsport_api_proxy.py`, remove `dashboard/coach`, `dashboard/parent`, `messages/coach`, `messages/parent` from LOCAL_PATHS. This routes all API calls through to port 8001. Then remove or disable the mock coach/parent API files from main_v2.py. **Success criteria:** `curl https://hoffdesk.com/api/v1/dashboard/coach/status?school_id=schl_001` (with Bearer token) returns data from the real DB, not mock dicts. ### Blocker 2: Seed Full Test Data **Current state:** Only `parent@example.com` exists in the real DB. Coach, AT, admin accounts and athlete roster are only in mock Python dicts. **Fix:** Update `seed_data.py` to create: - 1 school: Preble High School (schl_001) - 4 users: parent@example.com (parent), coach@preble.k12.wi.us (coach), at@preble.k12.wi.us (at), admin@preble.k12.wi.us (admin) - 8+ athletes with realistic data (names, grades, sports, teams) - 4-5 active cases (Jake Larson ankle, Marcus Johnson ACL, etc — port the coach API mock data into real DB records) - Seed milestones for each case **Success criteria:** `curl http://127.0.0.1:8001/api/v1/roster?school_id=schl_001` with coach Bearer token returns 8+ athletes. ### Blocker 3: Auth Guard on Dashboards **Current state:** Visiting /rtsport/parent directly without login shows a broken page — API calls fail silently with "Field required" because no school_id in localStorage. **Fix:** Add to each dashboard HTML (parent, coach, at, ad) at the top of the bootstrap script: ```js if (!localStorage.getItem('rtsport_token') && !sessionStorage.getItem('rtsport_token')) { window.location.href = '/rtsport/login'; } ``` **Success criteria:** Visiting /rtsport/parent with cleared localStorage redirects to /rtsport/login. ### Blocker 4: Remove Hardcoded Credentials **Current state:** Parent dashboard has auto-login block with hardcoded `parent@example.com` / `testpass123`. Coach dashboard same pattern. **Fix:** Delete the auto-login fetch block from parent/dashboard.html and coach/dashboard.html (the `checkAuth()` function's !token branch that does `fetch('/api/v1/auth/login/json'...)` with hardcoded body). **Success criteria:** No hardcoded credentials in any HTML file. `grep -r "testpass123"` returns nothing in the frontend directory. ## Files to Modify ``` hoffdesk-api/rtsport_api_proxy.py — Remove LOCAL_PATHS exclusion hoffdesk-api/main_v2.py — Disable mock coach/parent router mounts shared/build-20260501/backend/seed_data.py — Full seed data shared/build-20260501/frontend/templates/parent/dashboard.html — Auth guard + remove auto-login shared/build-20260501/frontend/templates/coach/dashboard.html — Auth guard + remove auto-login shared/build-20260501/frontend/templates/at/dashboard.html — Auth guard shared/build-20260501/frontend/templates/ad/dashboard.html — Auth guard ``` ## Success Criteria - All 4 roles can login → get redirected to their dashboard → see real data from the database - Visiting a dashboard without auth redirects to login page - No hardcoded credentials anywhere - Messages persist across restarts (in DB, not in-memory dict)