Inspiration
When a patient in a clinical trial who is on several medicines suddenly develops liver damage, a rash or kidney trouble, someone has to answer a hard question: was this the drug's fault?
Drug-safety doctors answer it by hand. They pull prescription dates from one system, lab results from another, and side effects from long FDA labels, then work through a 10-question checklist (the Naranjo scale) for every drug. The FDA receives over a million side-effect reports a year, far more than anyone can review properly. We wanted to do the digging for them, so the doctor only has to make the call.
What it does
Druggie turns each case into a card a doctor can review in minutes:
- Drugs page: patients grouped under the drug most likely behind their problem.
- Patient card: the problem, symptoms, BMI, blood pressure and existing conditions at a glance.
- Most likely cause: the drug's boxed warning, its serious side effects, and the exact label sentence that matches this patient.
- Reasons: every checklist answer with its proof, e.g. "ALT fell from 186 to 31 U/L, 5 weeks after stopping."
- AI second opinion: a draft where every claim cites a numbered piece of evidence, so nothing is taken on trust.
- Agree / disagree: the doctor swipes. The tool never makes the final decision.
How we built it
Data. Patients come from Synthea, a synthetic patient generator, so there's no real patient data. Drug information comes from free public sources:
- openFDA drug labels
- RxNorm, to turn a product code into its active ingredient
- RxClass, for drug classes such as "penicillins"
Cleaning first. Before scoring anything, a Python pipeline builds seven cleaned tables per case:
- reactions
- drug courses (refills within 30 days merged)
- label side-effect sections
- lab trends
- re-exposures to the same drug
- drug allergies
- objective evidence
Each table is shown in the app, so every number can be traced.
Scoring. We implemented the six Naranjo questions the data can actually answer:
| Question | Yes | No |
|---|---|---|
| Known side effect on the label? | +1 | 0 |
| Did the reaction start after the drug? | +2 | −1 |
| Did it improve when the drug was stopped? | +1 | 0 |
| Did it come back when the drug was restarted? | +2 | −1 |
| Similar reaction to this or a similar drug before? | +1 | 0 |
| Confirmed by a lab test? | +1 | 0 |
"Don't know" always scores 0. A drug's score is
$$S = \sum_{i} p_i, \qquad p_i \in {-1, 0, +1, +2}$$
and it maps to a category: S ≥ 9 definite, 5 ≤ S ≤ 8 probable, 1 ≤ S ≤ 4 possible, S ≤ 0 doubtful.
AI. A small Python server sends the AI only the evidence we gathered. Every item is tagged with its source, e.g. (source: openFDA label, boxed warning), and every reason in the answer must cite one. The server drops any citation the model invents, and any drug the patient isn't actually taking. We used OpenRouter with a free model, behind an OpenAI-compatible interface, so the provider can be swapped.
Frontend. React + TypeScript + Vite: swipeable cards that flip and expand into Drug / Reasons / Data pages, in a deliberately plain black-and-white design.
Challenges we ran into
- Synthetic patients never have drug reactions. Synthea doesn't make drugs cause anything, so every link it shows is a coincidence. We planted one test case with a known answer: amiodarone causing liver damage, with matching labs and symptoms. Druggie ranked it first at 5 points ("probable"), and the AI agreed.
- Text matching lies. Our first label search counted "renal failure" in a warning about newborns, a cold medicine's "If sore throat is severe…", and lung cancer in paclitaxel's label, which is what paclitaxel treats. We switched to strict phrase matching, skipped sentences about pregnancy, monitoring and "patients with…", and showed the quoted sentence so a doctor can check it.
- Messy medical data:
- Kidney disease shows up as stages 1, 2 and 3 all "ongoing" at once.
- Infections clear on their own, so their end dates say nothing about the drug.
- One RxNorm code turned out to be obsolete.
- Two brands of the same drug, Jolivette and Errin, had to be matched by active ingredient.
- Free AI models. They returned broken JSON, duplicate drugs, and even a drug named
"null". We added a strict response schema, retries and server-side checks. - Knowing when to stop. Three Naranjo questions (placebo, blood levels, dose changes) have no data behind them in Synthea. We dropped them rather than fake answers.
What we learned
Built With
- css
- html
- javascript
- node.js
- openfda
- openrouter
- python
- react
- react-router
- rxclass
- rxnorm
- synthea
- typescript
- vite
Log in or sign up for Devpost to join the conversation.