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_meanhr_range_max number 18 ML feature fields

Demo Flow

  1. Sign up for a new account
  2. Dashboard loads with Fitbit not connected
  3. Click "Connect Fitbit" — randomly assigns a Fitbit data profile
  4. Metrics populate: heart rate, sleep, steps
  5. Click "Run Risk Assessment" — model evaluates the data
  6. Risk result updates live: "At Risk" or "Not at Risk"
  7. Health recommendations appear based on result
  8. Click "What does this mean?" for a plain-language explanation
  9. Download a PDF report from My Reports or Profile tab

Notes

  • model.pkl is 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.pkl is available
  • In production, Fitbit OAuth would replace the simulated connect flow
Share this project:

Updates