Healthcare Assistance & Doctor Consultation Web Platform
Built with Node.js (Express 5), MongoDB, Google Gemini, Groq (LLaMA 3.3), and EJS.
Caution
DocOnCall is an educational prototype and demonstration application, NOT a certified medical device or a substitute for professional clinical advice, diagnosis, or treatment.
- All symptom assessments, report summaries, and drug insights are generated by general-purpose Large Language Models (LLMs) and may produce inaccurate medical information or hallucinations.
- Do not enter real personal, identifiable, or sensitive medical information into this public demonstration prototype.
- Never disregard or delay seeking professional medical advice because of information provided by this application.
- In case of a medical emergency, immediately contact your local emergency services (e.g., 911 / 112) or visit the nearest emergency department.
Note
Hosting Notice: The live demo runs on Render's free tier. If the instance has spun down due to inactivity, the initial page load may take 50โ60 seconds to wake the container.
- Overview
- System Architecture & Graphs
- Core Features
- Technology Stack
- API Reference
- Repository Structure
- Getting Started & Installation
- Visual Showcase
- Known Limitations & Architecture Trade-offs
- Future Roadmap
- Contributors & Context
DocOnCall is a full-stack digital health prototype created during HackSprint 2025 by Gyan Ranjan and Team DevStormers, maintained under DevAI. The platform pairs client-facing AI health tools with a consultation appointment pipeline connecting patients to doctor profiles.
To prevent single-provider service disruptions caused by API rate limits, the backend implements an automated rate-limit cooldown and model fallback mechanism across two distinct providers: Google Gemini (gemini-2.5-flash โ gemini-2.5-flash-lite) and Groq Cloud (llama-3.3-70b-versatile).
The platform comprises an EJS server-rendered UI, an Express.js application tier managing sessions and AI request routing, a MongoDB persistence tier, and external generative AI services:
graph TB
subgraph ClientLayer ["Client Layer (Browser)"]
UI_User["Patient Portal\n(EJS / CSS3 / Vanilla JS)"]
UI_Doc["Doctor Portal & Dashboard\n(EJS / CSS3 / Vanilla JS)"]
UI_Admin["Super Admin Console\n(EJS / CSS3 / Vanilla JS)"]
end
subgraph AppLayer ["Application Tier (Node.js & Express 5.1.0)"]
Router["Express Router & Session Guard\n(express-session)"]
Security["Security Layer\n(bcrypt / express-rate-limit / trust proxy)"]
TriageEngine["Keyword Specialty Matcher\n(Rule-based Substring Classifier)"]
AIEngine["AI Fallback Engine\n(generateWithFallback & chatWithFallback)"]
Telemetry["In-Memory Stats Tracker\n(modelStats Map)"]
end
subgraph DBLayer ["Database Tier (MongoDB via Mongoose 8.19.2)"]
UserCol[("Users Collection\n- Vitals, Profiles, bcrypt Hashes")]
DocCol[("Doctors Collection\n- Profiles, Approval, Appointments")]
end
subgraph AILayer ["External AI Providers"]
GeminiPrimary["Google Gemini 2.5 Flash\n(Primary Multimodal)"]
GeminiSecondary["Google Gemini 2.5 Flash-Lite\n(Secondary Fallback)"]
GroqTertiary["Groq Cloud - LLaMA 3.3 70B\n(Text-Only Tertiary Fallback)"]
end
UI_User -->|HTTP Requests| Router
UI_Doc -->|HTTP Requests| Router
UI_Admin -->|HTTP Requests| Router
Router --> Security
Router --> TriageEngine
Router --> AIEngine
Router --> Telemetry
Router -->|Mongoose ODM| UserCol
Router -->|Mongoose ODM| DocCol
AIEngine -->|Priority 1| GeminiPrimary
AIEngine -.->|Priority 2 Fallback| GeminiSecondary
AIEngine -.->|Priority 3 Fallback| GroqTertiary
When an AI endpoint is called, the engine attempts models sequentially according to priority. If an API returns a rate limit or quota exhaustion error (429, RESOURCE_EXHAUSTED, or quota messages), a 60-second cooldown timestamp is attached to that model, and the request immediately advances to the next provider.
flowchart TD
Start(["Incoming AI Request"]) --> CheckP1{"Is Gemini 2.5 Flash Available?"}
CheckP1 -- "Yes (Cooldown clear)" --> TryP1["Dispatch to Google Gemini 2.5 Flash"]
CheckP1 -- "Rate-limited (< 60s cooldown)" --> CheckP2
TryP1 --> RespP1{"Success?"}
RespP1 -- "Yes" --> ReturnSuccess(["Format & Return Response to Client"])
RespP1 -- "No (Quota / Rate Limit)" --> FlagP1["Mark Gemini Flash Cooldown (60s)"]
FlagP1 --> CheckP2{"Is Gemini 2.5 Flash-Lite Available?"}
CheckP2 -- "Yes (Cooldown clear)" --> TryP2["Dispatch to Google Gemini 2.5 Flash-Lite"]
CheckP2 -- "Rate-limited (< 60s cooldown)" --> CheckP3
RespP2{"Success?"}
TryP2 --> RespP2
RespP2 -- "Yes" --> ReturnSuccess
RespP2 -- "No (Quota / Rate Limit)" --> FlagP2["Mark Gemini Flash-Lite Cooldown (60s)"]
FlagP2 --> CheckP3{"Is Request Text-Only?"}
CheckP3 -- "Yes" --> TryGroq["Dispatch to Groq LLaMA 3.3 70B Versatile"]
CheckP3 -- "No (Prescription Image)" --> ErrorVision["Image input unsupported by Groq (Abort)"]
TryGroq --> RespGroq{"Success?"}
RespGroq -- "Yes" --> ReturnSuccess
RespGroq -- "No" --> AllFailed["Throw 503 Service Unavailable"]
ErrorVision --> AllFailed
sequenceDiagram
autonumber
actor Doctor as Doctor
actor Admin as Super Admin
actor Patient as Patient
participant System as Express Backend
participant DB as MongoDB
Note over Doctor,System: 1. Registration & Verification Request
Doctor->>System: Register profile (Degrees, College, Experience, Timings)
System->>DB: Save Doctor (isVerified: false, verificationRequested: false)
Doctor->>System: Submit verification request (/api/doctor/request-verification)
System->>DB: Update Doctor (verificationRequested: true)
Note over Admin,System: 2. Admin Authentication & Approval
Admin->>System: Navigate to /superadmin/login
Admin->>System: Submit ADMIN_PASSWORD (Rate-limited, timingSafeEqual)
System-->>Admin: Authenticated Session (req.session.isAdmin = true)
Admin->>System: Access /superadmin (Lists pending requests & full roster)
Admin->>System: Approve doctor (/api/superadmin/verify/:id)
System->>DB: Update Doctor (isVerified: true, verificationRequested: false)
Note over Patient,Doctor: 3. Symptom Triage & Appointment Booking
Patient->>System: Submit symptoms & complaint (/consult/book)
System->>System: Substring keyword scan (e.g., 'chest' -> Cardiology)
System-->>Patient: Recommend matching doctors
Patient->>System: Select doctor & submit appointment date/time (/api/consult/book)
System->>DB: Append appointment to Doctor's appointments array (status: 'Pending')
Note over Doctor,Patient: 4. Consultation Management
Doctor->>System: Access /doctor/dashboard
System->>DB: Fetch assigned appointments
Doctor->>System: Review patient details and complaints
Doctor->>System: Update status (Pending / Completed / Cancelled)
-
Dr. AI Virtual Assistant (
/chatbot,POST /api/chat)- Conversational health assistant providing preliminary medical guidance.
- Session tracking handled via an in-memory
Map. Every response reinforces that guidance does not replace a clinical consultation.
-
Symptom Assessment (
/symptom-analysis,POST /api/analyze-symptoms)- Ingests patient symptoms, age, gender, and duration.
- Outputs suspected conditions, model-generated likelihood estimates (High/Medium/Low, uncalibrated LLM outputs), urgency categorization, and general self-care notes.
-
Medical Report Summarizer (
/report-summary,POST /api/summarize-report)- Parses clinical report text and outputs patient-oriented summaries, explaining abnormal values and suggesting questions to ask a doctor.
-
Prescription Image Analysis (
POST /api/read-prescription)- Multimodal Gemini Vision endpoint parsing Base64 prescription photographs.
- Extracts readable medicine names, dosages, administration frequencies, and special warnings.
-
Medicine Directory (
/medicine-info,POST /api/medicine-info)- Reference for common medications: therapeutic indications, mechanism, typical side effects, and precautions.
-
Health Tips Generator (
/health-tips,POST /api/health-tips)- Generates 5 practical wellness and lifestyle tips tailored by selected wellness category and demographic profile.
-
Personalized Diet Planner (
/diet-plan,POST /api/diet-plan)- Produces a 1-day sample meal structure with caloric estimates and hydration tips tailored to dietary preferences.
- Doctor Onboarding: Collects profile data (specialization, degrees, medical college, years of experience, city/state, phone, consultation hours) with bcrypt salted password hashes.
- Verification Workflow: Doctors submit their profile for administrator review with a single click from their dashboard.
- Appointment Queue: Overview of scheduled patient consultations displaying patient vitals, reported symptoms, and booking date/time.
- Consultation Status: Update patient appointments across
Pending,Completed, andCancelledstates.
- Gated Console (
/superadmin): Accessible via a dedicated admin login portal (/superadmin/login) requiring master passphrase authentication (ADMIN_PASSWORD), protected byexpress-rate-limit(5 attempts per 15 minutes) andcrypto.timingSafeEqual. - Approval Actions (
POST /api/superadmin/verify/:id,POST /api/superadmin/reject/:id): Allows an administrator to approve (isVerified: true) or reject pending doctor applications. (Note: This is an administrative approval flag, not an automated medical license registry check.)
- Profile & Vitals (
/about): Stores physical metrics (height, weight, age, biological gender, blood group, address, and critical medical history notes). - Rule-Based Specialty Triage (
/consult/book): Substring keyword matching on patient symptom input to categorize cases into specialties (Cardiology,Dermatology,Neurology,Orthopedics,Pediatrics,General Medicine,Gynecology,Psychiatry).
| Layer | Package / Technology | Exact Version (Installed) | Role |
|---|---|---|---|
| Runtime | Node.js | >= 22.0.0 (LTS) |
Asynchronous JavaScript runtime environment |
| Framework | express | 5.1.0 |
HTTP routing, JSON middleware, and route dispatching |
| Template Engine | ejs-mate | 4.0.0 |
Server-rendered HTML templates with shared layouts and partials |
| Database ODM | mongoose | 8.19.2 |
Schemas for Users, Doctors, and embedded Appointment subdocuments |
| Password Hashing | bcrypt | 6.0.0 |
Salted password hashing (12 rounds) with auto-rehash legacy upgrade |
| Rate Limiting | express-rate-limit | 8.7.1 |
Brute-force throttling on admin login and AI endpoints |
| Session Store | express-session | 1.18.2 |
Cookie-based session state (httpOnly, sameSite: 'lax', secure in production) |
| Primary AI SDK | @google/generative-ai | 0.24.1 |
Multimodal Gemini 2.5 Flash and Gemini 2.5 Flash-Lite |
| Fallback AI SDK | groq-sdk | 0.37.0 |
High-speed LLaMA 3.3 70B Versatile for text-only requests |
| CORS Middleware | cors | 2.8.5 |
Cross-Origin Resource Sharing middleware |
| Method Override | method-override | 3.0.0 |
RESTful HTTP PUT and DELETE verbs for forms |
| Environment | dotenv | 17.2.3 |
Loads local environment variables from .env |
| Method | Endpoint | Auth Required | Rate Limited | Description |
|---|---|---|---|---|
POST |
/api/chat |
Yes (User) | 25 req/min | Chat message dispatch to Dr. AI assistant |
POST |
/api/analyze-symptoms |
Yes (User) | 25 req/min | Generates structured symptom analysis and triage |
POST |
/api/summarize-report |
Yes (User) | 25 req/min | Summarizes clinical lab reports in plain language |
POST |
/api/read-prescription |
Yes (User) | 25 req/min | Multimodal OCR parsing of prescription photos (Gemini only) |
POST |
/api/medicine-info |
Yes (User) | 25 req/min | Drug information, side effects, and precautions |
POST |
/api/health-tips |
Yes (User) | 25 req/min | Category-based health and lifestyle advice |
POST |
/api/diet-plan |
Yes (User) | 25 req/min | 1-day personalized meal and hydration schedule |
POST |
/api/clear-chat |
Yes (User) | No | Clears an active chat session from memory |
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
POST |
/doctor/login |
No | Authenticates doctor credentials using bcrypt (auto-rehashes legacy records) |
POST |
/doctor/signup |
No | Registers new doctor profile with bcrypt salted password hash |
PUT |
/api/doctor/profile |
Doctor | Updates doctor bio, credentials, and office timings |
POST |
/api/doctor/request-verification |
Doctor | Flags profile as awaiting admin approval (verificationRequested: true) |
POST |
/api/consult/book |
User | Submits appointment booking with selected doctor |
GET |
/superadmin/login |
No | Admin login page |
POST |
/superadmin/login |
No (5 attempts / 15 min) | Authenticates master admin session via ADMIN_PASSWORD (timing-safe check) |
GET |
/superadmin/logout |
Admin | Clears admin session |
GET |
/superadmin |
Admin | Dashboard showing pending verification requests and all registered doctors |
POST |
/api/superadmin/verify/:id |
Admin | Sets doctor isVerified flag to true |
POST |
/api/superadmin/reject/:id |
Admin | Resets doctor verification request |
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
GET |
/api/health |
No | Returns system status (sanitized to basic status in production) |
GET |
/api/model-stats |
Yes (User) | Per-model attempt counts, failures, and cooldown status |
GET |
/api/test |
Admin in prod | Internal diagnostic catalog (disabled for public callers in production) |
DocOnCall/
โโโ assets/ # Application screenshots and demo media
โ โโโ ai_chatbot.png # AI Chatbot interface
โ โโโ ai_features.png # AI features directory
โ โโโ auth.png # User login / signup modal
โ โโโ landing.png # Landing page
โ โโโ patient_dashboard.png # Patient portal overview dashboard
โ โโโ report_summary.png # Medical report summary tool
โโโ models/ # Mongoose ODM schemas
โ โโโ doctor.js # Doctor profile, approval flag & appointment subdocuments
โ โโโ user.js # User profile, physical vitals & hashed credentials
โโโ views/ # Dynamic EJS views
โ โโโ partials/ # Shared layouts, modals, and headers
โ โ โโโ footer.ejs
โ โ โโโ header.ejs
โ โ โโโ login-modal.ejs
โ โ โโโ navbar.ejs
โ โ โโโ signup-modal.ejs
โ โโโ about.ejs # Patient vitals and medical profile form
โ โโโ chatbot.ejs # Chat interface with Dr. AI
โ โโโ consult.ejs # Doctor directory & symptom triage form
โ โโโ consult-book.ejs # Specialist recommendation and booking confirmation
โ โโโ diet-plan.ejs # AI nutrition planner interface
โ โโโ doctor-dashboard.ejs # Doctor appointment queue and profile manager
โ โโโ doctor-login.ejs # Doctor login interface
โ โโโ doctor-signup.ejs # Doctor registration form
โ โโโ error.ejs # Error handler view (404 / 500)
โ โโโ health-tips.ejs # Wellness tips interface
โ โโโ help.ejs # Platform FAQs and help guide
โ โโโ index.ejs # AI Healthcare features menu hub
โ โโโ login.ejs # Patient login page
โ โโโ main.ejs # Authenticated patient portal dashboard
โ โโโ medical-info.ejs # Drug directory search tool
โ โโโ report-summary.ejs # Lab report summarizer
โ โโโ signup.ejs # Patient registration page
โ โโโ superadmin.ejs # Super Admin approval console
โ โโโ superadmin-login.ejs # Super Admin login portal
โ โโโ symptom-analysis.ejs # Clinical symptom assessment interface
โ โโโ welcome.ejs # Public landing page
โโโ .env.example # Environment configuration template
โโโ app.js # Express application, AI fallback logic & route handlers
โโโ LICENSE # MIT License
โโโ package.json # Dependency manifest and Node engines
โโโ README.md # Project documentation- Node.js (
>= 22.0.0LTS recommended) - MongoDB (Local installation or MongoDB Atlas URI)
- API Keys:
- Google AI Studio API Key (Gemini)
- Groq Console API Key (LLaMA 3.3)
git clone https://github.com/Gyan-Ranjan-01/DocOnCall.git
cd DocOnCallnpm installCreate a .env file in the root directory using the provided template:
cp .env.example .envSet the required environment keys:
# Server Configuration
PORT=8080
SESSION_SECRET=replace_with_a_secure_random_string
ADMIN_PASSWORD=replace_with_your_admin_password
# Database Configuration
MONGO_URL=mongodb+srv://<username>:<password>@cluster0.example.mongodb.net/doconcall?retryWrites=true&w=majority
# AI Provider API Keys
GEMINI_API_KEY=your_gemini_api_key_here
GROQ_API_KEY=your_groq_api_key_here(Note: The server terminates immediately on startup if SESSION_SECRET is missing. If ADMIN_PASSWORD is unset, admin authentication fails closed with HTTP 503.)
node app.jsThe console will indicate database connection status and model fallback order:
๐ฅ HEALTHCARE AI SERVER STARTED
๐ Server URL: http://localhost:8080
๐ Gemini API: โ Configured
๐ Groq API: โ Configured
๐ค AI Providers: Google Gemini + Groq (Multi-Model Fallback)
Open http://localhost:8080 in your web browser.
When deploying to Render or similar cloud platforms, verify the following:
- Environment Variables: Set
SESSION_SECRET,ADMIN_PASSWORD,MONGO_URL,GEMINI_API_KEY, andGROQ_API_KEYin the hosting dashboard. IfSESSION_SECRETis omitted, the process will crash-loop. - Reverse Proxy Trust: app.js enables
app.set('trust proxy', 1). WhenNODE_ENV=productionis set, Express automatically requires HTTPS to transmit the session cookie (secure: true). - Secret Rotation: Never reuse local development secrets or keys committed in past commits.
| ๐ Landing Page | ๐ User Authentication |
|---|---|
![]() |
![]() |
| ๐ค Patient Portal Dashboard | ๐ฉบ AI Clinical Suite |
|---|---|
![]() |
![]() |
| ๐ค AI Medical Chatbot | ๐ Lab Report Summary |
|---|---|
![]() |
![]() |
To remain candid about current engineering boundaries, the following limitations are present in the codebase:
- Monolithic Architecture: All routes, database operations, error handlers, and AI fallback routines reside inside a single app.js file (~1,450 lines) rather than being split into modular controllers, services, and route modules.
- Default In-Memory Session Store (
MemoryStore):express-sessionis configured with its default in-memory store. Restarting the server or redeploying the container logs out all active users and doctors. Production deployment requires migrating to a persistent session store such asconnect-mongo. - Volatile In-Memory AI State: Active chat conversations (
chatSessions) and AI telemetry metrics (modelStats) are stored in Node.js in-memoryMapobjects and reset on process termination. - Prescription OCR Lacks Fallback: Vision analysis relies exclusively on Gemini's multimodal capabilities. Because Groq's LLaMA 3.3 model is text-only, prescription image analysis cannot fail over to Groq and will return an HTTP 503 error if Gemini is rate-limited or unavailable.
- Basic Single-Secret Admin Authentication (No Granular RBAC): The
/superadminportal is gated by a master access passphrase (ADMIN_PASSWORD) with timing-safe comparison and rate limiting. It lacks individual administrator accounts, audit logs, or multi-factor authentication (MFA). - Rule-Based Keyword Matching for Triage: Doctor recommendations use substring keyword matching against patient symptoms (e.g., checking if the text includes
"chest"or"heart"for Cardiology). It lacks clinical taxonomy parsing (such as SNOMED CT / ICD-10) and can misclassify complex or ambiguous clinical presentations. - No Automated Testing Suite: The repository currently does not include automated unit, integration, or end-to-end tests.
- No Strict Payload Validation: Incoming POST request bodies rely on basic presence checks rather than strict schema validation libraries (such as Zod or Joi).
- Persistent Session Storage: Migrate
express-sessiontoconnect-mongoto maintain login sessions across server restarts. - Role-Based Access Control (RBAC): Support individual admin accounts with audit trails and multi-factor authentication.
- Modular Code Refactoring: Split app.js into dedicated
controllers/,routes/, andservices/layers. - Persistent Cache (Redis): Store chat history and telemetry metrics in Redis to preserve session states across restarts.
- Automated Test Coverage: Introduce unit and integration tests using Jest and Supertest.
- WebRTC Teleconsultations: Peer-to-peer encrypted video consultations between verified doctors and patients.
- Request Schema Validation: Integrate Zod or Joi middleware to validate request bodies and file upload constraints.
Created during HackSprint 2025 by Gyan Ranjan and Team DevStormers; maintained under DevAI.
- Gyan Ranjan โ Lead Developer & Maintainer (GitHub โข LinkedIn)
- Team DevStormers โ HackSprint 2025 Contributors
This project is licensed under the MIT License.





