Inspiration
Quebec's healthcare access crisis isn't a future problem; it's happening right now. As students at McGill, we see it around us: friends who've never had a family doctor, classmates who sit in ERs for non-urgent issues simply because they have nowhere else to turn, and a dysfunctional, non-responsive 811 government health line that averages hours and hours of wait time.
The number that stuck with us: 1.5 million Quebecers, almost 20% of the population, have no family doctor, confirmed by the provincial government as recently as October 2025. And yet, over half of all ER visits in Quebec are non-urgent. People aren't flooding emergency rooms because they're reckless; they're doing it because there is no structured alternative.
We kept coming back to one question: Why does no one have a good answer to "should I worry about this, and what do I do next?" Diagnosis is a solved problem for doctors. Triage navigation, which provides unattached patients with a safe, structured, evidence-based path forward, isn't. That gap is what RéponSanté is built to fill.
What We Built
RéponSanté is an asynchronous medical triage navigation platform built around a two-stage AI pipeline that routes every patient to the right level of care.
Stage 1: Emergency Gate (Client-Side, Zero Latency)
The moment a patient begins their intake, a keyword gate screens for 16 life-threatening patterns — chest pain, stroke symptoms, anaphylaxis, seizure, overdose, and more. This check runs entirely client-side, before any API call is ever made.
If triggered, the patient sees an emergency modal with one instruction: call 911 immediately. There is no button to proceed. No AI call is made for these cases. The safety gate cannot be bypassed.
Stage 2: AI Triage (Claude + Live NIH Evidence)
All non-emergency cases are analyzed by Claude Sonnet alongside real-time data retrieved in parallel from four public NIH APIs: MedlinePlus, PubMed, RxNorm, and OpenFDA. Claude assigns one of five tiers:
| Tier | Level | Action |
|---|---|---|
| Tier 0 | Self-Manageable | AI generates a home care response grounded in NIH sources |
| Tier 1 | Monitor | Routed to Quebec's 811 nurse line or a pharmacist |
| Tier 2 | Book Appointment | Walk-in clinic or specialist within 2–5 days |
| Tier 3 | Urgent | Go to the ER now |
| Tier 4 | Emergency | Blocked at intake — Call 911 |
For provider-reviewed cases (Tiers 1–3), Claude also produces a structured clinical brief that includes medication interaction flags, red flags, the patient's specific questions, and cited NIH sources, giving providers full context before they write a structured SBAR response.
How We Built It
| Layer | Stack |
|---|---|
| Framework | Next.js 16 App Router (Turbopack), TypeScript 5 |
| Styling | Tailwind CSS, Radix UI primitives |
| State Management | Zustand (intake), React useState |
| Backend | Supabase (PostgreSQL + JSONB) |
| AI — Triage | Claude Sonnet 4.6 (claude-sonnet-4-6) via Anthropic API |
| AI — Translation | Claude Haiku 4.5 (claude-haiku-4-5-20251001) via Anthropic API |
| NIH Grounding | MedlinePlus, PubMed, RxNorm, OpenFDA APIs |
| Validation | Zod v4 |
| Auth | Provider token header (x-provider-token) |
| Resend (case confirmation + response notification) | |
| Real-time Updates | Supabase polling every 5 seconds |
| i18n | Custom EN/FR context with localStorage persistence |
The architecture is intentionally simple: no message queues, no microservices. When a patient submits a case, a Next.js API route fires four NIH API calls in parallel using Promise.all with a 5-second timeout per API, assembles the retrieved content, and passes everything to Claude Sonnet in a single structured prompt. Claude returns a validated JSON object — enforced by Zod — containing the tier score, clinical brief, navigation action, and medication flags. If the output fails schema validation, the case falls back to awaiting_review — a human always sees it.
Simultaneously, Claude Haiku translates the clinical brief into French in the background (fire-and-forget), storing it in ai_brief.fr so French-language providers get an instant translation with zero wait. The patient status page polls Supabase every 5 seconds, so the provider's SBAR response appears automatically with no refresh required.
The platform is fully bilingual. All UI strings switch instantly between English and French. Patient-submitted values are always stored in English regardless of the patient's chosen language, ensuring the provider sees consistent data in their own language preference.
Challenges We Faced
1. Grounding Claude without hallucination
Our biggest technical fear was Claude generating medical information from training data and presenting it as sourced. The solution was to never ask Claude to recall medical facts, only to classify and organize content that we explicitly retrieved from top NIH databases and passed in. Every NIH source displayed to a patient was fetched live at submission time. Claude cites what we gave it; it doesn't fill gaps from memory.
2. Keeping diagnostic language out of the output
Claude is very good at sounding like a doctor. That's a problem when you're explicitly not building a diagnostic tool. We spent significant time on system prompt engineering to eliminate diagnostic framing. The word "diagnosis" is prohibited in patient-facing output, and Claude is instructed to frame every response as guidance on what to do next, not what the patient has. Testing this robustly against edge-case inputs was one of the more painstaking parts of the build.
3. Atomic case claiming at the provider layer
Without concurrency control, two providers could theoretically claim the same case simultaneously. We solved this with a Supabase row-level lock on claim operations — the first write wins and receives the case; the second receives a 409 error that the UI surfaces gracefully. Simple in principle; getting the Supabase policy right took longer than expected.
What We Learned
- Working as a team, i.e. coordinating across the stack, dividing ownership, and staying aligned under time pressure, was essential to project success.
- Managing Claude context and usage effectively, including understanding token limits, structuring prompts efficiently, and controlling what goes into context, was essential to keeping the system reliable and cost-effective.
- Prompting techniques and best practices matter enormously. We spent more time on the system prompt, the tier criteria, the disclaimer, and the human-in-the-loop design than on any other single component.
- Working with NIH database APIs: MedlinePlus, PubMed, RxNorm, and OpenFDA taught us how to retrieve, parse, and pass live medical data into an AI pipeline in a way that keeps responses grounded and prevents hallucination.
- The most important part of a project is the problem it solves. All the technical decisions we made only mattered because they traced back to a real gap affecting 1.5 million Quebecers.
Built With
- next.js
- nih
- postgresql
- react
- resend
- tailwind
- typescript
Log in or sign up for Devpost to join the conversation.