๐Ÿ“„ README.md 4,683 bytes May 01, 2026 ๐Ÿ“‹ Raw

RTSport Backend

FastAPI-based REST API for athletic training case management in scholastic sports.

Architecture

  • Framework: FastAPI 0.111.0
  • Database: PostgreSQL with SQLAlchemy ORM
  • Schemas: Pydantic v2
  • Auth: JWT-based (FERPA-compliant role system)

Quick Start

Prerequisites

  • Python 3.11+
  • PostgreSQL 14+

Installation

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Linux/Mac
# or: venv\Scripts\activate  # Windows

# Install dependencies
pip install -r requirements.txt

# Set up environment variables
cp .env.example .env
# Edit .env with your database credentials

Database Setup

# Create database
createdb rtsport

# Initialize tables
python -c "from app.database import init_db; init_db()"

Running the Server

# Development (with auto-reload)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# Production
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

Project Structure

backend/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ main.py           # FastAPI app factory
โ”‚   โ”œโ”€โ”€ config.py         # Settings management
โ”‚   โ”œโ”€โ”€ database.py       # SQLAlchemy engine/session
โ”‚   โ”œโ”€โ”€ schemas.py        # Pydantic v2 schemas (5 models)
โ”‚   โ”œโ”€โ”€ models.py         # SQLAlchemy ORM models
โ”‚   โ””โ”€โ”€ api/
โ”‚       โ”œโ”€โ”€ __init__.py
โ”‚       โ”œโ”€โ”€ roster.py     # GET /api/v1/roster
โ”‚       โ”œโ”€โ”€ cases.py      # GET /api/v1/cases/*
โ”‚       โ””โ”€โ”€ events.py     # POST /api/v1/events/sideline-entry
โ”œโ”€โ”€ requirements.txt
โ””โ”€โ”€ README.md

API Endpoints

Read Operations

Method Endpoint Description
GET /api/v1/roster Get athlete roster (with filters)
GET /api/v1/roster/{athlete_id} Get single athlete
GET /api/v1/cases/{athlete_id} Get cases for athlete
GET /api/v1/cases/{case_id}/timeline Get event timeline
GET /api/v1/cases/{case_id}/milestones Get case milestones

Write Operations

Method Endpoint Description
POST /api/v1/events/sideline-entry 3-tap rapid entry

Data Models

1. School (Tenant)

  • Multi-tenant boundary - every model has school_id
  • Config JSON for branding and sport name mappings

2. Athlete

  • Central roster node
  • current_status: cached property (cleared|restricted|out)
  • Updated via DB trigger on event creation

3. Case

  • Single injury lifecycle
  • severity (clinical, static) โ‰  attention_level (operational, daily)
  • Resolved via clearance_granted event (reopenable within 30 days)

4. Milestone

  • Forward-looking targets (Phase Bar UI)
  • Separate from Events (backward-looking records)

5. Event

  • Every sideline entry, note, or clearance
  • visibility defaults to ["at"] - must explicitly expand
  • clinical_notes stripped server-side for non-AT roles

FERPA Compliance

Role-based access matrix:

Entity AT Coach Parent
Roster Full Team Only No Access
Cases Full Active Status Only Own Child Only
Timeline All visibility: coach visibility: parent
Clinical Notes Read/Write HARD BLOCK HARD BLOCK
Restrictions Write Read-Only Read-Only

Environment Variables

# Required
DATABASE_URL=postgresql://user:pass@localhost:5432/rtsport
SECRET_KEY=your-secret-key-here

# Optional
DEBUG=true
ACCESS_TOKEN_EXPIRE_MINUTES=10080  # 7 days
CORS_ORIGINS=["http://localhost:3000"]

Development Notes

Auto-Case Creation (Sideline Entry)

The POST /api/v1/events/sideline-entry endpoint:
1. Checks for existing active case for athlete + body_part
2. Creates new Case if none exists
3. Creates initial Event
4. Updates athlete.current_status via DB trigger

Status Synchronization

SQLAlchemy event listeners in models.py handle:
- restriction_added event โ†’ athlete.status = "restricted"
- clearance_granted event โ†’ athlete.status = "cleared" + case.resolved

Database Indexes

All tables indexed on:
- school_id (tenant isolation)
- Foreign keys (query performance)
- Array fields using GIN (JSONB/ARRAY queries)

Testing

# Run tests (when implemented)
pytest

# With coverage
pytest --cov=app --cov-report=html

Contract Alignment

Source of truth: ../docs/contract.md

  • All 5 Pydantic schemas validate against contract ยง1
  • All 4 GET + 1 POST endpoints match contract ยง2
  • FERPA matrix implemented per contract ยง3
  • Multi-tenant by school_id per contract ยง4