Outpatient care creates a connected history. A patient has visits; each visit may include prescribed medicines and reports; and those records matter because of how they relate to one another. When information is hard to find across visits, clinicians can miss context while reviewing a patient's history.
For our hackathon project, we built MedGraph , a digital outpatient-book prototype that uses FalkorDB to keep those relationships at the center of the application. Instead of treating visits, medicines, and reports as unrelated records, MedGraph connects them in a graph and retrieves them together for patient search and chat.
The problem we wanted to address
A medical record is more than a list of notes. A prescription belongs to a particular visit, and a report is associated with a particular encounter. Keeping those connections clear helps answer practical questions such as:
- What happened during this patient's recent visits?
- Which medicines were prescribed, and when?
- Is there a report associated with a particular visit?
We wanted to build a working prototype that could retrieve this connected history by patient ID and make it easier to explore.
Why FalkorDB?
We chose FalkorDB to represent the connections directly. In MedGraph, the patient is connected to visits, and each visit can connect to medicines and reports. This makes the relationships part of the data model—not something the application has to reconstruct from separate, unconnected records.
Our graph has four main node types:
-
Patientrepresents a patient identified by a patient ID. -
Visitrepresents an encounter, with a date, condition, and optional notes. -
Medicinerepresents a prescribed medicine. -
Reportrepresents report metadata and any text extracted from an uploaded file.
The relationships capture how those records fit together:
(:Patient)-[:HAS_VISIT]->(:Visit)
(:Visit)-[:PRESCRIBED {dosage, frequency, duration}]->(:Medicine)
(:Visit)-[:HAS_REPORT]->(:Report)
Prescription details live on the PRESCRIBED relationship because dosage and frequency belong to a medicine as prescribed during a specific visit.
How MedGraph uses the graph
The application has a Streamlit interface, a FastAPI backend, and FalkorDB for graph persistence. The UI sends requests to the API, and the API uses Cypher queries through the FalkorDB Python client to write and retrieve graph data.
When a visit is recorded, MedGraph creates or matches the patient, creates a visit, connects the two, and links any medicines with their prescription details. When someone searches for a patient, the backend follows the HAS_VISIT relationship and retrieves the medicines and reports linked to those visits.
A simplified visit-and-medicine lookup looks like this:
MATCH (p:Patient {patient_id: $patient_id})-[:HAS_VISIT]->(v:Visit)
OPTIONAL MATCH (v)-[rx:PRESCRIBED]->(m:Medicine)
RETURN v.visit_date AS visit_date,
v.condition AS condition,
collect({
name: m.name,
dosage: rx.dosage,
frequency: rx.frequency,
duration: rx.duration
}) AS medicines
ORDER BY v.visit_date DESC
The patient ID scopes the query, and the graph relationships determine which records belong in the result.
Reports and file storage
MedGraph accepts PDF, TXT, and CSV reports. FalkorDB stores each report's metadata, extracted text when available, and a reference to the original file. The original file bytes are kept in local storage on the API host rather than inside the graph database.
This distinction was an important part of our design: the graph connects a report to the visit it belongs to, while local file storage preserves the original attachment. Text can be extracted from supported files, but scanned PDFs can currently be uploaded without OCR. Adding OCR is a possible future enhancement.
Chat grounded in patient history
MedGraph includes a patient-scoped chat flow. The backend retrieves the patient's graph-connected history and can answer from that context. Without an API key, it uses deterministic responses. Optionally, non-report history questions can use a hosted Gemini model to summarize visit history. Report content and attachment bytes are not sent to Gemini.
We kept the project focused on retrieving and summarizing records. MedGraph is a hackathon prototype, not a diagnostic system or a source of treatment recommendations.
What we learned
Model the relationships that matter. Connecting visits, medicines, and reports gave us a clearer way to retrieve a longitudinal record than treating every item as an isolated entry.
Keep durable data separate from interface state. Patient records persist in FalkorDB, while the chat transcript is not stored as long-term memory. The application can retrieve a patient's graph records again after an API restart.
Choose the right storage for each kind of data. FalkorDB stores the graph and report references; original uploaded files remain in local file storage and need separate backup.
Be precise about what the AI does. The graph provides the patient context. The optional language model summarizes visit history; it does not interpret images, and it does not receive report attachments.
What we'd build next
There are several promising next steps: authentication and authorization for clinician access, OCR for scanned reports, and visible graph-path citations that show which connected records support a chat response. We would also explore audit logging, retention controls, and deployment-readiness work before considering any real-world clinical use.
Try MedGraph
MedGraph is our submission to Graph Hacks — Track 01: Agents That Act on Connected Data. The source code and local setup instructions are available in the MedGraph GitHub repository.
Demo video: https://www.youtube.com/watch?v=KDf3FXspL_w&t=3s
For the hackathon demo, use synthetic or de-identified records. The project does not currently provide a live deployment; the repository README explains how to run it locally with FalkorDB, FastAPI, and Streamlit.


Top comments (0)