Skip to content

malik-builds/HealthLens

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HealthLens

Next.js FastAPI Docker scikit-learn

Repository: github.com/malik-builds/HealthLens

Tagline: See your risk clearly.

HealthLens is a portfolio full-stack app: a Next.js 15 frontend (green wellness UI, Three.js DNA-style hero) and a FastAPI backend that serves RandomForest-based diabetes risk estimates trained on the Pima Indians Diabetes dataset.

Medical disclaimer: For education and demonstration only. Not clinically validated. Not a diagnostic—always consult a licensed professional for medical decisions.

HealthLens screenshot placeholder


Table of contents

  1. Features
  2. Frontend architecture
  3. Repository layout
  4. Prerequisites
  5. Quick start (local, no Docker)
  6. Docker
  7. Environment variables
  8. API
  9. Model methodology
  10. Deploying live (optional)
  11. Troubleshooting
  12. License

Features

  • Landing (/) — Full-viewport hero with rotating dual-helix background, gradient CTA, animated stats strip.
  • Assessment (/predict) — Eight biomarkers with typed inputs and sliders (synced), short tooltips, expandable “What this feature means” copy, animated risk ring, and global feature-importance bars.
  • About (/about) — Dataset, model, and limitations.
  • Backend — On first start (if model.joblib is absent), trains a pipeline, saves it beside main.py, and logs out-of-fold F1 from stratified 5-fold CV.

Frontend architecture

The frontend is a Next.js 15 app (App Router, React 19) that gives users a clear, calm interface around the same eight biomarkers the backend model expects. It does not run ML in the browser: it collects inputs, POSTs them to the FastAPI /predict endpoint, and visualizes the JSON response (probability, label, and global feature importances). Styling is dark green / wellness themed—deep backgrounds, brand green accents, and readable contrast.

What it does (user journey)

  1. Home (/) — Full-height hero with headline, short value proposition, primary CTA Run assessment and secondary How it works, plus an animated stats strip (e.g. training set size, biomarker count). The background is a WebGL “DNA-style” double helix: two point-cloud helices in brand green and mint, slowly rotating, loaded client-only (no SSR for Three.js) so the first paint stays fast.
  2. Assessment (/predict) — A two-column layout: a form of eight biomarkers and a results panel. Users type values or use sliders (stayed in sync); each field has a Radix tooltip, allowed ranges, and an expandable “What this feature means” block with educational copy. Run assessment calls the API; while loading, a placeholder animates. On success, the app shows an SVG risk ring (animated percentage and LOW / MODERATE / HIGH label by threshold), a short outcome message (depends on the binary prediction and probability), a bar-style chart of the top 5 global feature importances from the response, and a disclaimer.
  3. About (/about) — Static cards on dataset, model, what the UI shows, and safety—aligned with the medical disclaimer on the home page.

Shell — A fixed navbar (logo, Home, Assessment, About) sits above all pages; the root layout sets page metadata, theme color, and loads DM Serif Display (headings), DM Sans (body), and JetBrains Mono (numbers).

Technical stack (frontend)

Area Details
Framework Next.js 15 App Router, output: "standalone" for Docker
Dev server next dev --turbopack
Styling Tailwind CSS v4 with @theme tokens in app/globals.css (colors, fonts); custom range and input classes for sliders
Motion Framer Motion (page transitions, risk ring, feature bars, stats strip)
3D @react-three/fiber, threeDNAHelix built with point buffers; HeroCanvas uses next/dynamic with ssr: false
UI primitives Radix Tooltip; class-variance-authority + Button; clsx / tailwind-merge via lib/utils
Icons lucide-react

API integration

lib/api.ts exports postPredict(): it POSTs JSON to `${NEXT_PUBLIC_API_URL}/predict` (default http://localhost:8000 if unset). The request body matches the API’s camelCase fields (pregnancies, glucose, bloodPressure, etc.). The response type includes risk_probability, prediction, and feature_importances. Network failures surface a single friendly error in the form.

Key files (mental map)

Path Role
app/layout.tsx Global fonts, Navbar, main padding for fixed header
app/page.tsx Landing: HeroCanvas, copy, links, StatsStrip
app/predict/page.tsx Renders PredictForm
app/about/page.tsx About copy
components/PredictForm.tsx Form state, biomarker rows, submit, results column
components/biomarkerFields.ts Labels, min/max, steps, tooltips, “about” text, defaults
components/RiskRing.tsx Circular progress, color bands by %
components/FeatureChart.tsx Top 5 importances as horizontal bars
components/DNAHelix.tsx / HeroCanvas.tsx 3D hero background

Repository layout

HealthLens/
├── backend/                 # FastAPI + sklearn
│   ├── main.py              # App, train/load pipeline, /predict, /health
│   ├── diabetes.csv         # Pima dataset (bundled)
│   ├── requirements.txt
│   ├── Dockerfile
│   └── .env.example         # CORS_ORIGINS template
├── frontend/                # Next.js 15 (App Router)
│   ├── app/                 # Routes: /, /predict, /about
│   ├── components/          # DNAHelix, PredictForm, RiskRing, etc.
│   ├── Dockerfile           # Multi-stage, output: standalone
│   └── .env.example         # NEXT_PUBLIC_API_URL
├── docker-compose.yml
└── README.md

Generated locally (gitignored): backend/model.joblib after the first successful training run.


Prerequisites

Tool Version (tested / expected)
Node.js 20.x (for frontend/)
Python 3.11+ (for backend/)
Docker Optional, for docker compose

Quick start (local, no Docker)

1. Clone the repository

git clone https://github.com/malik-builds/HealthLens.git
cd HealthLens

2. Start the API

cd backend
python3 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload --host 0.0.0.0 --port 8000

Leave this terminal open. First launch may take a minute while the model trains and writes model.joblib.

Sanity check: open http://127.0.0.1:8000/health — you should see {"status":"ok"}.

3. Start the web app

In a second terminal:

cd frontend
npm install
cp .env.example .env.local

Ensure .env.local contains (adjust if your API port differs):

NEXT_PUBLIC_API_URL=http://localhost:8000

Then:

npm run dev

Open http://localhost:3000. Go to Assessment, enter or slide biomarker values, then Run assessment.

4. Useful frontend commands

Command Purpose
npm run dev Dev server (Turbopack)
npm run build Production build
npm run start Serve production build
npm run lint ESLint

Docker

From the repository root (with Docker running):

docker compose up --build
Service URL
Frontend http://localhost:3000
Backend http://localhost:8000

The browser loads the frontend from your machine; it must call the API at a URL it can reach. Compose sets NEXT_PUBLIC_API_URL=http://localhost:8000 for the build of the frontend image so client-side fetch targets your published API port.


Environment variables

Backend (backend/.env optional; copy from backend/.env.example)

Variable Purpose
CORS_ORIGINS Comma-separated browser origins allowed to call the API. Default in code: http://localhost:3000. Add your production frontend URL when deploying.

python-dotenv loads .env from the backend working directory when present.

Frontend (frontend/.env.local; copy from frontend/.env.example)

Variable Purpose
NEXT_PUBLIC_API_URL Base URL of the FastAPI server as seen by the browser (no trailing slash), e.g. http://localhost:8000.

API

Base URL: same as NEXT_PUBLIC_API_URL (e.g. http://localhost:8000).

Method Path Description
GET /health { "status": "ok" }
POST /predict JSON body (camelCase) — see below

POST /predict body (example)

{
  "pregnancies": 1,
  "glucose": 120,
  "bloodPressure": 70,
  "skinThickness": 20,
  "insulin": 80,
  "bmi": 32,
  "diabetesPedigreeFunction": 0.5,
  "age": 45
}

Response (truncated)

{
  "risk_probability": 0.42,
  "prediction": 0,
  "feature_importances": { "Glucose": 0.25, "...": "..." }
}

Interactive docs: http://localhost:8000/docs (Swagger UI) when the backend is running.


Model methodology

  1. Data: backend/diabetes.csv — Pima Indians Diabetes Database (768 rows, 8 features + outcome).
  2. Missing values: zeros in Glucose, BloodPressure, SkinThickness, Insulin, and BMI are treated as missing and imputed with the median (SimpleImputer).
  3. Scaling: StandardScaler on all features.
  4. Classifier: RandomForestClassifier(n_estimators=100, random_state=42).
  5. Evaluation: StratifiedKFold(n_splits=5) with cross_val_predict and F1 on out-of-fold predictions, then a final fit on all rows.
  6. Artifact: model.joblib stores the fitted pipeline and global feature importances (not per-patient SHAP-style explanations).

Deploying live (optional)

If you later host the frontend and API separately (e.g. Vercel + Railway), set:

  • NEXT_PUBLIC_API_URL on the frontend to your public API HTTPS URL.
  • CORS_ORIGINS on the backend to your frontend origin(s), comma-separated.

See the Checklist in an earlier version of this doc or platform-specific guides; the same rules apply: browser must reach the API URL, and CORS must allow your site’s origin.


Troubleshooting

Issue What to try
Assessment shows a network error Confirm the backend is running and NEXT_PUBLIC_API_URL matches (including http vs https and port).
CORS error in the browser console Add your frontend origin to CORS_ORIGINS on the backend (comma-separated, no trailing slashes). Restart the API.
First API start is slow Training runs once until model.joblib exists; subsequent starts load the file.
model.joblib missing after clone Expected—train once by starting the backend; the file is gitignored.

Tech stack

Layer Technologies
Frontend Next.js 15 (App Router), Tailwind CSS v4 (@theme), Framer Motion, React Three Fiber, drei, Radix Tooltip
Backend FastAPI, uvicorn, pandas, scikit-learn, joblib, python-dotenv
Ops Docker, Docker Compose

License

MIT (or your choice) — adjust if you add a LICENSE file.

About

AI-powered diabetes risk assessment using clinical biomarkersclear, calm, and built for understanding (not replacing) your care team.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors