📄 integration.md 4,243 bytes Today 04:47 📋 Raw

SidelineWorks Build — Integration Status

Date: 2026-05-09

TRACK A: SidelineWorks Marketing Site (Port 8003)

Status: ✅ DONE

Page Status Notes
/ ✅ 200 Hero + role cards + CTA
/product ✅ 200 Feature breakdown
/pricing ✅ 200 3-tier pricing
/demo ✅ 200 Form with POST handler
/contact ✅ 200 Contact form
/blog ✅ 200 Blog index
/blog/{slug} ✅ 200 Individual articles
/health ✅ 200 Health check
SVGs ✅ 200 Favicon, wordmark, icon, RTSport badge

Brand Assets Created

  • static/img/sidelineworks-icon.svg — Shield + medical cross icon for favicon
  • static/img/sidelineworks-wordmark.svg — Full wordmark with tagline
  • static/img/rtsport-wordmark.svg — RTSport sub-brand badge ("A product by SidelineWorks")

Fix Applied

Starlette 1.0.0 TemplateResponse signature change
Old: templates.TemplateResponse("home.html", {"request": request})
New: templates.TemplateResponse(request, "home.html", {"request": request})
Created tmpl() helper for all routes.

Running at: http://localhost:8003
TODO: Wadsworth to wire Cloudflare Tunnel for sidelineworks.com → port 8003


TRACK B: Dashboard API Unification (Port 8002)

Status: ✅ DONE

Dashboard Server (FastAPI proxy on port 8002)

  • Serves all 4 dashboard templates + login page
  • Proxies real API (port 8001) with response transformations
  • Handles auth via /api/login POST → real API login

Response Transformations

Dashboard Field Mismatch Proxy Fix
Coach teams is object, frontend expects array transform_teams() converts {Varsity: [...]}[{team_name, athletes}]
Coach Athlete has current_status, frontend expects status Added a["status"] = a["current_status"]
Coach Athlete has case_title, frontend expects injury.body_part Added a["injury"] = {"body_part": case_title}
AT stats has full_count/out_count/modified_count, frontend expects cleared/out/modified Renamed fields
AT active_cases has athlete_id/athlete_name/injury_short, frontend expects id/name/injury Renamed fields
AD Flat total_athletes/active_cases/out_today not nested under school_stats Added data["school_stats"] = {...}
AD Sport has athletes/out/modified, frontend expects total_athletes/out_count/modified_count Renamed fields
AD Activity has time_ago, frontend expects time Renamed field
Parent API expects athlete_id param, frontend sends child_id Fixed in parent-tabs.js

Auth Changes

  • New /login page with email/password form
  • dashboard-tabs.js: autoLogin() now parses {access_token, role, school_id} from real API
  • Auth guard: checkAuth() redirects to /login if no token
  • All dashboard templates include checkAuth() on DOMContentLoaded

Dashboards Served

Dashboard Route Auth Real Data
Coach /coach ✅ (with proxy)
AT /at ✅ (with proxy)
Parent /parent ✅ (with proxy, no parent-child seed data)
AD /ad ⚠️ No ad role user in seed data
Login /login

Running at: http://localhost:8002


TRACK C: Offline Architecture

Status: 🔮 Not started (scoped at 2-3 weeks)

ServiceWorker + IndexedDB + sync queue for sideline entry without internet.
Deferred — focus is Track A + Track B.


Demo Form Webhook

Status: 🔧 Pending (Wadsworth's job)

Demo form POST handler in main.py logs to stdout. Needs:
- Telegram notification via wacli or bot
- Or email notification

Cloudflare Tunnel

Status: 🔧 Pending (Wadsworth's job)

  • sidelineworks.com → port 8003 (marketing site)
  • Could also expose rtsport app → subdomain

Summary of Running Services

Service Port PID Status
RTSport API 8001 145233 ✅ Live (v0.3.0)
RTSport Dashboard 8002 154072 ✅ Live
SidelineWorks Marketing 8003 153132 ✅ Live
HoffDesk 8000 ✅ Live