# Project export: PhysioLens

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2026
- Tagline: AI-powered physical therapy platform that provides professional-grade biomechanical analysis from any smartphone or laptop camera.
- Devpost: https://devpost.com/software/physiolens
- GitHub: https://github.com/sherwinvishesh/PhysioLens
- Video: https://www.youtube.com/embed/KL5bgOmMvLI?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 2 GitHub contributor(s) — aaravmat1209 (11 commits), Sherwin Vishesh Jathanna (5 commits)

## Devpost submission (written by the team)

### Inspiration

Two months ago, our teammate Sherwin underwent surgery. His recovery required weekly physiotherapy sessions where he'd receive new exercises to perform at home. The problem? Small mistakes with catastrophic consequences. Picture this: Sherwin performs his bicep curls but doesn't realize his elbow is drifting forward. His shoulder rotates slightly during lateral raises. His back arches during shoulder presses. These aren't major failures, they're subtle form deviations that feel "close enough." But in physical therapy, "close enough" isn't good enough. The reality is brutal: Recovery times extended by weeks due to incorrect form Billions of dollars wasted on preventable extended therapy No feedback between weekly PT sessions—you're flying blind Patients don't know they're doing exercises wrong until their next appointment Thousands of patients make similar mistakes every single day I realized that traditional PT gives you exercises on paper, sends you home, and hopes you do them correctly. There's zero real-time feedback, zero performance tracking, and zero accountability between sessions. We needed something that meets patients where they are—at home—and provides the professional-grade coaching they'd get in a clinic. Something that uses AI to analyze every rep, catches mistakes before they become habits, and gives doctors actual data instead of patient self-reports. PhysioLens was born from this frustration. It's the AI physical therapist I wish Sherwin had during his recovery.

### What it does

PhysioLens is an AI-powered physical therapy platform that transforms your home into a professional rehabilitation clinic. Just turn on your camera, and watch the magic happen: 🎯 For Doctors: AI-Powered Exercise Creation Type a description: "Tricep extensions for post-surgical shoulder rehabilitation" Claude AI instantly generates: Camera positioning requirements Precise angle thresholds for rep counting Step-by-step patient instructions Automated form checks PubMed research references supporting the exercise protocol Camera positioning requirements Precise angle thresholds for rep counting Step-by-step patient instructions Automated form checks PubMed research references supporting the exercise protocol Production-ready exercise configuration in 30 seconds to 5 minutes Built-in library: 5 professionally configured exercises Unlimited custom AI-generated exercises 🏃‍♂️ For Patients: Real-Time AI Coaching Dual video feed: Raw camera + AI skeleton overlay 10-second countdown with on-screen positioning guidance Automatic rep counting using biomechanical angle analysis Instant form warnings: "Elbow drifting - keep it stable!", "Using momentum - slow down!" Real-time angle display with target ranges Phase tracking: "Down" → "Up" with progress bar Target completion popup when reps reached 🤖 Meeting Mode: Voice-Powered Clinical Assistant Continuous voice transcription during exercise sessions Emergency detection: "My knee hurts really bad" → Instant alert with urgency score Meeting scheduling: "Let's schedule a follow-up next Tuesday at 3 PM" → Auto-captured and calendared AI-generated clinical summaries after every session: Chief complaint extraction Performance + conversation insights Patient mood assessment Compliance level tracking Follow-up recommendations Chief complaint extraction Performance + conversation insights Patient mood assessment Compliance level tracking Follow-up recommendations Advanced Session Analysis AI Performance Scoring (0-100): Weighted algorithm considering reps completed, form issues, and severity Scoring philosophy: 80-85 is excellent (perfect form is rare) Biomechanical Issue Detection (9 Categories): Tremor/Instability, Compensation Patterns, Speed Variations Range of Motion Issues, Balance Problems, Form Deviations Asymmetry Detection, Fatigue Signs, and more Click any issue → jumps to exact timestamp in video Clinical Research Integration: PubMed API: Automatic research references BrightData Web Scraping: NICE, NHS, CSP clinical guidelines Evidence-based recommendations with clickable citations Clinical Notes Dashboard AI-generated clinical summaries for every session Scheduled meetings from voice transcriptions Performance metrics tracking Complete patient records

### How we built it

PhysioLens is a sophisticated full-stack application combining AI, computer vision, and clinical research: Frontend React 18 with Vite for lightning-fast development MediaPipe Pose for 33-point skeletal tracking React Router v6 for client-side routing Custom utilities for angle calculations and rep counting Real-time pose detection at 30 FPS with <50ms latency Backend FastAPI (Python 3.8+) for high-performance async API Pydantic v2 for request/response validation In-memory storage for MVP (production-ready for database migration) 12 RESTful API endpoints for exercise management, session recording, and research AI Engine Claude Sonnet 4 for exercise generation, performance analysis, and clinical summaries Structured JSON output with prompt engineering Context window management for efficient processing Multi-model approach for different use cases Research Integration PubMed API for medical research papers BrightData Web MCP with Claude Agent SDK Agentic scraping of NICE, NHS, and CSP websites Structured extraction with proper citations Voice Processing Web Speech API for browser-native transcription Real-time processing with auto-restart logic Emergency and meeting keyword detection Client-side processing for privacy Video Recording System MediaRecorder API for session recording Pose data logging (33 landmarks × 3D coordinates) LocalStorage for session persistence Blob creation and URL generation Rep Counting Algorithm Generic angle-based counter with phase state machine 15° hysteresis prevents false triggers 5-frame exponential moving average for smoothing 95%+ accuracy compared to manual counting Advanced Analysis Engine SessionAnalyzer with 9 detection modules Processes sessions 5-10x faster than real-time Smart deduplication prevents spam Issue confidence scoring and severity classification Key Technologies

### Challenges we ran into

🌐 BrightData Integration Evolution Initial Approach: Started with BrightData's Browser API for static site structures, which limited website coverage and response quality. The Breakthrough: During a sponsor panel session, BrightData recommended switching to their agentic framework with MCP tools integrated. What changed: Agentic search with Claude AI intelligently queries multiple sources MCP tools (search_engine, scrape, grep) for advanced extraction Pro Mode unlocked full tool access Context-aware medical terminology understanding Result: 9-12 high-quality clinical references per exercise vs 0-2 broken snippets before ⏱️ 10-Second Countdown Implementation MediaPipe onPoseResults callback captured stale state due to closures. React state updates didn't re-register the callback. Solution: Used useRef instead of useState for mutable values that callbacks need to access. 🎥 MediaRecorder State Management Recording would sometimes stop unexpectedly or duplicate chunks. Solved with dual state tracking and safe start/stop guards. 🧹 Cleanup & Memory Leaks Memory usage climbing and camera not releasing when navigating away. Implemented comprehensive cleanup function with double-cleanup prevention. 🎯 False Positive Form Warnings Users got spammed with warnings. Drastically increased thresholds (5x for tremor, 33% for lateral lean) and added better deduplication. ⚡ AI API Rate Limits Hit Claude API rate limits during testing. Added random delays and planned request queue with exponential backoff for production. 🕐 Time Pressure Built the entire system in under 36 hours. Had to cut features like user authentication and multi-patient support to focus on core MVP. The lesson? Ship a great core experience beats shipping 10 half-broken features.

### Accomplishments we're proud of

✅ We Actually Finished (And Shipped Early!) Completed 6 hours before the deadline All core features working end-to-end Zero critical bugs in final build Professional-grade polish 🎯 Real Impact Potential The numbers that matter: Average PT session: $150-200 Typical patient needs: 12-24 sessions ($1,800-4,800 total) If PhysioLens reduces sessions by 20%: $360-960 saved per patient Over 10 million Americans undergo PT annually Billions of dollars wasted on preventable extended therapy If PhysioLens helps just 1,000 patients: $360,000-960,000 in healthcare savings 20,000-60,000 hours of patient time saved Countless improved quality-of-life outcomes 🤖 AI That Actually Works Exercise generation: ~95% success rate, 30 seconds to 5 minutes Performance analysis: Processes 5,000+ pose frames per session Clinical summaries: Structured medical note format Emergency detection: Zero false negatives, ~5% false positive rate 🏗️ Engineering Excellence Smart rep counting with 95%+ accuracy Advanced analysis 5-10x faster than real-time Beautiful UX that doesn't suck Full-stack mastery across 8+ technologies 💡 We Learned From Our Mistakes The BrightData pivot showed the power of asking for sponsor help early. Went from failing static scraping to getting 10x better results with agentic framework. 🏆 Built Something We're Proud to Show Demoed to PT patients, physical therapists, and hackathon judges—all saw real value. This could be a real business.

### What we learned

🎓 From Our Sponsors Anthropic & Claude AI: Prompt engineering is everything—specificity drives quality Context window management for efficient processing Function calling for structured JSON output Cost optimization strategies ($0.05-0.15 per session) Claude's medical knowledge is genuinely impressive BrightData & Web Scraping: Agentic scraping > Traditional scraping MCP gives Claude powerful extraction tools Pro Mode unlocks full capabilities 5-minute sponsor conversation > hours of documentation OpenEvidence: Healthcare data must be evidence-based, not anecdotal Every recommendation needs research citations Higher bar for medical tools than consumer apps Zingage: Understanding the patient journey is critical Healthcare products must be empathetic, not just functional Focus on emotional states patients experience Stanford TreeHacks: Hackathons are innovation accelerators Constraints drive creativity Community makes the difference Impact over perfection 🛠️ Technical Skills Leveled Up Computer vision (MediaPipe, angle math, skeleton rendering) Voice processing (Web Speech API, continuous transcription) AI engineering (prompt engineering, RAG, cost optimization) Web scraping (agentic scraping, MCP tools) State management (useRef vs useState, cleanup functions) Healthcare domain (PT workflows, biomechanics, clinical notes) 💡 Product Philosophy The biggest learning: Technology is easy. Impact is hard. Start with the problem, not the tech. Talk to users. Measure what matters. Build for outcomes.

### What's next

🚀 Immediate Optimization User testing with 10-20 real PT patients Production infrastructure (PostgreSQL, authentication, cloud deployment) Security hardening (HIPAA compliance considerations) Cost optimization for scale 📱 Mobile App Native iOS/Android apps (80% of PT patients prefer mobile) Better camera angles and movement tracking Offline mode for exercises without internet 🌐 Multi-Provider Platform Support for multiple doctors and clinics Patient portal for progress tracking Doctor dashboard for patient management Insurance integration for reimbursement 🔬 Advanced Features Exercise progression algorithms Predictive analytics for recovery timelines Integration with wearables (Apple Watch, Fitbit) Telemedicine video consultations 💼 Go-to-Market Strategy Pilot program with 3-5 local PT clinics Pricing model: $29/month per patient or clinic licensing Insurance partnerships for coverage Clinical trials for FDA clearance (if needed) The vision: Make professional-grade physical therapy accessible to everyone, everywhere. PhysioLens could save billions in healthcare costs and help millions recover faster. Acknowledgments Anthropic - Claude AI for exercise generation and analysis Google MediaPipe - Pose detection technology PubMed/NCBI - Medical research database BrightData - Web scraping infrastructure OpenEvidence - For empowering us to create innovative healthcare solutions Zingage - For supporting our journey in building impactful health technology products Stanford TreeHacks - For providing the opportunity to participate in this incredible hackathon and bring PhysioLens to life

## README (from the GitHub repository)

# PhysioLens : AI-Powered Physical Therapy Platform

## Overview

PhysioLens is a comprehensive AI-powered physical therapy platform that combines computer vision pose detection to deliver professional-grade rehabilitation at home. The system enables doctors to assign exercises to patients, tracks exercise performance in real-time, and generates clinical summaries using AI.

## Key Features

### Core Capabilities

- **AI-Powered Exercise Creation**: Doctors can create custom exercises by providing a description and optional image. Claude AI automatically generates:
  - Camera positioning requirements (upper body, full body, lower body)
  - Rep counting algorithms with angle thresholds
  - Step-by-step instructions
  - Form checks and safety warnings
  - Clinical research references from PubMed

- **Real-Time Pose Detection**: Uses MediaPipe for accurate skeletal tracking with:
  - Dual video feed (raw + skeleton overlay)
  - Automatic rep counting
  - Form deviation detection
  - Live angle measurements

- **Meeting Mode (Voice Coaching)**: 
  - Continuous voice transcription during sessions
  - Automatic emergency detection with instant alerts
  - Meeting/appointment scheduling detection
  - AI-generated clinical summaries after sessions

- **Comprehensive Session Analysis**:
  - Records video + pose data for later review
  - AI performance scoring (0-100)
  - Detailed biomechanical analysis detecting:
    - Tremor/instability
    - Compensation patterns
    - Speed variations
    - Range of motion issues
    - Form deviations
  - Clinical research integration via PubMed and BrightData web scraping

### 👨‍⚕️ Doctor Dashboard

- Browse and assign 5 built-in exercises + unlimited custom AI-generated exercises
- Set target reps for each patient
- Create custom exercises using Claude AI
- View assigned exercises and completion status

### 🏃‍♂️ Patient Interface

- View assigned exercises with instructions
- Start guided exercise sessions with:
  - 10-second countdown before rep counting begins
  - Real-time camera positioning guidance
  - Live rep counting and angle feedback
  - Optional video recording for analysis
- Review session history with AI performance insights
- Access clinical notes and scheduled meetings

### Analytics & Reporting

- **Session History**: 
  - Video playback with timestamp navigation
  - AI-generated performance scores
  - Detailed issue detection with severity levels
  - Research references from clinical literature

- **Clinical Notes**:
  - AI-generated session summaries
  - Patient mood and compliance tracking
  - Follow-up recommendations
  - Scheduled appointments

## Technology Stack

### Frontend
- **React 18** with Vite
- **React Router** for navigation
- **Google MediaPipe** for pose detection
  - `@mediapipe/pose` - Skeletal tracking
  - `@mediapipe/camera_utils` - Camera integration
  - `@mediapipe/drawing_utils` - Skeleton visualization

### Backend
- **FastAPI** (Python) - RESTful API
- **Claude AI (Anthropic)** - Exercise generation, analysis, and clinical summaries
- **PubMed API** - Medical research integration
- **BrightData Web MCP** - Clinical resource scraping (NICE, NHS, CSP, and more)
- **Web Speech API** - Voice transcription

### AI Integration
- Claude Sonnet 4 for:
  - Custom exercise configuration generation
  - Performance analysis and scoring
  - Clinical summary generation
  - Emergency/meeting detection from voice

## Project Structure

```
physiolens/
├── backend/
│   ├── main.py                           # FastAPI server
│   ├── services/
│   │   └── brightdata_service.py         # Web scraping for clinical resources
│   └── requirements.txt
├── frontend/
│   ├── src/
│   │   ├── components/                   # React components
│   │   │   ├── CameraPositioning.jsx
│   │   │   ├── FormFeedback.jsx
│   │   │   ├── References.jsx
│   │   │   ├── ClinicalResources.jsx
│   │   │   ├── EmergencyAlert.jsx
│   │   │   └── MeetingSchedulePopup.jsx
│   │   ├── contexts/
│   │   │   └── MeetingModeContext.jsx    # Voice transcription state
│   │   ├── pages/                        # Main views
│   │   │   ├── LandingPage.jsx
│   │   │   ├── DoctorView.jsx
│   │   │   ├── PatientView.jsx
│   │   │   ├── AddExercise.jsx
│   │   │   ├── ExerciseDetail.jsx
│   │   │   ├── ExerciseSession.jsx
│   │   │   ├── SessionHistory.jsx
│   │   │   ├── ClinicalNotes.jsx
│   │   │   └── UpcomingMeetings.jsx
│   │   ├── utils/                       # Core algorithms
│   │   │   ├── exerciseConfigs.js       # Exercise configurations
│   │   │   ├── repCounters.js           # Rep counting logic
│   │   │   ├── formAnalysis.js          # Form checking
│   │   │   ├── poseUtils.js             # Angle calculations
│   │   │   └── advancedAnalysis.js      # Session analysis
│   │   ├── styles/
│   │   └── App.jsx
│   └── package.json
├── README.md
├── .gitignore
└── LICENCE
```

## Installation

### Prerequisites

- **Node.js** 18+ and npm
- **Python** 3.8+
- **Anthropic API Key** (for Claude AI)
- **BrightData API Token** (optional, for clinical resource scraping)

### Backend Setup

1. Navigate to backend directory:
```bash
cd backend
```

2. Create virtual environment:
```bash
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
```

3. Install dependencies:
```bash
pip install -r requirements.txt --break-system-packages
```

4. Create `.env` file:
```env
ANTHROPIC_API_KEY=your_claude_api_key_here
BRIGHTDATA_WS_ENDPOINT=your_brightdata_endpoint
BRIGHTDATA_API_TOKEN=your_brightdata_token_here  
```

5. Run server:
```bash
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```

### Frontend Setup

1. Navigate to frontend directory:
```bash
cd frontend
```

2. Install dependencies:
```bash
npm install
```

3. Run development server:
```bash
npm run dev
```

4. Open browser to `http://localhost:5173`

## Usage Guide

### For Doctors

1. **Navigate to Doctor View** from landing page
2. **Assign Exercises**:
   - Select up to 5 exercises from the library
   - Set target reps for each exercise
   - Click "Assign Exercises"
3. **Create Custom Exercise** (optional):
   - Click "Add Custom Exercise"
   - Provide exercise name and detailed description
   - Optionally upload an image
   - Claude AI generates complete configuration (30s - 5min)
   - Review generated instructions and parameters

### For Patients

1. **Navigate to Patient View** from landing page
2. **Review Assigned Exercises**
3. **Start Exercise Session**:
   - Click on an exercise
   - Review instructions
   - Enable "Video Guided Session" for recording (optional)
   - Click "Start Exercise Session"
   - Position yourself within camera frame (guidance provided)
   - 10-second countdown before rep counting begins
   - Perform exercise - AI tracks reps and form
   - Click "Complete Session" when done
4. **Review History**:
   - View recorded sessions
   - Watch video playback
   - See AI performance analysis
   - Review clinical research references

### Meeting Mode (Voice Coaching)

1. **Enable Meeting Mode** on landing page
2. Voice recording starts automatically
3. System continuously monitors for:
   - Emergency keywords → Instant alert popup
   - Meeting scheduling → Auto-capture and confirm
4. After session, AI generates clinical summary
5. View summaries in "Clinical Notes"

## Built-in Exercises

1. **Bicep Curls** (ID: 3) - Upper body, intermediate
2. **Lateral Raises** (ID: 5) - Upper body, beginner
3. **Front Raises** (ID: 6) - Upper body, beginner
4. **Standing Leg Raises** (ID: 8) - Full body, beginner

## AI Analysis Features

### Performance Scoring (0-100)
- Reps completed vs target
- Form quality assessment
- Issue severity weighting
- Strengths and weaknesses identification
- Actionable recommendations

### Detected Issues
- **Tremor/Instability**: Joint shaking during movement
- **Opposite Hand Support**: Using non-working hand for assistance
- **Compensation Patterns**: Leaning, twisting, momentum use
- **Speed Vari

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 43 recognized source files, 378 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code

## Codebase structure (from repository index)

### Files (48 of 48)

```
.gitignore
backend/main.py
backend/requirements.txt
backend/services/brightdata_service.py
frontend/.gitignore
frontend/eslint.config.js
frontend/index.html
frontend/package.json
frontend/README.md
frontend/src/App.css
frontend/src/App.jsx
frontend/src/components/CameraPositioning.jsx
frontend/src/components/ClinicalResources.jsx
frontend/src/components/EmergencyAlert.jsx
frontend/src/components/FormFeedback.jsx
frontend/src/components/MeetingModeIndicator.jsx
frontend/src/components/MeetingSchedulePopup.jsx
frontend/src/components/References.jsx
frontend/src/contexts/MeetingModeContext.jsx
frontend/src/index.css
frontend/src/main.jsx
frontend/src/pages/AddExercise.jsx
frontend/src/pages/ClinicalNotes.jsx
frontend/src/pages/DoctorView.jsx
frontend/src/pages/ExerciseDetail.jsx
frontend/src/pages/ExerciseSession.jsx
frontend/src/pages/LandingPage.jsx
frontend/src/pages/PatientView.jsx
frontend/src/pages/SessionHistory.jsx
frontend/src/pages/UpcomingMeetings.jsx
frontend/src/styles/AddExercise.css
frontend/src/styles/CameraPositioning.css
frontend/src/styles/ClinicalNotes.css
frontend/src/styles/DoctorView.css
frontend/src/styles/ExerciseDetail.css
frontend/src/styles/ExerciseSession.css
frontend/src/styles/FormFeedback.css
frontend/src/styles/LandingPage.css
frontend/src/styles/PatientView.css
frontend/src/styles/SessionHistory.css
frontend/src/utils/advancedAnalysis.js
frontend/src/utils/exerciseConfigs.js
frontend/src/utils/formAnalysis.js
frontend/src/utils/poseUtils.js
frontend/src/utils/repCounters.js
frontend/vite.config.js
LICENSE
Readme.md
```

### Dependencies

- backend/requirements.txt: anthropic, claude-agent-sdk, fastapi@>=0.115.0, httpx, playwright, pydantic@>=2.5.0, python-dotenv, python-multipart, uvicorn[standard]@>=0.32.0
- frontend/package.json: @mediapipe/camera_utils@^0.3.1675466862, @mediapipe/drawing_utils@^0.3.1675466124, @mediapipe/pose@^0.5.1675469404, @mediapipe/tasks-vision@^0.10.32, @types/react@^18.2.43, @types/react-dom@^18.2.17, @vitejs/plugin-react@^4.2.1, react@^18.2.0, react-dom@^18.2.0, react-router-dom@^6.20.0, vite@^5.0.8

### Recent commits (newest first)

- Corrections
- Add MIT License to the project
- [Stable] Finalised commit
- Merge pull request #2 from sherwinvishesh/frontend-all
- feat: Enhance header styling in SessionHistory and ClinicalNotes, and refine exercise assignment logic to update or append existing exercises.
- feat: Implement a monochrome theme for the Clinical Notes page and update pricing details on the Landing Page.
- refactor: Extract inline styles from ClinicalResources and SessionHistory components into dedicated CSS classes and a new stylesheet, and add state reset to ClinicalResources.
- did the exercises page
- feat: Implement a new UI design for PatientView and ExerciseDetail, including dedicated styling and updated components.
- feat: Implement manual summary generation for meeting mode, integrate its toggle on the landing page, and update the landing page roles grid to 4 columns.
- refactor: Overhaul Add Exercise and Doctor View UI with a new design system and premium styling.
- doctor frontend initial
- ui-oldpush
- done with landing page
- Convert frontend from nested repo/submodule into normal folder with actual files
- Push with all features

## Key source files (fetched from GitHub, selected and truncated for size)

### backend/requirements.txt

```
fastapi>=0.115.0
uvicorn[standard]>=0.32.0
pydantic>=2.5.0
httpx
anthropic
python-multipart
python-dotenv
playwright
claude-agent-sdk
```

### frontend/package.json

```
{
  "name": "physiolens-frontend",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@mediapipe/camera_utils": "^0.3.1675466862",
    "@mediapipe/drawing_utils": "^0.3.1675466124",
    "@mediapipe/pose": "^0.5.1675469404",
    "@mediapipe/tasks-vision": "^0.10.32",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.20.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.43",
    "@types/react-dom": "^18.2.17",
    "@vitejs/plugin-react": "^4.2.1",
    "vite": "^5.0.8"
  }
}

```

### frontend/src/main.jsx

```javascript
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './App.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)
```

### frontend/src/App.jsx

```javascript
// frontend/src/App.jsx

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import { MeetingModeProvider } from './contexts/MeetingModeContext'
import MeetingModeIndicator from './components/MeetingModeIndicator'
import EmergencyAlert from './components/EmergencyAlert'
import MeetingSchedulePopup from './components/MeetingSchedulePopup'
import LandingPage from './pages/LandingPage'
import DoctorView from './pages/DoctorView'
import PatientView from './pages/PatientView'
import ExerciseDetail from './pages/ExerciseDetail'
import ExerciseSession from './pages/ExerciseSession'
import SessionHistory from './pages/SessionHistory'
import AddExercise from './pages/AddExercise'
import UpcomingMeetings from './pages/UpcomingMeetings'
import ClinicalNotes from './pages/ClinicalNotes'

function App() {
  return (
    <MeetingModeProvider>
      <Router
        future={{
          v7_startTransition: true,
          v7_relativeSplatPath: true,
        }}
      >
        <MeetingModeIndicator />
        <EmergencyAlert />
        <MeetingSchedulePopup />
        
        <Routes>
          <Route path="/" element={<LandingPage />} />
          <Route path="/doctor" element={<DoctorView />} />
          <Route path="/add-exercise" element={<AddExercise />} />
          <Route path="/patient" element={<PatientView />} />
          <Route path="/exercise/:exerciseId" element={<ExerciseDetail />} />
          <Route path="/session/:exerciseId" element={<ExerciseSession />} />
          <Route path="/session-history" element={<SessionHistory />} />
          <Route path="/upcoming-meetings" element={<UpcomingMeetings />} />
          <Route path="/clinical-notes" element={<ClinicalNotes />} />
        </Routes>
      </Router>
    </MeetingModeProvider>
  )
}

export default App
```

### backend/main.py

```python
from fastapi import FastAPI, HTTPException, File, UploadFile, Form
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Optional
import httpx
import os
import base64
from dotenv import load_dotenv
import xml.etree.ElementTree as ET
from datetime import datetime
import json
from services.brightdata_service import BrightDataService

load_dotenv()

app = FastAPI(title="PhysioLens API")

# Enable CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Data Models
class Exercise(BaseModel):
    id: int
    name: str
    description: str
    instructions: List[str]
    duration: str
    difficulty: str

class ExerciseAssignment(BaseModel):
    exercise_id: int
    target_reps: int

class AssignExercisesRequest(BaseModel):
    assignments: List[ExerciseAssignment]

class AssignedExercise(BaseModel):
    id: int
    name: str
    description: str
    instructions: List[str]
    duration: str
    difficulty: str
    target_reps: int
    completed: bool = False

class WarningEvent(BaseModel):
    timestamp: float
    message: str
    severity: str

class RecordingSession(BaseModel):
    exercise_id: int
    exercise_name: str
    completed_at: str
    duration: int
    rep_count: int
    target_reps: int
    warnings: List[WarningEvent]

class AnalysisRequest(BaseModel):
    session_data: dict
    analysis_results: dict

class CreateExerciseRequest(BaseModel):
    name: str
    description: str
    image_base64: Optional[str] = None

class TranscriptAnalysis(BaseModel):
    transcript: str
    phase: str

class Meeting(BaseModel):
    id: Optional[int] = None
    scheduled_date: Optional[str] = None
    title: Optional[str] = None
    patient_name: Optional[str] = None
    doctor_name: Optional[str] = None
    extracted_phrase: Optional[str] = None
    date: Optional[str] = None
    time: Optional[str] = None
    created_at: Optional[str] = None

class TranscriptChunk(BaseModel):
    text: str

class SummaryRequest(BaseModel):
    transcript: str
    duration: int
    detectedMeetings: list
    detectedEmergencies: list
    sessionContext: dict

# In-memory storage
assigned_exercises = []
recorded_sessions = [] 
custom_exercises = []
meetings_db = []
next_exercise_id = 9
next_meeting_id = 1

# Built-in exercises
EXERCISES = [
    {
        "id": 3,
        "name": "Bicep Curls",
        "description": "Builds arm strength and muscle tone",
        "instructions": [
            "Stand with feet shoulder-width apart",
            "Hold a light weight in each hand, palms facing forward",
            "Keep elbows close to your body",
            "Slowly curl weights toward shoulders",
            "Pause at the top, then slowly lower",
            "Repeat for the target number of reps"
        ],
        "duration": "5-10 minutes",
        "difficulty": "Intermediate"
    },
    {
        "id": 4,
        "name": "Shoulder Press",
        "description": "Strengthens shoulders and upper arms",
        "instructions": [
            "Stand with feet shoulder-width apart",
            "Hold weights at shoulder level, elbows bent at 90 degrees",
            "Keep your core engaged and back straight",
            "Press weights straight up overhead",
            "Fully extend your arms at the top",
            "Lower back to starting position with control"
        ],
        "duration": "5-10 minutes",
        "difficulty": "Intermediate"
    },
    {
        "id": 5,
        "name": "Lateral Raises",
        "description": "Targets shoulder muscles for better definition",
        "instructions": [
            "Stand with feet hip-width apart",
            "Hold light weights at your sides, palms facing inward",
            "Keep a slight bend in your elbows",
            "Raise arms out to the sides until shoulder height",
            "Pause briefly at the top",
            "Lower back down slowly and with control"
        ],
        "duration": "5-8 minutes",
        "difficulty": "Beginner"
    },
    {
        "id": 6,
        "name": "Front Raises",
        "description": "Builds front shoulder strength and stability",
        "instructions": [
            "Stand with feet shoulder-width apart",
            "Hold weights in front of thighs, palms facing down",
            "Keep arms mostly straight with slight elbow bend",
            "Raise weights forward to shoulder level",
            "Keep your core tight and avoid leaning back",
            "Lower weights back down with control"
        ],
        "duration": "5-8 minutes",
        "difficulty": "Beginner"
    },
    {
        "id": 8,
        "name": "Standing Leg Raises",
        "description": "Strengthens hip flexors and improves balance",
        "instructions": [
            "Stand tall with feet together",
            "Hold onto a chair or wall for balance if needed",
            "Keep your standing leg slightly bent",
            "Raise one leg forward to about hip height",
            "Keep your leg straight and core engaged",
            "Lower leg back down with control and repeat"
        ],
        "duration": "5-10 minutes",
        "difficulty": "Beginner"
    }
]

# PubMed API Helper Functions
async def search_pubmed(query: str, max_results: int = 5):
    """Search PubMed for research papers"""
    base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
    
    params = {
        "db": "pubmed",
        "term": query,
        "retmax": max_results,
        "retmode": "json",
        "sort": "relevance"
    }
    
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(base_url, params=params, timeout=10.0)
            if response.status_code == 200:
                data = response.json()
                ids = data.get("esearchresult", {}).get("idlist", [])
                return ids
            return []

[truncated — 25488 more characters]
```

### frontend/vite.config.js

```javascript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 5173
  }
})
```

### frontend/index.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PhysioLens - AI Physical Therapy</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>
```

### frontend/eslint.config.js

```javascript
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{js,jsx}'],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat.recommended,
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaVersion: 'latest',
        ecmaFeatures: { jsx: true },
        sourceType: 'module',
      },
    },
    rules: {
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
    },
  },
])

```

### frontend/src/index.css

```css
:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  font-weight: 500;
  color: #646cff;
  text-decoration: inherit;
}
a:hover {
  color: #535bf2;
}

body {
  margin: 0;
  display: flex;
  place-items: center;
  min-width: 320px;
  min-height: 100vh;
}

h1 {
  font-size: 3.2em;
  line-height: 1.1;
}

button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}

```

### frontend/src/App.css

```css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
  min-height: 100vh;
  color: #ffffff;
}

#root {
  min-height: 100vh;
}

/* Landing Page Styles */
.landing-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 20px;
  text-align: center;
}

.landing-header {
  margin-bottom: 60px;
}

.landing-header h1 {
  font-size: 4rem;
  color: white;
  margin-bottom: 15px;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4);
}

.landing-header p {
  font-size: 1.3rem;
  color: rgba(255, 255, 255, 0.9);
  max-width: 700px;
  margin: 0 auto;
  line-height: 1.6;
}

.role-buttons {
  display: flex;
  gap: 40px;
  flex-wrap: wrap;
  justify-content: center;
}

.role-button {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border: 2px solid rgba(255, 255, 255, 0.2);
  padding: 40px 60px;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  min-width: 280px;
}

.role-button:hover {
  transform: translateY(-5px);
  box-shadow: 0 15px 40px rgba(102, 126, 234, 0.4);
  background: rgba(102, 126, 234, 0.2);
  border-color: rgba(102, 126, 234, 0.5);
}

.role-button-icon {
  font-size: 4rem;
  margin-bottom: 20px;
}

.role-button h2 {
  font-size: 2rem;
  color: #ffffff;
  margin-bottom: 10px;
}

.role-button p {
  font-size: 1rem;
  color: rgba(255, 255, 255, 0.8);
}

/* Common Page Styles */
.page-container {
  min-height: 100vh;
  padding: 40px 20px;
}

.page-header {
  text-align: center;
  margin-bottom: 40px;
}

.page-header h1 {
  color: white;
  font-size: 3rem;
  margin-bottom: 15px;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4);
}

.page-header p {
  color: rgba(255, 255, 255, 0.9);
  font-size: 1.2rem;
}

.content-card {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 15px;
  padding: 40px;
  max-width: 1200px;
  margin: 0 auto;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}

/* Button Styles */
.btn {
  padding: 12px 30px;
  border: none;
  border-radius: 8px;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 600;
}

.btn-primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}

.btn-secondary {
  background: rgba(255, 255, 255, 0.1);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.btn-secondary:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
}

.btn-success {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: white;
  box-shadow: 0 4px 15px rgba(16, 185, 129, 0.4);
}

.btn-success:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(16, 185, 129, 0.6);
}

.btn-danger {
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
  color: white;
  box-shadow: 0 4px 15px rgba(239, 68, 68, 0.4);
}

.btn-danger:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(239, 68, 68, 0.6);
}

.back-button {
  margin-bottom: 20px;
}

/* Doctor View Styles */
.exercise-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  margin-bottom: 40px;
}

.exercise-card {
  border: 2px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  padding: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.exercise-card:hover {
  border-color: #667eea;
  transform: translateY(-3px);
  box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
  background: rgba(102, 126, 234, 0.1);
}

.exercise-card.selected {
  border-color: #667eea;
  background: rgba(102, 126, 234, 0.2);
}

.exercise-card-header {
  display: flex;
  justify-content: space-between;
  align-items: start;
  margin-bottom: 10px;
}

.exercise-card h3 {
  font-size: 1.3rem;
  color: #ffffff;
  margin-bottom: 5px;
}

.checkbox {
  width: 24px;
  height: 24px;
  cursor: pointer;
}

.difficulty-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 10px;
}

.difficulty-beginner {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: white;
}

.difficulty-intermediate {
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
  color: white;
}

.exercise-card p {
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.95rem;
  line-height: 1.5;
}

.exercise-card .duration {
  margin-top: 10px;
  font-weight: 600;
  color: #00FF88;
}

.selection-info {
  text-align: center;
  margin: 30px 0;
  padding: 20px;
  background: rgba(102, 126, 234, 0.1);
  border: 1px solid rgba(102, 126, 234, 0.3);
  border-radius: 10px;
}

.selection-info h3 {
  font-size: 1.3rem;
  color: #00FF88;
  margin-bottom: 5px;
}

.selection-info p {
  color: rgba(255, 255, 255, 0.8);
}

.action-buttons {
  display: flex;
  gap: 15px;
  justify-content: center;
  flex-wrap: wrap;
}

/* Patient View Styles */
.assigned-exercises-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-bottom: 30px;
}

.assigned-exercise-card {
  border: 2px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  padding: 25px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: all 0.3s ease;
}

.assigned-exercise-card:hover {
  border-color: #667eea;
  box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
  background: rgba(102, 126, 234, 0.1);
}

.exercise-info h3 {
  font-size: 1.5rem;
  color: #ffffff;
  margin-bottom: 8px;
}

.exercise-info p {
  color: rgba(255, 255, 255, 0.8);
  margin-bottom: 5px;
}

.
[truncated — 2589 more characters]
```

[33 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]