📄 2026-05-08-rtsport-roadmap.md 10,035 bytes Yesterday 01:54 📋 Raw

RTSport — Product Roadmap & State of the Build

2026-05-08 | Compiled by Wadsworth 📋


Current Architecture (what actually exists)

Layer 1: RTSport Standalone API (port 8001)

Status: ✅ Core backend built and running

Location: ~/.openclaw/shared/build-20260501/backend/
Framework: FastAPI + SQLAlchemy
Database: SQLite (rtsport_test.db) with PostgreSQL migration path
Auth: JWT with role-based access (at/coach/parent/admin)
Component File Lines State
Database models app/models.py 285 ✅ Complete — User, School, Athlete, Case, Milestone, Event
Pydantic schemas app/schemas.py 316 ✅ Complete
JWT Auth app/auth.py 191 ✅ Complete — login, token creation/verification, role guards
Auth endpoints app/api/auth.py 168 ✅ Complete — /login (OAuth2), /login/json, /me
Athletes API app/api/athletes.py 321 ✅ Complete
Cases API app/api/cases.py 544 ✅ Complete — CRUD, milestones
Roster API app/api/roster.py 328 ✅ Complete — role-gated (at/coach only)
Events API app/api/events.py 409 ✅ Complete — sideline entry, general events
Dashboard API app/api/dashboard.py 892 ✅ Largest module — AT/Coach/Parent/AD dashboards
Admin API app/api/admin.py 320 ✅ Complete — stats, roster management
Seed data seed_data.py ⚠️ Only seeds parent@example.com
Tests tests/ ✅ test_auth.py, generate_test_data.py

25 live endpoints, role-based access control enforced.

Layer 2: HoffDesk Proxy Layer (port 8000)

Status: ✅ Partial proxy with mock fallbacks

Location: ~/.openclaw/workspace-socrates/hoffdesk-api/
Component File What it does State
Static mock router rtsport_mock.py Serves static HTML/CSS/JS for all dashboards ✅ Live via RTS_BASE → shared/current/frontend
API proxy rtsport_api_proxy.py Forwards /api/v1/rtsport/* → port 8001 ✅ Live
Coach API (mock) rtsport_coach_api.py In-memory mock data, 8 endpoints, shares MESSAGES with parent API ✅ Live, bypasses port 8001
Parent API (mock) rtsport_parent_api.py In-memory mock data, 6 endpoints, linked to coach API ✅ Live, bypasses port 8001
Login router login_router.py Serves /rtsport/login page ✅ Live
Unified auth auth/router.py Session cookies for admin, Bearer for API ✅ Live (HoffDesk family, not RTSport-specific)

Layer 3: Frontend (served as static files)

Status: ✅ All role dashboards built

Dashboard File Lines Features
AT Dashboard templates/at/dashboard.html Roster, case management, sideline entry
Coach Dashboard templates/coach/dashboard.html ~1550 Roster cards, status filter, injury breakdown, timeline, messages
Parent Dashboard templates/parent/dashboard.html ~1200 Child selector, case milestones, restrictions, care team, messages
AD Dashboard templates/ad/dashboard.html Admin stats, school-wide overview
Login templates/login.html 67 Dark theme, role-based redirect
Shared components templates/components/ Athlete detail, notifications, timeline
CSS 5 files ~2936 lines Dark theme, mobile-first, role-specific styles
JS 5 files ~2726 lines Tab logic, API clients, auto-login, mock data

The Two Systems Problem

Right now RTSport runs as two parallel systems:

User → https://hoffdesk.com/rtsport/coach
  → rtsport_mock.py serves coach/dashboard.html
  → dashboard.html JS calls /api/v1/dashboard/coach/status?school_id=schl_001
  → This routes to rtsport_coach_api.py (IN-MEMORY MOCK DATA)
  → NOT the real RTSport API at port 8001

Meanwhile:
  RTSport API at port 8001 has full CRUD, real DB, role guards
  → But the frontend doesn't call it directly
  → The proxy at port 8000 → 8001 only handles /api/v1/rtsport/* paths
  → Coach/Parent dashboard endpoints are LOCAL_PATHS (not proxied)

Root cause: The coach and parent dashboard API endpoints are deliberately excluded from the proxy (LOCAL_PATHS in rtsport_api_proxy.py) because they have mock implementations in rtsport_coach_api.py and rtsport_parent_api.py. The real API at 8001 has its own /dashboard/coach and /dashboard/parent endpoints, but they're unreachable from the frontend.


Auth State — What Works, What Doesn't

Flow Status Detail
Login page /rtsport/login serves dark theme login form
Login API call POST /api/v1/auth/login/json → returns JWT + role + school_id
Role-based redirect JS routes to correct dashboard based on role
Token storage localStorage: rtsport_token, rtsport_role, rtsport_school_id
Auto-login (dashboard direct access) ⚠️ Works, but insecure Hardcoded credentials in dashboard.html: email: 'parent@example.com', password: 'testpass123'
Auth guard on dashboard ❌ Missing No redirect to login if token invalid/missing — API calls fail silently
Auth guard on API ⚠️ Partial Port 8000 mock APIs accept any non-empty token (no real validation). Port 8001 has real JWT validation + role guards.
Role-based API access ✅ Port 8001 "Access denied. Required role: one of ['at', 'coach']"
Password hashing bcrypt via passlib in port 8001 auth.py
Session management ✅ Admin only Cookie-based for HoffDesk admin, not used for RTSport

Database: Multi-Tenant Design (already built)

Schema: Single database, school_id on every table
Already implemented in models.py
Table Multi-tenant column Indexed
schools id (PK) domain
users school_id ✅ school_id, email, role
athletes school_id ✅ school_id, current_status, sports, team
cases school_id, athlete_id ✅ school_id, athlete_id, status, opened_at
milestones school_id, case_id
events school_id, case_id

Scale model:
- 1 database, ~10 tables, school_id column on every query
- SQLite for dev/small deployments (<100 schools), PostgreSQL for production
- Indexed by school_id on every table — fast multi-tenant queries
- JWT encodes school_id so a user can't query another school's data

Seed data gap: Only parent@example.com is seeded in the real database. Coach, AT, and admin accounts exist only in the mock Python dicts.


Blockers & Prioritized Work

🔴 Blocking Go-To-Market

# Blocker Impact Effort
1 Unify the two API systems — frontend calls real API at 8001, not mock dicts Users see inconsistent/empty data. Mock data doesn't persist. Medium (1-2 days)
2 Seed full test data — coach, AT, admin accounts + realistic athlete roster in the real DB Can't demo multi-role flows end-to-end Small (2-4 hours)
3 Auth guard on dashboards — redirect to login if no valid token Direct dashboard access shows broken pages Small (1-2 hours)
4 Remove hardcoded credentials from dashboard.html Security risk, even for demo Small (1 hour — just rely on login page)

🟡 Needed Before Beta

# Item Detail
5 AT Dashboard: case creation form → real API Currently uses mock data
6 Sideline entry → real event creation API Endpoint exists, frontend not wired
7 Message persistence — currently in-memory, lost on restart Port 8001 needs message table + endpoints
8 Role-based UI — hide elements based on role Coach shouldn't see AT-only actions

🟢 Post-Beta / v1.1

# Item Detail
9 PostgreSQL migration SQLite works for beta, PG needed for concurrent users
10 Admin onboarding flow — create school, invite users Currently manual DB inserts
11 Email notifications Case updates, milestone completions
12 Mobile app shell PWA wrapper around existing responsive HTML

Go-To-Market Estimate

What's Done

  • ✅ Full database schema with multi-tenant design
  • ✅ JWT auth with role-based access (bcrypt, token refresh ready)
  • ✅ 25 API endpoints with role guards
  • ✅ All 5 role dashboards (AT, Coach, Parent, AD, Login)
  • ✅ Mobile-first responsive CSS (~3000 lines)
  • ✅ Coach dashboard: status cards, injury breakdown, recovery timeline, athlete messages
  • ✅ Parent dashboard: child selector, milestones, restrictions, care team, activity feed
  • ✅ AT dashboard: roster view, case management UI
  • ✅ AD dashboard: admin stats (mock)
  • ✅ Sideline entry form (frontend)
  • ✅ Shared components (athlete detail, notifications, timeline)
  • ✅ HTTPS via Cloudflare, secure in production posture

What Remains

  • 🔴 Unify APIs (1-2 days)
  • 🔴 Seed data + auth hardening (1 day)
  • 🟡 Wire frontend to real API (2-3 days)
  • 🟡 Message persistence (1 day)
  • 🟡 Polish + bug fixes (1-2 days)

Timeline Estimate

Milestone Effort Target
Demo-ready (all roles work, real data) 1 week May 15
Beta-ready (persistent messages, polished UI) 2-3 weeks May 22-29
Production MVP (PG migration, onboarding) +2 weeks June 12

  1. Unify APIs — Remove LOCAL_PATHS exclusion in proxy, have coach/parent dashboards call real port 8001 endpoints. Delete mock coach/parent API files.
  2. Seed database — Add coach@, at@, admin@ accounts + 10-15 athletes with real cases to rtsport_test.db.
  3. Auth guard — Add 10 lines of JS to each dashboard: if (!getAuthToken()) window.location = '/rtsport/login'
  4. Kill auto-login — Remove hardcoded credential block from dashboard HTML files.