Inspiration
Every hospital visit in India seems to come with the same three problems: a long queue, a plastic folder full of old papers, and a doctor asking questions you've already answered at your last visit. A patient with a surgery booked for 9 am can still spend an hour at the admission desk filling forms and making photocopies.
The numbers back this up. One study at a North East India tertiary hospital found patients waited about 116 minutes in total for a consultation of about 5 minutes (source). EMR adoption in India is only around 35%, and small and mid-sized hospitals still rely heavily on paper (Bain & HealthQuad, 2026).
What stuck with me most: when patients register online instead of walking in, the median wait at the registration counter drops from 60 minutes to 15 (source). India's own Scan & Share proved this works for OPD registration, but only 1.3% of its tokens came from private hospitals (WHO Bulletin). Nobody had brought the "do it before you arrive" idea to admission paperwork or to the old paper records patients carry around. HeyDoc started as my project for SIPS '26 at IIT Kharagpur, and that gap is what I built it to fill.
What it does
HeyDoc gives every patient one medical vault, and lets the hospital work from that vault instead of from paper.
- Patient Health Memory: patients, doctors and labs upload records (digital PDFs, printed scans, even handwritten prescriptions). HeyDoc reads, sorts and indexes them. Patients can ask "What medications am I on?" and get an answer pulled only from their own records, with the source document shown.
- Queue-free admission from home: for a scheduled surgery, the patient uploads their ID, the doctor's admission letter and insurance papers from home. HeyDoc checks them automatically. Once everything is verified, the patient gets a one-time QR code. At the hospital, the admin scans it, the verified record opens, and the patient goes straight to a bed.
- Booking and live queue: patients book from the doctor's real slots, check-in opens 30 minutes before, and staff move the queue with a "Notify" button so patients know when it's their turn.
There are five roles (patient, doctor, lab, TPA/insurance desk, hospital admin), and each one only sees what real hospital access rules allow.
How I built it
Backend: FastAPI with raw SQLite. Frontend: a single-file vanilla JavaScript app with no framework and no build step. Deployed on Railway (backend) and GitHub Pages (frontend).
OCR that picks the right tool per document
- Digital PDF: PyMuPDF reads the text layer instantly
- Printed scan: docTR, accepted if confidence is 0.80 or higher
- Handwritten or unclear: escalated to Gemini Vision
Search that finds the right answer. Each document is sorted into 7 types and split into 6 medical categories (diagnosis, medications, lab reports and so on). A question goes through two searches at once: meaning-based search (BAAI bge-large embeddings in ChromaDB) and keyword search (BM25). The two ranked lists are merged with Reciprocal Rank Fusion:
$$\text{RRF}(d) = \sum_{r \in R} \frac{1}{k + r(d)}$$
where \( r(d) \) is the rank of chunk \( d \) in each list and \( k \) is a small constant. The top results are reranked with bge-reranker-v2-m3, and Gemini 2.5 Flash-Lite writes the answer with citations. Every search is locked to one patient ID, so there is no cross-patient data, ever.
Admission checks that don't blindly trust AI
- Tier 1, plain rules, zero AI calls: Aadhaar checksum, PAN format, doctor registration number, insurance document structure
- Tier 2, Gemini only for the unclear cases
- Still unsure? It goes to a human admin as "needs review". Nothing uncertain is ever auto-approved.
The QR token is random, unguessable and single-use. It holds only the token, never any patient data.
Challenges I ran into
- OCR that was confidently wrong. Sometimes docTR reported high confidence on text that was complete garbage. I added a garbage-detection check that overrides the reported confidence and escalates the page to Gemini Vision.
- Fitting the model stack on a small server. The embedding model, reranker and OCR together came to about 3.5GB, which didn't fit on Railway's free 1GB tier. I built an INT8 quantization pipeline to shrink them, then later moved to a bigger plan and kept the quantized path as a fallback.
- Access rules getting messy. Labs, insurance desks and admins each needed "same hospital only" access. Writing that check in every endpoint caused bugs, so I moved it into one shared function that every endpoint goes through.
- A time zone bug in the queue. Mixing UTC and local timestamps broke appointment and queue times. The fix was a strict rule: all appointment and queue times stay in local time.
Accomplishments that I'm proud of
- A working, deployed app, not just a slide deck, with all five roles and real access rules
- An admission flow where the AI is never the final word on an uncertain case
- Strict per-patient isolation, so one patient's question can never surface another patient's records
What I learned
In healthcare, knowing when not to trust the AI matters as much as the AI itself. The best design choice in HeyDoc wasn't a model; it was the rule that rules go first, AI goes second, and a human goes last. I also learned that most of healthcare's pain here isn't clinical at all. It's queues, paperwork and lost context.
What's next for HeyDoc
- Connect the lab and insurance dashboards to live data (they currently run on sample data)
- Test OCR on a much larger set of real handwritten prescriptions
- Plug in official ID and insurer verification APIs (current checks catch careless fakes, but they are not official lookups)
- A pilot with 2 to 3 hospitals in Delhi NCR, measuring desk time, cost per admission and error rates
- ABDM integration, so HeyDoc works alongside India's national health IDs instead of beside them
Log in or sign up for Devpost to join the conversation.