Inspiration

Discharge is one of the most fragile moments in a patient's care journey—not because clinicians are careless, but because information is handed across multiple documents created by different people at different times. A discharge summary, prescription, lab report, and referral letter may all be individually correct, yet still fail to tell a complete, consistent story.

I wanted to build something that focuses on that specific transition-of-care problem. Not an AI doctor. Not a diagnostic assistant. Just a reliable second pair of eyes that checks whether the discharge paperwork is actually complete before a patient walks out the door.


What it does

CareGate AI reviews an entire discharge packet—typically a discharge summary, prescription, lab report, and referral letter—and checks whether the patient handoff is actually complete.

Rather than summarizing documents, it looks for four specific classes of discharge gaps:

  • Medication reconciliation – conflicting dosages or incomplete medication instructions across documents.
  • Follow-up completeness – referrals or follow-up actions without a documented appointment or responsible owner.
  • Pending-test closure – tests that require future action but have no corresponding follow-up plan.
  • Instruction consistency – contradictory instructions appearing in different discharge documents.

Every finding is fully explainable. Nothing is flagged without evidence.

Each issue links directly back to the exact document, page, and supporting excerpt so a reviewer can immediately understand why it was raised.

Instead of simply dismissing alerts, reviewers can:

  • assign ownership,
  • document a resolution,
  • override a finding with a recorded justification.

Only after every finding has been reviewed does the case move from Review Required to Ready for Clinician Sign-off.

CareGate also compares revised discharge packets against previous versions, highlighting exactly what changed instead of forcing reviewers to manually compare documents.


How we built it

One design decision never changed throughout the project:

The model never decides whether something is wrong.

The pipeline is intentionally split into two independent stages that don't trust each other.

First, Gemini processes the uploaded PDFs (using local text extraction with OCR fallback for scanned pages) and extracts structured facts such as:

  • diagnoses,
  • medications,
  • laboratory tests,
  • referrals,
  • documented owners,
  • follow-up instructions.

Its job ends there.

Gemini never decides whether a discharge packet contains a problem.

Early in development I realized I couldn't safely rely on raw model output. Even a single missing field could produce misleading findings, so every extraction is validated against a strict Zod schema. If validation fails, processing stops immediately instead of quietly producing incorrect results.

A separate deterministic rule engine—written entirely in TypeScript—performs every safety check. Because extraction and judgment are separated, debugging became much easier. Whenever something looked wrong, I immediately knew whether the issue came from document extraction or from the rule logic rather than trying to untangle one large AI workflow.

Cases, findings, evidence, reviewer decisions, and version history are stored in Supabase so reviewers can safely continue where they left off.

The frontend is built with Next.js and deployed on Vercel. whole project is built with Codex gpt-5.6 Terra and gemini api is being called at runtime for docuement extraction and parsing.

Throughout development I used Codex (GPT-5.6) as a pair programmer rather than an autopilot. It helped scaffold the application, build the Supabase schema, implement the rule engine, generate tests, and accelerate repetitive engineering work. Every significant change was reviewed manually, and before considering any feature complete I validated it against the live deployed application using real Gemini API calls—not just local mock data.


Challenges we ran into

The most interesting production issue wasn't actually a coding bug.

Partway through development, gemini-2.5-flash—the model I had originally built around—was deprecated for new users. My extraction endpoint suddenly started returning a generic 502 error in production.

The real problem wasn't Gemini.

It was my own error handling.

I had accidentally hidden the provider's actual response behind a generic message, making debugging much harder than it needed to be. Once I surfaced the real Gemini error, the fix itself was straightforward, but it reinforced an important lesson: a demo working once on your machine isn't the same as a system behaving reliably in production.

The second issue was more subtle.

An external reviewer discovered that assigning a finding to someone—without actually resolving it—incorrectly allowed the entire case to move to Ready for Clinician Sign-off.

For a project whose entire purpose is preventing missed handoffs, that was exactly the kind of bug that couldn't be ignored.

I reproduced the scenario on the deployed application, fixed the workflow, and re-tested the complete review process before considering the feature finished.

One design choice that often surprises people is an inconsistency I intentionally kept.

Even after every finding has been resolved, the discharge timeline may still visually show where the original paperwork contained a gap—for example, a missing documented owner.

That's deliberate.

Resolving a finding represents a reviewer's informed decision, not a rewrite of the original documents. I'd rather preserve an accurate audit trail than make the interface appear perfectly clean by hiding what actually happened.


Accomplishments that we're proud of

The part I'm proudest of isn't simply getting AI to read medical documents—it's making every finding explainable.

Every issue produced from a real Gemini extraction links back to real evidence, including the exact PDF page and highlighted source text that triggered it.

Getting that right was significantly harder than I expected because Gemini doesn't always reproduce source wording exactly, so matching extracted facts back to their original document locations required far more work than simple text extraction.

I'm also happy that one of the planned "nice-to-have" features—the discharge packet comparison view—ended up proving its own value during development. While testing version comparisons, it exposed two findings that disagreed about the same follow-up timeframe across document revisions, allowing me to fix the underlying logic before the demo ever reached anyone else.


What we learned

The biggest lesson was that "explainable AI" is much harder than it sounds.

Showing a highlighted PDF isn't enough.

A reviewer has to be able to inspect why a finding exists and, if necessary, disagree with it.

That's why I deliberately avoided letting the model decide whether a discharge packet is safe. AI extracts structured information; deterministic rules make the safety decisions.

That separation turned out to be the single architectural choice that made testing, debugging, and trusting the system possible.


What's next for CareGate AI

The current prototype demonstrates the workflow, but there are several areas I'd improve before considering it production-ready.

Near-term priorities include:

  • implementing real authentication and least-privilege access controls (the current Supabase RLS configuration is intentionally relaxed for the demo and clearly documented as unsuitable for production),
  • expanding instruction-consistency checks to reason across multiple care teams instead of individual documents,
  • supporting richer evidence linking and reviewer collaboration.

Longer term, I'd like CareGate to integrate directly with hospital Electronic Health Record (EHR) systems rather than relying on uploaded PDFs.

The core architecture wouldn't change.

Documents would simply arrive automatically instead of being uploaded manually, while the same extraction-plus-rules pipeline continues acting as a final, explainable safety gate before every patient discharge.

Built With

Share this project:

Updates