Skip to content

Sathvik2954/Continuum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CONTINUUM

Offline-first healthcare continuity platform - patient ↔ doctor, anywhere.

Live: https://continuum-alpha-two.vercel.app

API: https://continuum-a8um.onrender.com


What it is

CONTINUUM is a healthcare continuity platform built for patients who see multiple doctors and lose the thread between appointments - and for doctors who spend the first ten minutes of every consultation asking questions that were already answered by someone else.

Patients maintain a single, portable health record: conditions, medications, consultations, lab reports, vitals. They share access with specific doctors. Doctors see the full picture before responding. Everything works offline and syncs when connectivity returns.


Features

For patients

  • Health timeline - every consultation, condition, medication, document, and vital in one chronological feed
  • Async consultations - record symptoms by voice, submit to a connected doctor, receive a response with structured medications and follow-up scheduling
  • Document upload - lab reports, scans, and prescriptions attached to your record, compressed client-side before upload
  • Vitals tracking - blood pressure, glucose, weight, heart rate with trend charts
  • Live calls - scheduled WebRTC video calls with doctors, call audio saved to your timeline automatically
  • Offline-first - everything above works without internet; data syncs automatically when back online

For doctors

  • Patient timeline view - full health history before responding to any consultation
  • Structured medications - prescribe with dosage, frequency, duration, and instructions; active medications surfaced in the patient's profile
  • Condition management - add chronic conditions with severity and status; only doctors can add conditions (not inferred from symptom checkboxes)
  • Follow-up scheduling - schedule follow-ups from any consultation response; overdue follow-ups surfaced on the dashboard
  • Doctor-initiated check-ins - reach out to chronic patients without waiting for them to submit a consultation
  • Analytics - patient count, avg response time, follow-up completion rate, top conditions, call stats; CSV export

For admins

  • Doctor verification - one-click approve/revoke verified status
  • User management - view all users, filter by role, soft-delete accounts
  • Storage monitoring - file count and total MB across uploads

Architecture

continuum/
β”œβ”€β”€ client/          React + Vite + TypeScript + Tailwind CSS
β”‚   β”œβ”€β”€ PWA          vite-plugin-pwa (offline shell, service worker)
β”‚   β”œβ”€β”€ Offline DB   Dexie.js (IndexedDB) - sync queue + timeline cache
β”‚   └── Real-time    Socket.io client + RTCPeerConnection (WebRTC)
β”‚
└── server/          Node.js + Express + TypeScript
    β”œβ”€β”€ Database     MongoDB Atlas (Mongoose ODM)
    β”œβ”€β”€ Auth         JWT (jsonwebtoken + bcryptjs)
    β”œβ”€β”€ Files        Multer - audio, images, call recordings
    β”œβ”€β”€ Real-time    Socket.io - WebRTC signaling server
    └── i18n         Client-side (i18next) - English, Hindi, Telugu

Offline sync flow

Patient (offline)
β”œβ”€β”€ Creates consultation ──► IndexedDB sync_queue (pending)
β”œβ”€β”€ Records audio ──────────► IndexedDB blobs store
└── Logs vitals ────────────► IndexedDB sync_queue (pending)

[connectivity returns]

Sync engine
β”œβ”€β”€ Upload blobs ──────────► Express β†’ /uploads/audio/
β”œβ”€β”€ POST records ──────────► Express β†’ MongoDB
β”œβ”€β”€ Mark synced ───────────► IndexedDB update
└── Pull fresh data ───────► Update IndexedDB cache

Conflict resolution: client sends updatedAt, server rejects stale writes with HTTP 409. User sees a non-blocking notification - no silent data loss.

WebRTC call flow

Patient                Signaling (Socket.io)          Doctor
β”œβ”€β”€ join_room ────────────────────────────────────────►│
│◄────────────────── peer_joined ──────────────────────
β”œβ”€β”€ sdp_offer (forwarded) ───────────────────────────►│
│◄────────────── sdp_answer (forwarded) ───────────────
│◄══════════════ P2P audio + video ═══════════════════►│
β”‚
[call ends]
β”œβ”€β”€ Patient's device stops MediaRecorder
β”œβ”€β”€ Uploads audio blob to server
└── Server creates LIVE_CALL consultation β†’ appears on timeline

Tech stack

Layer Technology
Frontend React 18, Vite, TypeScript, Tailwind CSS
Offline storage Dexie.js (IndexedDB wrapper)
PWA vite-plugin-pwa
Real-time Socket.io client, RTCPeerConnection
i18n i18next, react-i18next, i18next-browser-languagedetector
Backend Node.js, Express, TypeScript
Database MongoDB Atlas (Mongoose)
Auth JWT (jsonwebtoken), bcryptjs
File upload Multer
Signaling Socket.io (same Express server, same port)
TURN Xirsys (NAT traversal for WebRTC)
Frontend hosting Vercel
Backend hosting Render

Local setup

Prerequisites

  • Node.js 20+
  • npm
  • MongoDB Atlas account (free M0 cluster)
  • Git

1. Clone and install

git clone https://github.com/your-username/continuum.git
cd continuum

# Install server dependencies
cd server && npm install

# Install client dependencies
cd ../client && npm install

2. Configure the server

cd server
cp .env.example .env

Edit .env:

MONGODB_URI=mongodb+srv://<user>:<password>@cluster.mongodb.net/continuum
JWT_SECRET=<generate with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))">
PORT=3001
CLIENT_ORIGIN=http://localhost:5173

# Optional - TURN server for WebRTC NAT traversal
# Without these, calls work on the same network but may fail on mobile data
XIRSYS_IDENT=
XIRSYS_SECRET=
XIRSYS_CHANNEL=

3. Configure the client

Create client/.env:

VITE_API_ORIGIN=http://localhost:3001

4. Run

# Terminal 1 - server
cd server && npm run dev

# Terminal 2 - client
cd client && npm run dev

Client runs at http://localhost:5173, server at http://localhost:3001.


Creating an admin account

Admin accounts cannot be self-registered by design (prevents privilege escalation). To create one:

  1. Register normally as a patient
  2. Open MongoDB Atlas β†’ Collections β†’ users
  3. Find your document, change role: "PATIENT" to role: "ADMIN"
  4. Log out and log back in

Deployment

Render (backend)

Setting Value
Root directory server
Build command npm install && npm run build
Start command npm start
Environment Node

Add all .env variables in Render's Environment tab. CLIENT_ORIGIN must match your Vercel URL exactly, no trailing slash.

Note: Render's free tier sleeps after 15 minutes of inactivity. The first request after sleep takes ~30 seconds. WebRTC calls will fail if the signaling server is cold - upgrade to a paid instance before live use.

Vercel (frontend)

Setting Value
Root directory client
Framework preset Vite
Build command npm run build
Output directory dist

Add VITE_API_ORIGIN=https://continuum-a8um.onrender.com in Vercel's Environment Variables.

Note: Uploaded files (audio, documents, call recordings) are stored on Render's ephemeral filesystem and are lost on every redeploy. For production use, replace the local Multer storage with Cloudflare R2 or AWS S3.


Offline testing

  1. Open Chrome DevTools β†’ Network β†’ Offline
  2. Register as a patient, complete health profile, submit a consultation with audio
  3. Check Application β†’ IndexedDB β†’ continuum_db β†’ sync_queue - pending items should appear
  4. Set network back to Online
  5. The sync engine fires automatically on the online event
  6. Verify records in MongoDB Atlas β†’ Collections

Project structure

continuum/
β”œβ”€β”€ client/
β”‚   └── src/
β”‚       β”œβ”€β”€ components/
β”‚       β”‚   β”œβ”€β”€ consultation/    AudioRecorder, AudioPlayer, SymptomChecklist
β”‚       β”‚   β”œβ”€β”€ documents/       DocumentUploadButton
β”‚       β”‚   β”œβ”€β”€ followups/       FollowUpsList
β”‚       β”‚   β”œβ”€β”€ medication/      SpeakMedicationButton (TTS)
β”‚       β”‚   β”œβ”€β”€ sync/            SyncStatusWidget, SyncErrorPanel
β”‚       β”‚   β”œβ”€β”€ timeline/        TimelineEntryRow, HealthSummaryCard, AddConditionForm
β”‚       β”‚   β”œβ”€β”€ ui/              GlassCard, Avatar, StatusPill, Navbar, LanguageSwitcher
β”‚       β”‚   └── vitals/          VitalsLogForm, VitalsChart
β”‚       β”œβ”€β”€ lib/
β”‚       β”‚   β”œβ”€β”€ apiClient.ts     Axios + JWT injection
β”‚       β”‚   β”œβ”€β”€ authContext.tsx  Auth state
β”‚       β”‚   β”œβ”€β”€ callRecorder.ts  MediaRecorder for live calls
β”‚       β”‚   β”œβ”€β”€ compressImage.ts Canvas-based image compression
β”‚       β”‚   β”œβ”€β”€ i18n.ts          i18next setup
β”‚       β”‚   β”œβ”€β”€ offlineDB.ts     Dexie schema (v3)
β”‚       β”‚   β”œβ”€β”€ resolveFileUrl.ts Server-relative β†’ full URL
β”‚       β”‚   β”œβ”€β”€ socket.ts        Socket.io singleton
β”‚       β”‚   β”œβ”€β”€ syncEngine.ts    Offline queue + retry logic
β”‚       β”‚   β”œβ”€β”€ useAudioRecorder.ts MediaRecorder hook
β”‚       β”‚   β”œβ”€β”€ useTextToSpeech.ts  Web Speech API hook
β”‚       β”‚   └── webrtc.ts        RTCPeerConnection wrapper
β”‚       β”œβ”€β”€ locales/
β”‚       β”‚   β”œβ”€β”€ en/common.json
β”‚       β”‚   β”œβ”€β”€ hi/common.json
β”‚       β”‚   └── te/common.json
β”‚       └── pages/
β”‚           β”œβ”€β”€ admin/           AdminDashboard
β”‚           β”œβ”€β”€ auth/            LoginPage, RegisterPage
β”‚           β”œβ”€β”€ call/            ScheduleCallPage, CallRoomPage
β”‚           β”œβ”€β”€ doctor/          DoctorDashboard, ConsultationDetailPage, AnalyticsPage, MyPatientsSearchPage
β”‚           └── patient/         PatientDashboard, TimelinePage, OnboardingPage, NewConsultationPage,
β”‚                                ConsultationListPage, DoctorSearchPage, MyDoctorsPage, ProfilePage
β”‚
└── server/
    └── src/
        β”œβ”€β”€ lib/
        β”‚   β”œβ”€β”€ db.ts            MongoDB connection
        β”‚   └── expiryCron.ts    Auto-expires stale connection requests
        β”œβ”€β”€ middleware/
        β”‚   β”œβ”€β”€ auth.ts          JWT verification + role guard
        β”‚   β”œβ”€β”€ auditTrail.ts    Patient change logging
        β”‚   β”œβ”€β”€ patientAccess.ts assertPatientAccess() - core access control
        β”‚   β”œβ”€β”€ upload.ts        Multer - async audio
        β”‚   β”œβ”€β”€ uploadImage.ts   Multer - documents
        β”‚   └── uploadCallRecording.ts  Multer - call recordings
        β”œβ”€β”€ models/
        β”‚   β”œβ”€β”€ Call.ts
        β”‚   β”œβ”€β”€ Condition.ts
        β”‚   β”œβ”€β”€ Consultation.ts
        β”‚   β”œβ”€β”€ Document.ts
        β”‚   β”œβ”€β”€ DoctorProfile.ts
        β”‚   β”œβ”€β”€ FollowUp.ts
        β”‚   β”œβ”€β”€ Medication.ts
        β”‚   β”œβ”€β”€ PatientChange.ts
        β”‚   β”œβ”€β”€ PatientDoctorLink.ts
        β”‚   β”œβ”€β”€ PatientProfile.ts
        β”‚   β”œβ”€β”€ User.ts
        β”‚   └── Vital.ts
        β”œβ”€β”€ routes/
        β”‚   β”œβ”€β”€ admin.ts
        β”‚   β”œβ”€β”€ analytics.ts
        β”‚   β”œβ”€β”€ auth.ts
        β”‚   β”œβ”€β”€ calls.ts
        β”‚   β”œβ”€β”€ conditions.ts
        β”‚   β”œβ”€β”€ connections.ts
        β”‚   β”œβ”€β”€ consultations.ts
        β”‚   β”œβ”€β”€ documents.ts
        β”‚   β”œβ”€β”€ doctors.ts
        β”‚   β”œβ”€β”€ followups.ts
        β”‚   β”œβ”€β”€ patients.ts
        β”‚   β”œβ”€β”€ timeline.ts
        β”‚   └── vitals.ts
        β”œβ”€β”€ socket/
        β”‚   └── signaling.ts     Socket.io WebRTC signaling handlers
        └── index.ts             Express + Socket.io server bootstrap

Future scope

  • Persistent file storage - migrate audio, documents, and call recordings from local filesystem to Cloudflare R2 or AWS S3 for durability across deployments
  • Full i18n coverage - extend Hindi and Telugu translations across all pages and components (currently covers Navbar and Patient Dashboard)
  • SMS / WhatsApp notifications - notify patients of doctor responses and upcoming follow-ups via Twilio when the app is not open
  • Family health management - allow a single account to manage health records for dependents (children, elderly parents)
  • Diagnostic center integration - allow labs and imaging centers to upload reports directly to a patient's record without going through the patient manually
  • Medication reminders - push notifications or SMS reminders when a medication dose is due, based on prescribed frequency
  • Doctor availability calendar - let doctors set available slots for live calls so patients can self-schedule without back-and-forth
  • Population health analytics - village-level or region-level disease trend dashboards for public health administrators, built on anonymised aggregated data
  • AI-assisted symptom triage - surface relevant past consultations and conditions when a patient submits symptoms, helping doctors respond faster
  • Multi-language voice input - extend audio symptom recording with speech-to-text transcription in Hindi and Telugu so doctors can read symptoms without listening to full recordings

License

MIT

About

Secure, offline-first healthcare continuity platform with asynchronous consultations, local database caching, automatic background sync, WebRTC video calling, and multi-language support (English, Hindi, Telugu).

Topics

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages