Inspiration

A patient gets discharged, goes home, and for the next 48 hours nobody's really watching. Meds get skipped, symptoms creep up, follow-ups don't get booked — and by the time anyone notices, it's an ER visit that a five-minute phone call could've prevented. Hospitals know this. It's exactly why 30-day readmission rates are such a mess. We wanted to build the thing that actually makes that call.

What it does

Discharge Guardian calls high-risk patients within 48 hours of discharge and asks the questions a nurse would ask: are you taking your meds, how are you feeling, did you book your follow-up. It runs the answers through a risk check — chest pain, breathlessness, confusion, or fainting trips an immediate escalation flagged for the ED. Missed meds plus worsening symptoms gets a televisit booked within 24 hours. Everything lands on a live dashboard clinical staff can glance at, updating every 3 seconds, no manual chart-checking required.

How we built it

  • Backend: FastAPI + async SQLAlchemy on SQLite — built async from the ground up so it doesn't choke under real request load
  • Scheduler: a CSV-driven loop that ingests discharge data, dedupes on patient_id so re-runs don't crash on duplicate keys, and drives the call workflow
  • Call layer: every call goes through calle_client.py, which sits behind a single CALLE_MOCK flag. Flip it and you go from a fully offline mock pipeline to live CALL-E API calls — nothing else in the system changes. That was a deliberate choice: the demo path and the production path had to be the same code path, not two versions that drift apart.
  • Risk logic: LACE score + symptom keywords decide the escalation tier
  • Frontend: Next.js dashboard polling /patients, rendering risk badges and gap lists in real time
  • Ops: the whole thing runs with one command — docker compose up --build — or ./run.sh if you don't want Docker at all

Challenges we ran into

Getting the mock/live abstraction right was harder than it sounds — the temptation is always to special-case the mock path somewhere, and the moment you do that, your demo stops proving anything about production. We also had to get the async SQLAlchemy session lifecycle right for FastAPI (easy to reach for the sync sessionmaker out of habit and have it silently break under load), and tune the risk-triage logic so it separates genuinely urgent cases from noise without either crying wolf constantly or missing the ones that matter.

What's next

Escalations are currently logged, not paged — wiring that into a real alerting system is priority one. After that: load-testing the live CALL-E integration against real call volume, and tuning the agent's task prompt against actual transcripts instead of assumptions.

Built With

Share this project:

Updates

Submission history