← All projects

Freelance Project · Full-stack · LLM · OCR

Sample Collection Desk

AI platform that turns insurer emails into scheduled home visits and checks medical reports.

Next.js 15 (App Router)React 19Tailwind CSS v4PostgreSQL (Neon)Anthropic API (Claude Haiku 4.5)OCR.space APIWhatsApp Cloud API (Meta)Google Apps Scriptpdf-libVercel + CronJWT (jose)bcryptNode.js test runner

A multi-centre diagnostic group was running its home sample collections out of six Gmail inboxes and a spreadsheet. Insurance TPAs emailed bookings in a dozen different formats, staff re-typed each one, and technicians were coordinated by phone call. I designed and built the system that replaced that: one web app used by administrators, coordinators and field technicians, from the email arriving to the report going out.

A Google Apps Script forwarder in each inbox pushes new mail to the app every five minutes. Only mail from trusted insurer domains that passes Gmail’s sender authentication goes to Claude Haiku 4.5, which extracts the patient, tests, address, reference number and time slot into one schema, including the awkward formats, where the reference sits only in the subject line or a provider uses an employee ID instead of an application number. The email is treated as untrusted data inside the prompt, so text in a booking can’t rewrite the rules.

Nothing is silently lost or duplicated. Each email is processed exactly once, a reminder that says nothing new changes nothing, and missing details are filled in without overwriting what is already there. Anything uncertain (an unknown sender, an unreadable email, a conflicting identity, or a change to a case a technician already holds) waits on a review screen with the reason it stopped.

Coordinators assign each day’s visits on a dispatch board and hand them to technicians over WhatsApp in one tap. Technicians update status from their phones, and every change across thirteen statuses, from Fixed and Rescheduled to Cancelled with a reason, goes through one set of rules that stamps who did it, when, and records it in the case history.

When a case is fixed, rescheduled, cancelled or completed, the right insurer representative is notified on WhatsApp, either automatically through Meta’s WhatsApp Cloud API, or queued for one-click sending. Each representative also gets a permanent, read-only link showing only their own cases for yesterday, today and tomorrow. The link’s secret is never stored, only its SHA-256 hash.

For report quality, staff upload a completed medical examination report (MER) PDF. The app splits it with pdf-lib, reads it with OCR.space, and uses Claude to compare it against an approved sample and a fixed checklist covering ID details, vitals, every question answered, dates, signatures and the ECG. Findings come back in English and Hindi, each quoting the text on the page it rests on; anything the model can’t ground in the report goes to manual review instead of being reported as fact. It works within the OCR free tier’s limits, and a failed check retries only the pages it hasn’t read yet.

The same app runs staff operations. Attendance is marked automatically from each person’s first sign-in. Field staff log daily bike meter readings, bus or train fares and hotel or food expenses, with photo proof. Administrators approve each claim, and salary is calculated from base pay, approved kilometres at a per-km rate and approved expenses. Visit distance is calculated from the centre’s and client’s coordinates with the Haversine formula, so there are no map API costs.

Per-technician dashboards show assigned, completed and outstanding work by day, week and month. Every list exports to CSV or Excel with exactly the filters on screen. The Excel export is a hand-written XLSX writer rather than a library, because the only spreadsheet package on npm carries unfixed high-severity advisories and this app holds patient data.

Because it holds health data, access is locked down: three roles with server-enforced permissions, bcrypt-hashed PINs with lockout after repeated failures, and twelve-hour sessions that end immediately when access is revoked. It adds a strict content security policy, secrets that fail closed, and a full audit log of every sign-in, edit, export and status change with device and approximate location. Deletion is a soft delete into a recycle bin. Only an administrator can destroy a record, and only from there.

The codebase is around 18,000 lines of JavaScript with 28 unit-test files plus database integration tests, and its additive, re-runnable migrations upgrade the live system in place without losing data. Hosted on Vercel with Neon Postgres, with a scheduled job that closes each day’s attendance.