Case study
Clinra — Telemedicine Platform
See a doctor, anywhere: book across timezones and meet by secure video in the browser
Product Design & Full-Stack Development · By Sajith Kavishan
Open the live demo
About Project
Clinra lets patients find a doctor licensed for their country, book a time in their own timezone, and talk face to face over a secure video call in the browser. Afterwards they get notes, a verifiable e-prescription and a health timeline they can keep.
Next.js 15 · Express 5 · Socket.io · WebRTC · Prisma · PostgreSQL
Fonts & Colors
Bricolage Grotesque
Aa
Public Sans
Aa
JetBrains Mono
Aa
Teal accent
Soft background
Ink
At a glance
- Role: product design and full-stack development.
- Platform: a responsive web app for patients, doctors and admins.
- Stack: Next.js 15, Express 5, Socket.io, WebRTC, Prisma and PostgreSQL.
- Hosting: Vercel, Render and Neon, all on free tiers.
The whole journey in under three minutes
A patient books and pays with a Stripe test card, meets the doctor by video (shown side by side), and receives notes and an e-prescription. Recorded on the real app with captions.
The problem
Getting a doctor’s opinion should not mean a day off work and a long queue. For a routine consultation, such as a follow-up, a rash or a prescription renewal, many people in Sri Lanka and the region still travel to a clinic and wait. Video consultations help, but often the tools are a WhatsApp call and a photo of a handwritten prescription. There is no proper record and no way for a pharmacy to check it. Seeing a doctor online also brings problems a normal booking app does not have. A doctor can only treat patients in countries where they hold a licence. The patient and the doctor may be in different timezones. Mobile data can be slow. And medical records need much stricter privacy than a typical app.

Three people, three different jobs
- Patient: wants a trustworthy doctor quickly, with as little form-filling as possible. Searches by need and country, books in their own time and keeps notes and prescriptions.
- Doctor: wants a calm schedule, quick note-taking and a clear view of how the practice is doing. Sets hours, services and fees, writes SOAP notes and e-prescriptions, and tracks visits and earnings.
- Admin: keeps the platform safe by checking every doctor’s licence before they can be booked. Reviews licences, handles refunds and watches platform health.

Admin: licences checked first
Every doctor’s licence is reviewed before they can be booked. The admin overview shows platform figures and the licences waiting for review.

A complete product, built to run for free
- Simple enough for anyone: one clear action per screen, plain language, and no app to install.
- Correct across borders: doctors appear only where licensed, and every time is shown in the viewer’s own timezone.
- Private by default: records are locked to the patient and their doctors, and every view is logged.
- Zero hosting cost: storage, builds and database time were treated as scarce from day one.

From “I need a doctor” to a prescription in one sitting
- Find: choose a need (16 specialties in plain words, such as “Heart” or “Skin”) and a country. Only doctors licensed there are shown.
- Book: pick a slot from the next five days, a 30-day calendar, or a custom time within the doctor’s hours, then pay through Stripe.
- Get reminded: a browser notification, a Google Calendar link or an .ics file, each 30 minutes before the visit.
- Meet: join a 1-to-1 video call in the browser, with chat, file sharing and an audio-only mode for weak connections.
- Keep the record: the doctor’s notes, an e-prescription with a QR code, and shared files land on the patient’s health timeline.

A health timeline to keep
Every visit with its notes, prescriptions and files in one place.

A practice dashboard that answers real questions
Doctors set up a public profile, services with their own length and fee, a licence for review, and weekly hours in their own timezone. Their home screen shows today’s schedule and a live alert when a patient is waiting in the call. The stats page is built around what a doctor actually asks: am I busier than last month, when are my peak hours, and are patients coming back? Each figure is compared with the previous period, over 7 days, 30 days, 3 months or 12 months.

The doctor’s home
The next visit, notes still to write, and today’s schedule.

Visit records
SOAP notes and e-prescriptions, which can be revoked.

Designed for the phone in the patient’s hand
Most patients will open Clinra on a phone, often on mobile data. Every screen was checked at 375 px wide with no sideways scrolling, and the layouts change where it matters rather than just shrinking.
- Booking stays one tap away: on a doctor’s profile the price and “Book a video visit” stay pinned to the bottom of the screen.
- Navigation folds away: the sidebar becomes a menu button, so content gets the full width.
- Calls fit small screens: chat and notes open full screen on phones, and the controls stay within thumb reach.
- Light on data: photos are resized in the browser before upload, and an audio-only mode saves data on weak connections.

A clinical, light palette
One teal accent on soft neutral backgrounds. It feels medical without feeling cold, and leaves colour free for status, such as a waiting patient or a revoked prescription.
Borrow what people know
The call screen follows the Google Meet layout: round controls, red to leave, side panels for chat and details. Nobody has to learn a new interface in the middle of a consultation.

Booking across timezones without double bookings
Problem: a doctor in Colombo works 9 to 5 in their own time, while a patient abroad needs to see those hours in theirs. Two patients can also click the same slot at the same moment. Solution: slots are generated from each doctor’s weekly hours in their timezone, stored in UTC, and shown in the viewer’s. The database blocks double bookings with a unique slot key plus a Postgres advisory lock for custom times.

Real-time video between two different domains
Problem: the web app (Vercel) and the API (Render) live on different domains, so the browser will not send the login cookie to the call server. Solution: the page fetches a 2-minute socket token through the same-origin /api proxy. The call is raw WebRTC with the “perfect negotiation” pattern over Socket.io, so either side can reconnect safely.

Medical-grade privacy
Problem: notes, prescriptions and uploaded reports are among the most sensitive data a person has. Solution: httpOnly cookies with rotating refresh tokens, role-based access, files served only through 60-second signed links, and an audit log for every view. Patients can download all their data or delete their account; past records are anonymised because medical records must be kept.

Prescriptions a pharmacy can trust
Problem: a screenshot of a prescription is easy to fake or reuse. Solution: the server generates a PDF with a QR code. Scanning it opens a public page that shows the pharmacist only what they need, and whether the doctor has revoked it.

A monorepo with three apps and one shared core
Video and audio go directly between the patient and the doctor (peer-to-peer, encrypted), with an optional TURN relay for strict networks. Types, the specialty and country catalog, and the timezone and slot logic live in a shared package used by both the web app and the API, so the booking rules cannot drift apart.

A working product, live and free to run
- 3 roles, each with their own app.
- 16 specialties across 6 countries.
- 30-minute video visits in the browser.
- $0 monthly hosting cost.
- Full patient journey: search, timezone-aware booking, Stripe test payments, reminders, video call, notes, e-prescription and health timeline.
- Doctor onboarding, schedule, SOAP notes, e-prescriptions with revocation, practice analytics and payouts.
- Admin licence review with audit logging, refunds and platform analytics.
- Privacy controls: download my data and delete my account.
- Responsive down to phone width, with a seeded year of realistic demo data.
- English, Sinhala and Tamil translations built for patient screens (switched off for now).

An edge case, handled
When the camera is blocked, the screen says exactly how to fix it.

What I learned
- Constraints make better products. Designing for free tiers pushed me toward choices that are good anyway: smaller uploads, no wasted polling, and caching where it matters.
- The edges are the product. Timezones, a server waking up, a blocked camera, a weak connection: handling these well is what makes the app feel reliable.
- Privacy is a design problem as much as a technical one. Deciding what a pharmacist should see, or what happens to records when a patient deletes their account, shaped the screens as much as the database.
Try it
Open clinra.vercel.app and sign in with any demo account. The password for all of them is Clinra-demo-2026. The API runs on a free host that sleeps when idle, so the first visit after a quiet spell can take up to a minute while it wakes. Clinra is a portfolio project: all doctors, patients and notes are fictional, and payments are demo or Stripe test mode only.
- Patient (patient@clinra.test): home, appointments, health timeline, prescriptions.
- Doctor (doctor@clinra.test): today’s schedule, a year of stats, SOAP notes.
- Admin (admin@clinra.test): licence review, refunds, platform stats.
Thanks for watching!
Product Design & Full-Stack Development · By Sajith Kavishan
Start a project like this