๐Ÿ“„ rtsport-v0.3.yaml 11,640 bytes Sunday 02:52 ๐Ÿ“‹ Raw

RTSport API โ€” v0.3

Frontend-driven contract from the AT dashboard mock.

These are the endpoints the frontend currently fetches or POSTs to.

Socrates: wire these. Auth, roles, and FERPA matrix in contract.md.

openapi: "3.0.3"
info:
title: RTSport API
version: "0.3"
description: |
Athletic training case management for high school sports.
Current frontend targets: AT dashboard, sideline entry, athlete detail overlay.

servers:
- url: https://api.hoffdesk.com/rtsport/v1
description: Production
- url: https://hoffdesk.com/api/v1
description: Current mock server path

paths:
# โ”€โ”€ Dashboard โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
/events/sideline-entry:
post:
summary: Submit a sideline injury/incident entry
description: Called by the 3-tap sideline entry flow after all 3 selections
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- school_id
- athlete_id
- body_part
- severity
properties:
school_id:
type: string
example: "schl_001"
athlete_id:
type: string
example: "ath_001"
body_part:
type: string
example: "Ankle"
severity:
type: string
enum: [mild, moderate, severe]
example: "moderate"
removed_from_play:
type: boolean
default: false
timestamp:
type: string
format: date-time
description: ISO-8601 timestamp of when the injury occurred
responses:
"200":
description: Entry created
content:
application/json:
schema:
type: object
properties:
case_id:
type: string
example: "cas_abc123"
athlete:
type: string
example: "Jake Larson"
body_part:
type: string
example: "Ankle"
severity:
type: string
example: "moderate"
athlete_status:
type: string
enum: [removed, evaluated]
"400":
description: Validation error โ€” missing required fields

# โ”€โ”€ Athlete Detail โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
/athletes/{athlete_id}:
get:
summary: Get athlete profile
parameters:
- name: athlete_id
in: path
required: true
schema:
type: string
responses:
"200":
description: Athlete profile
content:
application/json:
schema:
$ref: "#/components/schemas/Athlete"

/cases/{athlete_id}:
get:
summary: Get active case for an athlete (latest if multiple)
parameters:
- name: athlete_id
in: path
required: true
schema:
type: string
responses:
"200":
description: Full case data including milestones and timeline
content:
application/json:
schema:
$ref: "#/components/schemas/Case"
"404":
description: No active case found for this athlete

/athletes/{athlete_id}/case:
get:
summary: Combined endpoint โ€” returns athlete + active case in one call
description: |
Frontend currently makes TWO separate fetches (athletes.json + cases.json)
and joins on athlete_id. This endpoint wraps both into one response
for the athlete detail overlay.
parameters:
- name: athlete_id
in: path
required: true
schema:
type: string
responses:
"200":
description: Athlete and case data merged
content:
application/json:
schema:
type: object
properties:
athlete:
$ref: "#/components/schemas/Athlete"
case:
$ref: "#/components/schemas/Case"

# โ”€โ”€ Dashboard Data โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
/dashboard/at:
get:
summary: AT dashboard โ€” quick stats and active cases
responses:
"200":
content:
application/json:
schema:
type: object
properties:
stats:
type: object
properties:
full_count:
type: integer
example: 72
modified_count:
type: integer
example: 8
out_count:
type: integer
example: 3
active_cases:
type: array
items:
$ref: "#/components/schemas/CaseSummary"
recent_activity:
type: array
items:
$ref: "#/components/schemas/ActivityItem"

# โ”€โ”€ Sideline โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
/body-parts:
get:
summary: Body part categories and parts for the sideline entry picker
responses:
"200":
description: Body part hierarchy (categories โ†’ parts)
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/BodyPartCategory"

components:
schemas:
Athlete:
type: object
required:
- id
- first_name
- last_name
- sport
- team
- grade
properties:
id:
type: string
example: "ath_001"
first_name:
type: string
example: "Jake"
last_name:
type: string
example: "Larson"
sport:
type: string
example: "Football"
team:
type: string
example: "Varsity"
grade:
type: integer
example: 11
initials:
type: string
example: "JL"
description: Computed from first/last name, could also be server-generated
active:
type: boolean
default: true

Case:
  type: object
  required:
    - case_id
    - athlete_id
    - injury
    - status
  properties:
    case_id:
      type: string
      example: "cas_001"
    athlete_id:
      type: string
      example: "ath_001"
    injury:
      type: string
      example: "Ankle Sprain (Grade 2)"
    injury_date:
      type: string
      format: date
      example: "2026-04-28"
    body_part:
      type: string
      example: "Ankle"
    side:
      type: string
      enum: [Left, Right, null]
      nullable: true
      example: "Right"
    severity:
      type: string
      enum: [mild, moderate, severe]
    attention:
      type: string
      enum: [stable, urgent, warning]
      description: >-
        stable = on track. warning = behind schedule, need check-in.
        urgent = medical concern, review today.
    status:
      type: string
      enum: [active, cleared, referred]
    phase:
      type: integer
      example: 2
    total_phases:
      type: integer
      example: 4
    phase_label:
      type: string
      description: Human-readable current phase name
      example: "Active Rehab"
    projected_return:
      type: string
      format: date
      nullable: true
      example: "2026-05-12"
    last_updated:
      type: string
      example: "2026-05-01 14:00"
    last_updated_by:
      type: string
      example: "You"
    notified:
      type: array
      items:
        type: string
      example: ["Coach Andrews", "Parent"]
    milestones:
      type: array
      items:
        $ref: "#/components/schemas/Milestone"
    timeline:
      type: array
      items:
        $ref: "#/components/schemas/TimelineEvent"

Milestone:
  type: object
  properties:
    num:
      type: integer
      description: Phase number (1-based)
      example: 2
    label:
      type: string
      description: Phase name
      example: "Active Rehab"
    status:
      type: string
      enum: [done, current, pending]
    completed:
      type: string
      format: date
      nullable: true
    note:
      type: string
      example: "Walking without limp. ROM 75%. Strength work initiated."

TimelineEvent:
  type: object
  properties:
    date:
      type: string
      example: "Apr 28 ยท 3:15 PM"
      description: Display-ready date string or ISO-8601 timestamp
    title:
      type: string
      example: "Initial Assessment"
    note:
      type: string
      example: "Grade 2 lateral ankle sprain. Swelling +2, unable to bear weight."
    by:
      type: string
      example: "You"
    type:
      type: string
      enum: [assessment, restriction, milestone, clearance, note]
      description: Drives the colored dot in the timeline UI

CaseSummary:
  type: object
  properties:
    athlete_id:
      type: string
    athlete_name:
      type: string
    initials:
      type: string
    sport:
      type: string
    injury:
      type: string
    injury_short:
      type: string
      example: "Ankle sprain (Grade 2)"
    status:
      type: string
      enum: [active, cleared, referred]
    status_label:
      type: string
      example: "Phase 2/4"
    avatar_color:
      type: string
      description: CSS-compatible color string for avatar background
      example: "teal"

ActivityItem:
  type: object
  properties:
    type:
      type: string
      enum: [cleared, out, modified]
    text:
      type: string
      example: "Marcus Johnson cleared for full practice"
    time_ago:
      type: string
      example: "2h ago"

BodyPartCategory:
  type: object
  properties:
    name:
      type: string
      example: "Lower Body"
    parts:
      type: array
      items:
        type: object
        properties:
          id:
            type: string
            example: "ankle"
          label:
            type: string
            example: "Ankle"
          icon:
            type: string
            example: "๐Ÿฆถ"