← All work

Independent product / Medical Aid Navigator

Better questions when the paperwork gets complicated.

An educational navigator and concierge that helps medical-aid members prepare questions, checklists, and documents, and understand what their own benefits guide says.

My role

Solo product design, safety architecture & build

Project status

Live MVP

The result you can inspect

A deterministic emergency check precedes generation; a rules layer reviews generated wording.

System overview

How the pieces connect.

  1. 01

    Check urgency

    Rules inspect scenario and emergency indicators.

  2. 02

    Ground the response

    Curated context guides the model.

  3. 03

    Review wording

    Rules flag or soften prohibited claims.

A simplified view of the documented architecture.

The short version

Context before code.

The problem

Medical-aid documents are detailed, technical, and hard to interpret in the moment — and most people only go looking for answers when they're already stressed, sick, injured, or trying to help a family member. That's exactly the moment to not drop a chatbot that confidently invents benefit limits or tells someone a claim "will be covered." The hard problem isn't generating helpful text; it's building an AI tool for a high-stakes domain that stays safe even when the AI is wrong, down, or manipulated.

What I built

A safety-first request pipeline where the AI is the last and least-trusted component. Every request runs: rate limit → deterministic emergency detection that never calls the AI → grounded AI generation fed only my own curated knowledge base → an output validator that scans and softens forbidden phrasing → a disclaimer appended to every result. The LLM is explicitly forbidden from inventing scheme rules, plan names, benefit limits, codes, or PMB status, and the app is scheme-neutral by design — it teaches the right questions to ask rather than encoding any named scheme's plan data. Stack: Next.js 15 (App Router, TypeScript) on Vercel, a provider-agnostic AI layer defaulting to Anthropic Claude Sonnet 4.6 (OpenAI swappable), an editable markdown knowledge base, optional anonymous Supabase feedback, and client-side PDF export. Stateless and POPIA-aware: no accounts, no member or ID numbers. In Ask MAN, the chat and any attached plan exist only in the browser tab's memory, and nothing is written to a database, browser storage or application logs.

What it demonstrates

A live MVP that demonstrates how to put an LLM into a health-and-money context responsibly — where it explains and asks good questions and uses deterministic checks and output filtering to reduce the risk of diagnosis, claim guarantees, broker advice, or missed emergency guidance. The same fact/commentary discipline as my other AI work, applied where the stakes are highest: structured safety guidance comes from deterministic code, and AI is layered on top, never load-bearing for the parts that could hurt someone.

For a closer look

The decisions behind it.

Architecture & data flow

The app runs on Next.js App Router on Vercel serverless (Node runtime). POST /api/navigate is the spine: rate limit, then detectEmergency() (pure, no network), then grounded generation through the AIProvider interface, then JSON parse with a safe fallback checklist, then validateOutput() on every field, then the standard disclaimer. A second route, /api/classify-scenario, routes free-text "I'm not sure" input to a scenario — but checks for emergencies deterministically first, so a crisis is never routed through the LLM. Content (scenarios, concept explainers, the system prompt, emergency keywords) lives in editable files separate from logic, so the knowledge base can be tuned without touching code.

Constraints & tradeoffs

Emergency guidance had to work even if the AI provider was down, slow, rate-limited, or manipulated by injected input — which is why detection is fully deterministic and runs before the model is ever called. The tool had to stay scheme-neutral because no named scheme's plan data can be reliably guaranteed year to year, so the LLM is fed only a curated knowledge base and forbidden from inventing rules, limits, or codes. Being stateless and POPIA-aware (no accounts, no member or ID numbers) was a design constraint from day one, not a retrofit.

Safety that does not depend on the AI

The single most important design decision. Emergency detection is fully deterministic — keyword, scenario, and structured-flag matching with no network call — and runs before the AI is ever invoked. If someone describes chest pain or a child not breathing, they get static, hard-coded urgent-care guidance (call 10177 / 112, don't delay for benefits) even if the AI provider is down, slow, rate-limited, or manipulated by injected input. The layer prioritises sensitivity, but keyword and scenario matching can miss emergencies. It is a precaution, not a guarantee of detection, and needs evaluation against a representative set of cases. Even the AI's fallback path — when generation fails or returns unparseable output — leads with an standard urgent-care notice, because a fallback can't know whether the keyword scan missed something.

Grounded generation, scheme-neutral by design

The LLM is fed only my own curated /content knowledge base and is forbidden from inventing scheme rules, plan names, benefit limits, prices, codes, or formulary details — if it isn't grounded, it must say so and tell the user to confirm with their scheme. I deliberately don't encode any named scheme's plan limits: they change yearly, vary by plan, and can't be reliably guaranteed from public information, so encoding them is both an accuracy risk and a legal one. Instead the tool teaches the right questions to ask your own scheme. That's a judgement call to ship less and be correct, rather than more and be wrong.

Output validation as a second wall

Never trust the prompt alone. After generation, every field is scanned by a rules layer for phrasing that would turn educational navigation into something dangerous: claim guarantees ("will be covered" becomes "may be covered — confirm with your scheme"), self-declared PMB status, telling someone they don't need care, broker or scheme-switching advice, and accusatory scheme-blaming. Hard violations are auto-softened and flagged for monitoring; softer cautions are logged. The system prompt forbids these and this layer checks for known patterns that may slip through — belt and braces. It's the same escalate-only discipline as ScamCheck, enforced in code rather than trusted to the model.

A provider-agnostic AI layer behind a clean interface

All AI sits behind a single AIProvider interface; the rest of the app never knows which model is active. Anthropic Claude Sonnet 4.6 is the default because it adheres more reliably to the refusal and guardrail instructions that matter here, with OpenAI swappable via one env var. User free text is wrapped in explicit delimiters and treated as data, not instructions, and the system prompt is told to ignore any embedded attempt to change its rules — a pragmatic prompt-injection posture for an MVP.

Ask MAN: the member's own plan, with data minimisation

The guided scenarios teach the right questions in general. Ask MAN lets a member work from their own scheme's benefits guide instead. They attach the PDF (up to 4 MB / 100 pages), and each answer sends the latest question, up to six recent exchanges and the attached plan to the AI provider. That keeps the context window bounded and predictable. The tool still has no live connection to any scheme, so it is explicit that it cannot confirm personal benefits, balances, authorisations, network or PMB status, or claim outcomes, and it asks the member to check the cited text and confirm with their scheme. Privacy is handled by keeping nothing: the conversation and PDF exist only in the browser tab's memory, are cleared on refresh, and are never saved to a database, browser storage or logs. Attaching or removing a plan starts a fresh conversation, so answers from one plan can't leak into another. Members are told to upload benefits guides, not clinical records, and to remove identifiers first. The provider's own retention terms still apply, and the About page says so instead of promising more.

Delivery process

Designed and built solo as a live MVP, and shipped to gather real feedback before deciding what to build next. Safety, knowledge, AI, and data are cleanly separated layers, and the entire knowledge base — scenarios, explainers, the system prompt, even the emergency keyword list — lives in editable content files so the guidance can be tuned without touching application logic. The code is heavily commented with the why behind each safety decision.

What I would improve next
  • Broaden and deepen the grounding knowledge base, and add structured per-scheme question sets while keeping the no-fabrication rule.
  • Act on real-world feedback from the live MVP to decide what's genuinely useful before expanding scope.
  • Back the in-memory rate limiter with a shared store (Upstash / Vercel KV) for a strict cross-instance cap.
  • Expand the automated safety test suite around emergency detection and the output validator.

Tools used on this project

Continue the conversation

Working on something similar?

Explore it with Jay ↗Talk to Justin ↗
Next project RenoClean SA
top