AI-assisted neuroimaging analysis platform. Clinicians and hospitals upload MRI/CT/DICOM studies and receive structured, radiologist-ready reports in seconds.
https://neuroscan-ai-872.netlify.app
demo@neuroscan.ai |
|
| Password | sanjay123 |
Auth, dashboard, upload, real AI analysis, reports, history, and billing UI are all live against a real Supabase project. The demo account is on the Free plan (10 scans/day). Stripe is in test mode, so checkout won't process a real charge.
NeuroScan.ai is a Next.js 16 (App Router) application backed by Supabase (Postgres, Auth, Storage) and Stripe for billing, with a real trained image-classification model for scan analysis (not a mock).
Core features:
- Email/password + Google OAuth authentication
- Drag-and-drop scan upload (MRI/CT/DICOM/ZIP), direct-to-storage via signed URLs
- Real AI analysis: an in-house trained image classifier flags scans suspicious for a mass lesion, feeding risk level, urgency, and recommendations
- Structured, PDF-exportable reports, scan history, and patient records
- Subscription billing (Free / Clinician / Hospital plans) via Stripe Checkout + webhooks
- Admin panel for platform-wide user, scan, and subscription oversight
- Fully responsive (mobile/tablet/desktop), dark mode
Frontend
- Next.js 16 (App Router, Server Actions, Turbopack)
- React 19 + TypeScript
- Tailwind CSS v4 (CSS-first config, no
tailwind.config.js) - shadcn/ui + react-aria-components for accessible primitives
- Framer Motion for scroll-reveals, staggered animation, and the landing page
- Recharts for admin analytics
- react-hook-form + Zod for form validation
- @react-pdf/renderer for generated report PDFs
Backend / Data
- Supabase: Postgres, Auth (email/password + Google OAuth), Storage (private, signed-URL scan uploads), Row-Level Security on every table
- Stripe: Checkout + webhooks for subscription billing
- Next.js Server Actions for all mutations — no separate REST/GraphQL API layer
AI / ML
- PyTorch — MobileNetV2 transfer learning, trained on the Kaggle
mhantor/mri-based-brain-tumor-imagesdataset - Exported to ONNX, int8-quantized (~2.4MB)
- onnxruntime-node — runs inference in-process inside the same Next.js server action that handles the scan pipeline (no separate model-serving infrastructure)
- sharp for server-side image preprocessing (resize/normalize to match training)
- Training scripts live in
ml/(train.py,export.py,verify_onnx.py) for reproducibility
Deployment
- Netlify (
@netlify/plugin-nextjs) — current live deployment - Vercel — also supported, same build config
- GitHub for source control
Unlike a typical demo/prototype, the AI step is a genuinely trained model, not hardcoded or randomized output:
- On upload, the file goes straight from the browser to a private Supabase Storage bucket via a signed URL (the Next.js server never touches the raw bytes at this stage).
- A Server Action (
src/lib/analysis/actions.ts) downloads the file from Storage and, for image uploads (JPEG/PNG), runs it through the ONNX model (src/lib/ai/real-classifier.ts): resize/normalize withsharp→ classify withonnxruntime-node→ map the prediction + confidence to a risk level, findings, urgency, and recommendations. - DICOM uploads (no decodable pixel data in the training set) and any inference failure fall back to a clearly-labeled simulated analyzer, so the pipeline never hard-fails.
- Results are persisted to
scan_recordsand rendered into a PDF report.
Validation accuracy: 100% (fp32) / 97.5% (after int8 quantization) on a held-out split of the training dataset — a small (400-image), binary (Normal/Tumor) dataset, so treat this as a real working pipeline, not a clinically-validated diagnostic tool.
NeuroScan-AI/
├── frontend/ # Next.js app (deploy this directory)
│ ├── src/
│ │ ├── app/ # Routes (App Router)
│ │ ├── components/ # UI components, organized by feature
│ │ ├── lib/ # Server Actions, Supabase/Stripe/AI clients
│ │ │ └── ai/ # Real classifier + bundled ONNX model
│ │ └── services/ # Simulated analyzer (DICOM/fallback path)
├── ml/ # Model training: train.py, export.py, verify_onnx.py
├── supabase/ # Supabase CLI project: migrations, config
├── netlify.toml # Netlify build config (base: frontend)
└── prompts/ # Historical build-phase specs (not used at runtime)
cd frontend
npm installCopy the example file and fill in real values:
cd frontend
cp .env.example .env.local| Variable | Required | Purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Yes | Supabase project URL (client + server) |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Yes | Supabase anon/public key (client + server) |
SUPABASE_SERVICE_ROLE_KEY |
Yes | Server-only. Used by the Stripe webhook route to write subscription/invoice rows, bypassing RLS by design. Never expose to the client. |
NEXT_PUBLIC_APP_URL |
Yes | Fallback origin for building absolute URLs (e.g. Stripe redirect URLs) when no request Origin header is present. Set to your deployed domain in production. |
NEXT_PUBLIC_APP_NAME |
Yes | Public app name constant, reserved for display use. |
STRIPE_SECRET_KEY |
For billing | Server-only Stripe API key. Billing actions degrade to a handled error toast (not a crash) if unset. |
STRIPE_WEBHOOK_SECRET |
For billing | Verifies incoming Stripe webhook signatures. |
STRIPE_CLINICIAN_MONTHLY_PRICE_ID / STRIPE_CLINICIAN_YEARLY_PRICE_ID |
For billing | Stripe Price IDs for the Clinician plan checkout. |
No AI-related env vars are needed — the ONNX model ships as a bundled file (src/lib/ai/model/), not a remote API.
Never commit .env.local — it's gitignored. Only .env.example (with placeholder values) is tracked.
cd frontend
npm run devRuns on http://localhost:3000 (bound to 0.0.0.0, so it's also reachable from other devices on the same network via your machine's LAN IP).
cd frontend
npm run build
npm run startConfig lives in the root netlify.toml:
- Base directory:
frontend - Build command:
npm run build - Publish directory:
frontend/.next - Plugin:
@netlify/plugin-nextjs
The ONNX model's native runtime (
onnxruntime-node) ships prebuilt binaries for every platform (~261MB total) with no per-platform npm split.next.config.tsusesoutputFileTracingIncludes/scoping to bundle only thelinux/x64binary actually needed at runtime — without it, the serverless function exceeds Netlify's 250MB limit.
- Root Directory:
frontend - Framework Preset: Next.js
- Build Command:
npm run build - Install Command:
npm install - Output Directory:
.next
Set all variables from Environment Variables in your platform's project settings before the first deploy.
- Create a project at supabase.com.
- Apply the schema:
supabase link --project-ref <ref>thensupabase db push(migrations live insupabase/migrations/). - Copy the Project URL and anon/service-role keys into your environment variables (see table above).
- Under Authentication → URL Configuration, set the Site URL and add Redirect URLs for both your production domain and
localhost. - Enable the Google provider under Authentication → Providers if using Google sign-in.
cd ml
pip install kagglehub torch torchvision pillow scikit-learn onnx onnxruntime
python3 train.py # trains best_model.pt
python3 export.py # exports + quantizes to brain-tumor-classifier.onnx
python3 verify_onnx.py # sanity-checks accuracy post-quantizationThen copy the output into frontend/src/lib/ai/model/ (brain-tumor-classifier.onnx + labels.json) and redeploy.