FitSense — Hypertension Risk Prediction Platform
FitSense is a patient-facing web application that uses Fitbit wearable data and a machine learning model trained on the All of Us Research Program dataset to predict a patient's hypertension risk.
Project Pipeline
All of Us Dataset (BigQuery)
↓
ML Model Training (model.py)
↓
model.pkl (trained Random Forest)
↓
Flask API (app.py) — serves predictions
↓
Express Backend (server/) — authenticates, validates, orchestrates
↓
React Frontend (client/) — patient dashboard
↓
Firebase Firestore — stores patient data + results
Project Structure
├── client/ # React frontend (Vite)
│ ├── src/
│ │ ├── Auth.jsx # Login + signup page
│ │ ├── Auth.css
│ │ ├── firebase.js # Firebase config
│ │ ├── data/
│ │ │ └── fitbitProfiles.json # Demo Fitbit profiles (5 variants)
│ │ ├── components/
│ │ │ ├── PatientDashboard.jsx # Main patient dashboard
│ │ │ ├── PatientDashboard.css
│ │ │ ├── CompleteProfileModal.jsx
│ │ │ └── CompleteProfileModal.css
│ │ └── pages/
│ │ └── Auth.jsx # Route re-export
│ ├── .env # Frontend environment variables
│ └── package.json
│
├── server/ # Node.js + Express backend
│ ├── index.js # App entry point
│ ├── firebase.js # Firebase Admin SDK setup
│ ├── middleware/
│ │ └── auth.js # Firebase JWT verification
│ ├── routes/
│ │ └── patients.js # Patient API routes
│ ├── .env # Backend environment variables
│ └── package.json
│
├── ML/ # Machine learning service
│ ├── model.py # Training script (run on All of Us)
│ ├── app.py # Flask prediction API
│ ├── model.pkl # Trained model (not in git)
│ ├── requirements.txt # Python dependencies
│ └── venv/ # Python virtual environment (not in git)
│
└── README.md
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React with Vite |
| Backend | Node.js, Express |
| ML Model | Python, Flask, scikit-learn |
| Database | Firebase Firestore |
| Auth | Firebase Authentication |
| ML Training Data | All of Us Research Program |
Running the Project
Requires 3 terminals:
Terminal 1 — ML Service (requires model.pkl)
cd ML
source venv/bin/activate
python app.py
# Runs on http://localhost:5000
Terminal 2 — Backend
cd server
npm run dev
# Runs on http://localhost:3001
Terminal 3 — Frontend
cd client
npm run dev
# Runs on http://localhost:5173
Machine Learning Model
- Algorithm: Random Forest Classifier (balanced class weights)
- Training data: All of Us Research Program — Fitbit activity, sleep, and heart rate summaries
- Input: 18 engineered features aggregated from 60 days of Fitbit data per patient
- Output: Binary prediction —
"At Risk"or"Not at Risk"for hypertension
Feature List
| Category | Features |
|---|---|
| Activity | steps_mean, steps_std, steps_min, steps_max, sedentary_mean, sedentary_std, very_active_mean, very_active_max |
| Sleep | asleep_mean, asleep_std, deep_mean, deep_std |
| Heart Rate | min_hr_mean, min_hr_min, max_hr_mean, max_hr_max, hr_range_mean, hr_range_max |
Training the Model
model.py must be run inside the All of Us Researcher Workbench — it requires BigQuery access to the CDR dataset. Running it locally will fail. After training, export model.pkl and place it in the ML/ folder.
API Endpoints
All endpoints require a Firebase ID token in the Authorization: Bearer <token> header.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/patients/:id |
Fetch own patient record |
| PATCH | /api/patients/:id |
Update own patient record |
| POST | /api/patients/:id/score |
Run ML risk assessment |
Firestore Schema
Collection: patients — document ID = Firebase Auth UID
| Field | Type | Description |
|---|---|---|
name |
string | Patient name |
email |
string | Patient email |
age |
number | Age |
gender |
string | Gender |
raceEthnicity |
string | Race / ethnicity |
sexAssignedAtBirth |
string | Sex assigned at birth |
fitbitConnected |
boolean | Whether Fitbit is connected |
avgHeartRate |
number | Avg resting heart rate (bpm) |
avgSleepHours |
number | Avg sleep per night (hrs) |
avgDailySteps |
number | Avg daily step count |
hypertensionRisk |
string | "At Risk" / "Not at Risk" / unset |
lastScreening |
string | Last sync date (YYYY-MM-DD) |
createdAt |
timestamp | Account creation time |
steps_mean … hr_range_max |
number | 18 ML feature fields |
Demo Flow
- Sign up for a new account
- Dashboard loads with Fitbit not connected
- Click "Connect Fitbit" — randomly assigns a Fitbit data profile
- Metrics populate: heart rate, sleep, steps
- Click "Run Risk Assessment" — model evaluates the data
- Risk result updates live: "At Risk" or "Not at Risk"
- Health recommendations appear based on result
- Click "What does this mean?" for a plain-language explanation
- Download a PDF report from My Reports or Profile tab
Notes
model.pklis excluded from git (file size + All of Us data restrictions)venv/is excluded from git- The demo uses a mock ML response derived from patient metrics until
model.pklis available - In production, Fitbit OAuth would replace the simulated connect flow
Log in or sign up for Devpost to join the conversation.