Browse Templates/Telemedicine Platform

Telemedicine Platform

A modern telemedicine database schema designed for virtual healthcare platforms. Includes healthcare provider profiles with credentials, patient management, online consultation booking and tracking, e-prescription generation, and video session recording with duration logs. Ideal for building telehealth startups, virtual clinic platforms, or remote patient monitoring applications in the post-pandemic healthcare landscape.

PostgreSQL5 tablesHealthcare
healthcaretelemedicinetelehealthvideo-consultatione-prescriptionremote-care
Created with ERD Studio

About this schema

consultations is both the booking and the clinical note. It carries scheduled_at and status like an appointment, and diagnosis, notes and fee like a visit record — which works because a telehealth consultation is one event with no separate arrival. Prescriptions and the video session both hang off it.

video_sessions is deliberately separate from the consultation it belongs to. A call can drop and be rejoined, so the session carries its own room_id, started_at, ended_at and duration_seconds. Keeping those on the consultation would mean the clinical record changes every time the connection does.

patients.timezone is a column because this is the one clinical product where the two parties are routinely in different ones. Storing it with the patient means a scheduled_at held in UTC can be rendered correctly for each side, and a reminder goes out at a time that means something to the person receiving it.

Key relationships

providers / patients → consultations
One row holds the appointment and the encounter, since a telehealth visit has no separate check-in to record.
consultations → prescriptions
E-prescriptions are issued during the call and belong to it, each carrying medication, dosage, frequency and duration_days.
consultations → video_sessions
The technical record of the call, kept apart so a dropped connection does not rewrite the clinical row.
consultations.fee / providers.hourly_rate
The rate is current policy on the provider; the fee is what this consultation actually cost, frozen on the row.
providers.is_available
A simple on-call flag rather than a schedule table, which is what makes on-demand consultation possible without pre-booked slots.

Design decisions

One consultations table instead of appointment plus record

In-person care separates the booking from the encounter because a patient can fail to arrive. A video consultation has no such gap — the call either happens or the status says it did not. Merging them keeps the clinical note attached to the booking that produced it. The cost is a row that is half-empty before the call and a status column carrying more meanings than it would otherwise.

The fee is stored on the consultation

providers.hourly_rate is the current price and will change. A consultation that charged ninety dollars has to keep saying ninety after the provider raises their rate, so the fee is written onto the row at the time. This is the same reason an invoice never recalculates itself, and it is the only way a billing report run next year is still correct.

recording_url is a reference, not a file

The recording itself lives in object storage; the row holds a pointer. That keeps the database small and lets retention be enforced by deleting media without destroying the session record. It also means the pointer can outlive the file, so a null-safe read path matters — and that recordings carry consent and retention obligations the schema does not express.

Availability is a flag, not a calendar

is_available supports the on-demand model: a patient asks for a consultation now and the system finds someone online. It cannot express working hours, time off or pre-booked slots, which a scheduled-care product needs. The flag is the right floor for an urgent-care service and the first thing to replace for a booking-led one.

Tables in this template

providersProviders
9 cols
patientsPatients
8 cols
consultationsConsultations
9 cols
prescriptionsPrescriptions
8 cols
video_sessionsVideo Sessions
8 cols

Frequently asked

Why is the video session a separate table?
Because the call is a technical event with its own lifecycle. Reconnecting creates a new session for the same consultation, and the clinical record should not change just because the network did.
How are time zones handled?
Store scheduled_at in UTC and render it using patients.timezone for the patient and the provider's own zone for them. The column exists because a telehealth product cannot assume both parties share a clock.
Can a consultation have more than one prescription?
Yes — prescriptions keys on the consultation, so each medication is its own row with its own dosage and frequency. There is no prescription header here, which keeps it simpler than a paper script.
Where is the consent for recording stored?
Nowhere, and it is a required addition for real use. A recording without recorded consent is a legal problem, so a consent flag or table has to sit beside video_sessions before recording is enabled.
Is this schema enough for insurance billing?
No. consultations.fee covers what was charged, but claims need a payer, diagnosis codes and a submission status. The diagnosis column here is free text, which is readable but not codeable — ICD codes are what a claim requires.