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:
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)