Production-style telemedicine platform built with Next.js, Express compatibility APIs, Prisma, Supabase Postgres/Auth/Realtime, Azure Blob Storage, and a React SPA.
This repository contains:
- Role-based telemedicine workflows for patients, doctors, help workers, and admins
- Real-time consultation support (video/audio/text signaling, chat, and shared call-end events)
- Prescription, pharmacy, lab, reminders, and document workflows
- AI-assisted draft tooling with review-required policy
- Azure-ready deployment flow and Capacitor mobile wrapper scaffolding
The system is designed for mixed-connectivity and rural-first usage patterns:
- Patient booking and consultation lifecycle
- Doctor slot and analytics management
- Delegated care support through explicit consent
- Document and prescription handoff via secure access controls
- Operations visibility with impact and readiness metrics
- Runtime: Next.js with Express compatibility APIs
- Database: Supabase Postgres via Prisma ORM
- Frontend: React + React Router inside a Next client boundary
- Realtime: Supabase Realtime for consultation signaling and chat
- Storage: Azure Blob Storage (with configurable local fallback)
- Auth: Supabase Auth cookies plus app-local role/profile rows
- Security: Helmet, rate limiting, role authorization
- Testing: Jest, Supertest, and Playwright E2E
.
|- app.js
|- apps/
| |- backend/
| | |- controllers/
| | |- middleware/
| | |- models/
| | |- routes/
| | |- server/
| | |- services/
| |- frontend/
| |- src/
|- docs/
|- prisma/
|- scripts/
|- tests/
|- azure-deploy.md
|- design.md
|- docs/PRD.md
|- docs/production-readiness.md
|- docs/CAPACITOR.md
- Node.js 20+
- PostgreSQL 14+
- npm 10+
- Optional: Docker (for local postgres container)
run-app.batcopy .env.example .env
docker compose up -d
npm install
npm run db:migrate
npm run db:seed
npm run devApp URLs:
- API + SPA server: http://localhost:3000
- Frontend-only dev server (optional): http://localhost:5173 via
npm run frontend:dev
Reference file: .env.example
PORTNODE_ENVDATABASE_URLPRISMA_CONNECTION_LIMIT(recommended1on Vercel/serverless with Supabase Session Pooler)JWT_SECRETJWT_EXPIRES_IN
APP_BASE_URL(comma-separated allowed web origins)ALLOW_NO_ORIGIN_SOCKET(defaultfalse)
AZURE_STORAGE_CONNECTION_STRINGAZURE_STORAGE_ACCOUNT_NAMEandAZURE_STORAGE_ACCOUNT_KEYas an alternative to a full connection stringAZURE_STORAGE_CONTAINER(defaultpatient-documents)AZURE_STORAGE_PUBLIC_BASE_URLAZURE_UPLOADS_MODE(azure-only,local-only, etc.)
OLLAMA_BASE_URLOLLAMA_MODEL(defaultllama3.1:8b)OLLAMA_TIMEOUT_MS(default45000)OPENROUTER_API_KEYOPENROUTER_MODEL(defaultopenai/gpt-oss-120b:free)OPENROUTER_TIMEOUT_MS(default45000)AI_RATE_LIMIT_PER_MINUTE(default40)
APPLICATIONINSIGHTS_CONNECTION_STRING(optional)SUPABASE_AUTH_CACHE_TTL_MS,APP_USER_CACHE_TTL_MS,DOCTOR_TRUST_CACHE_TTL_MSfor short-lived performance cachesENABLE_REMINDER_CRON(trueto auto-dispatch)REMINDER_CRON_INTERVAL_MSREMINDER_CRON_BATCH_LIMITLOG_LEVEL
ADMIN_INVITE_CODE(optional)
After npm run db:seed:
- Patient:
[email protected]/Demo@12345 - Patient:
[email protected]/Demo@12345 - Doctor:
[email protected]/Demo@12345 - Doctor:
[email protected]/Demo@12345 - Admin:
[email protected]/Demo@12345 - Help worker:
[email protected]/Demo@12345
| Script | Purpose |
|---|---|
npm run dev |
Start backend app with nodemon |
npm start |
Production startup (prestart + server) |
npm run start:azure |
Explicit Azure startup script |
npm run frontend:dev |
Legacy Vite dev server for the frontend package |
npm run frontend:build |
Build frontend bundle |
npm run frontend:preview |
Preview built frontend |
npm run prisma:generate |
Generate Prisma client |
npm run db:migrate |
Prisma dev migration |
npm run db:deploy |
Prisma deploy migration |
npm run db:seed |
Seed baseline users and data |
npm run test |
Jest suite |
npm run ci |
Lint + test + prisma generate + frontend build |
npm run mobile:build |
Build web bundle for Capacitor |
npm run mobile:sync |
Build and sync Capacitor assets |
npm run mobile:add:android |
Add Android platform |
npm run mobile:add:ios |
Add iOS platform |
npm run mobile:open:android |
Open Android Studio project |
Core startup path:
app.jsinitializes env, telemetry, optional reminder cron, and server lifecycleapps/backend/server/create-app.jswires middleware, APIs, static assets, and SPA fallbackapps/backend/server/create-server.jswraps the compatibility HTTP server for local/custom-server runs
Key middleware:
- Request context and request ID
- API mode adaptation for JSON clients
- Auth session attachment
- Role authorization
- Structured error handling
Both prefixes are active:
/api/*/api/v1/*
Health and session:
GET /health/liveGET /health/readyGET /session
Domain route groups:
/auth/users/doctors/patients/appointments/calls/prescriptions/documents/pharmacy/labs/reminders/support/ai/innovations/medicines
OpenAPI baseline is maintained in docs/openapi.yaml.
Public routes:
//auth/login/auth/register/privacy-policy/terms-of-service/help-center
Authenticated routes:
/dashboard/book/appointments/appointments/impact/appointments/:appointmentId/calls/:appointmentId/prescriptions/:appointmentId/doctors/doctors/:doctorId/doctors/me/slots(doctor)/doctors/me/analytics(doctor)/profile/users/me/patients/workspace(patient)/patients/me/medicines(patient)/pharmacy/orders/labs/tests/reminders/ai-copilot/doctor/patient-access(doctor/admin)/innovations/support/consents(patient/help_worker)/pdf-preview
- Booking flow with doctor, slot, mode, and family context
- Appointment detail and lifecycle actions
- Presence and call readiness helpers
- No-show follow-up action flow
- Doctor prescription creation and update
- PDF generation and preview
- Handoff code support
- Patient medicine cabinet and medicine search
- Pharmacy order timeline and status updates
- Lab catalog, orders, status progression, and report attach
- PDF preview integration for reports and prescriptions
- Context endpoint and role-aware draft tools
- Draft note, reminder text, referral summary, async reply support
- Translation and helper guidance endpoints
- Review-required metadata policy for outputs
- Vitals and trends
- Care plans and check-ins
- Emergency escalation workflow
- External consult threads/messages
- Second-opinion request and audit trail
- Patient QR token sharing and doctor/admin access-by-token
- Consent and helper delegation controls
Primary models include:
- Identity and roles:
User,PatientProfile,DoctorProfile - Visits and consults:
Slot,Appointment,CallSession,DoctorReview - Clinical records:
Document,Prescription,ConsultationVital,Referral - Orders and tests:
PharmacyOrder,LabTestCatalog,LabOrder,LabOrderItem - Care coordination:
ReminderJob,CareSupportLink,ConsentAudit,PatientAccessToken - Extended innovation set: care plans, emergencies, external consult threads, voice notes, second opinions
Schema source of truth: prisma/schema.prisma
- Helmet CSP enabled
- Global rate limiting enabled
- Auth via secure cookie JWT
- Role-gated endpoints and ACL checks
- Structured request IDs in response headers
- Readiness and liveness probes for orchestration
Run tests:
npm testCurrent automated coverage includes:
- Session endpoint behavior
- Versioned API parity checks (
/apivs/api/v1) - Health endpoints
- SPA fallback rendering
- Unauthorized access baseline checks
Extra QA reports and checklist outputs are available in qa-reports/.
- API reference (route matrix):
docs/API.md - Azure deployment guide:
azure-deploy.md - Production readiness gates:
docs/production-readiness.md - Product requirements:
docs/PRD.md - UX and interaction design spec:
design.md - Capacitor wrapper workflow:
docs/CAPACITOR.md
Capacitor configuration is included in capacitor.config.ts.
Use:
npm run mobile:sync
npm run mobile:add:android
npm run mobile:open:androidCurrent scope is wrapper readiness for the web app bundle (not native feature parity).
- Run
npm run frontend:build - Restart server with
npm run dev
- Ensure PostgreSQL is reachable from
DATABASE_URL - Run
npm run db:deploy(ornpm run db:migratelocally)
- Run
npm run prisma:generate
- Verify
APP_BASE_URLis set to correct HTTPS origins - Confirm
NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEYare available to the browser - Confirm Supabase Realtime is reachable from the deployed app
- If
OPENROUTER_API_KEYandOLLAMA_BASE_URLare unset/unreachable, AI endpoints use fallback-safe behavior - Check API response metadata for fallback indicators