TriageAI: Emergency Triage Assistant Development by Junaid ShahTriageAI: Emergency Triage Assistant Development by Junaid Shah

TriageAI: Emergency Triage Assistant Development

Junaid Shah

Junaid Shah

TriageAI — AI Emergency Triage Assistant

Idea2Impact 2026 · Theme 3: Crisis Management, HealthTech & Emergency Response
A premium, production-quality AI emergency triage assistant. Describe a situation — by typing, speaking, or photographing it — and TriageAI classifies urgency, explains its reasoning, gives first-aid steps, and gets you to help fast, even on a bad connection.

The Problem

In an emergency, people lose the first — and most critical — minutes deciding how serious this actually is. Real emergencies get delayed by hesitation; non-critical situations overload emergency services out of panic. Existing tools are either generic health chatbots with no real triage logic, or hospital systems you only reach once you've already arrived. TriageAI closes that gap: a fast, honest, AI-driven first step for the person standing next to the emergency, with no training.

What It Does

Describe the situation — type, speak (voice input), or attach a photo of a visible injury.
Optionally add vitals (pulse, temperature, SpO2) and a saved medical profile (age, allergies, conditions, medications) for a sharper read.
AI classifies severity — CRITICAL / URGENT / NON_URGENT — with a confidence score and plain-language reasoning ("why AI thinks this").
Gets you moving — first-aid steps, an emergency checklist for critical cases, one-tap ambulance calling with an auto-call countdown (SOS mode), live-traffic directions to the nearest hospital, and a one-tap WhatsApp alert to a saved emergency contact with your location.
Works on bad networks — installable PWA with an offline keyword-based fallback triage engine (English + Hindi/Hinglish) if the AI backend can't be reached in 6 seconds.
Keeps a private case timeline — searchable, filterable, exportable as a PDF report.

Folder Structure


AI Implementation

Providers: Google Gemini (gemini-2.5-flash) primary, OpenAI GPT (gpt-4o-mini) automatic fallback — configurable via AI_PROVIDER_PRIORITY. Each provider gets a 12s timeout; on failure/timeout/malformed output, the next provider is tried automatically. If both fail (or the network itself is too slow), the frontend falls back to a local offline triage engine — the tool never leaves the user with nothing.
Structured output: every provider is constrained to return strict JSON (severity, confidence, reasoning, steps, checklist, home remedies, follow-up question) validated server-side in parseTriageJSON — the single choke point all AI output passes through, so safety rules hold no matter which provider answered.
Multimodal: an optional photo is sent to whichever provider is answering (Gemini inline data / GPT image_url) alongside the text description.
Multi-turn: the AI may ask at most one clarifying question — and only when the situation isn't already clearly critical — before giving a final classification. Conversation history is passed back on the next turn.
Safety, enforced in code, not just prompted: home remedies only ever render for NON_URGENT cases; the emergency checklist only for CRITICAL; a clarifying question can never gate an already-critical case (needs_more_info is force-set to false for CRITICAL, regardless of what the model returns). Never diagnoses, never prescribes medicine or dosages.

Security

helmet for security headers + a scoped CSP (self + Google Fonts + cdnjs for the PDF library only)
express-rate-limit on all /api routes (20 req/min/IP by default — generous, since this is an emergency tool)
Input validation/sanitization (middlewares/validateTriage.js): strips control characters, caps text/history/image sizes, whitelists image MIME types
User text is only ever sent as a user message, never concatenated into the system prompt, and the AI is explicitly instructed to treat embedded instructions in the situation text as part of the description, not a command — limiting prompt-injection blast radius to "a weird but still schema-valid triage," not a security breach
Centralized error handling — a single bad request can't crash the process

Setup & Run Locally


App runs at http://localhost:3000.

Environment Variables

Variable Description Default NODE_ENV development or production development PORT Server port 3000 AI_PROVIDER_PRIORITY Fallback order, comma-separated gemini,openai AI_TIMEOUT_MS Per-provider timeout 12000 GEMINI_API_KEY Google AI Studio key — GEMINI_MODEL Gemini model name gemini-2.5-flash OPENAI_API_KEY OpenAI key — OPENAI_MODEL OpenAI model name gpt-4o-mini RATE_LIMIT_WINDOW_MS Rate limit window 60000 RATE_LIMIT_MAX Max requests/window/IP 20 MAX_BODY_SIZE Max JSON body size (photo uploads) 2mb
You only need one AI key for the app to function — add the other to get real automatic failover.

Migration Steps (if upgrading from an earlier local copy)

npm install — picks up helmet, express-rate-limit, morgan, compression.
Delete any old data/triage.db if you hit a schema error, or just run the app — data/db.js auto-migrates the confidence column onto existing tables without dropping data.
Copy any custom values from your old .env into the new .env.example shape (new vars: AI_TIMEOUT_MS, RATE_LIMIT_*, MAX_BODY_SIZE, NODE_ENV).
No API routes were removed or renamed — /api/triage accepts a richer payload (vitals, medicalProfile, history, image) but { situation: "..." } alone still works exactly as before.

Deployment

Render / Railway (recommended — plain Node.js)

Build command: npm install
Start command: npm start
Add env vars from the table above in the platform's dashboard
Both platforms give you a persistent disk if you want case history to survive redeploys; otherwise SQLite resets on each deploy (fine for a hackathon demo)

Docker


Vercel

Not recommended as-is — Vercel's Node runtime is serverless/stateless, which doesn't suit this app's persistent SQLite file or long-lived process model without restructuring into serverless functions + an external database (e.g. Turso/Postgres). Render or Railway are the better fit for this architecture without rework.

Testing Instructions


Then:
GET /health{"status":"ok"}
Open http://localhost:3000, describe a clearly critical situation (e.g. "chest pain, can't breathe") → confirm severity, confidence ring, reasoning chips, checklist, and the SOS countdown appear
Try voice input (mic icon) and "Read aloud" on a result — both are browser-native (Web Speech API), no server involved
Toggle your device offline (DevTools → Network → Offline) and submit again → confirm the offline fallback triage renders with an "Offline mode" badge
Open the profile modal, save a WhatsApp number, get a critical result, tap "Notify emergency contact" → confirms a WhatsApp message opens with your location
Download a PDF report from a result
Check the case timeline at the bottom, search/filter it, delete a case

Future Roadmap

Deliberately out of scope for the hackathon deadline, listed here rather than half-built:
Full clean-architecture backend refactor (dependency injection, repository layer) — current structure (routes/services/providers/middlewares) is already separated cleanly; a deeper refactor risks breaking working code this close to submission
Server-side accounts + synced (not just local) medical history and case timeline across devices
Real hospital directory with live bed availability (would need a data partnership or paid Places API, not just Maps URL scheme)
Native mobile app wrapper for background SOS + true silent auto-dial (only possible outside the browser sandbox, with OS-level call permissions)
Multi-language UI chrome (buttons/labels), not just AI response language

Disclaimer

TriageAI provides general, AI-generated first-response guidance. It is not a substitute for professional medical advice, diagnosis, or treatment. In any life-threatening situation, call emergency services immediately.
Like this project

Posted Sep 3, 2026

Developed AI tool for emergency triage classification and guidance.