📄 SPEC.md 4,115 bytes Yesterday 01:58 📋 Raw

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)