~/sabarish.dev
← all posts

~/posts/digital-qr-prescription

Digital QR Prescriptions: signed, tamper-proof, auditable

Sabarish R2 min read
  • security
  • healthcare
  • typescript
  • full-stack
Digital QR Prescription landing page
Digital QR Prescription landing page

Paper prescriptions have a fundamental problem: nothing about them is verifiable. Anyone with a scanner can forge, edit, or reprint one, a pharmacy can't confirm in real time that a prescription is real, there's no central audit trail for compliance, no expiration enforcement, and no traceability when a dispute happens.

Digital QR Prescription replaces the paper with a cryptographically signed QR code — and treats the prescription like a security token, not an image.

Repo: github.com/SabarishR08/digital-qr-prescription

Digital QR Prescription landing

The prescription as a signed QR code instead of a paper slip.

The approach

  • Signed QR payloads — each prescription's metadata is wrapped in an HMAC-SHA256 signature locked to that prescription, so a tampered or modified code is rejected on scan
  • Tamper detection — invalid QR codes never pass verification
  • Expiration enforcement — prescriptions expire and can't be redeemed afterward
  • Replay prevention — one-time redemption via an atomic check-and-set, so a screenshot of a valid code can't be redeemed twice
  • Complete audit trail — every verification attempt, success and failure, is logged (five distinct failure paths are captured)
  • Role-based access — doctors create, patients view, pharmacists verify, admins audit

Role selection

Role-based access from the start — Doctor, Patient, or Admin decides what each account can do.

The security detail that matters

The QR layer is only half the story — the surrounding system is hardened the same way:

  • JWT access tokens (12 h) + HTTP-only refresh tokens (7 d) with rotation and revocation
  • Role-based middleware for DOCTOR, PATIENT, PHARMACIST, and ADMIN
  • Rate limiting on the verification endpoint (10 requests/min per IP)
  • Database indexes on every high-traffic query path (prescriptionId, actorId, createdAt, result)
  • Cursor-based pagination and role-based request filtering — doctors only see their prescriptions, patients theirs

The UX side

Patients get a list view with embedded QR codes; pharmacists get a scanner workflow; admins get real-time dashboards of audit logs and scan history with auto-refresh, plus CSV/JSON export of scan records.

Create prescription

A doctor creates a prescription record — the payload that becomes the signed QR.

Stack

Next.js 14 + React 18 + TypeScript + Tailwind (frontend) · Node/Express + TypeScript + Prisma (backend) · PostgreSQL · Docker · system-level test suite · architecture docs

It's the QR security line from my QRishing research turned into product code: decode → verify signature → check state → act. Here, the "act" is safely dispensing medicine instead of opening a phishing page.