Skip to content

Appointments

A booked consultation between a patient and a specialist — from the moment of booking through the end of the session, with forms, video, and documentation all tied together.


What this enables

  • A patient books an appointment through the public booking page (no account required at booking time)
  • The specialist or admin onboards the patient afterward — creating their account and generating the required forms
  • The appointment moves through a clear lifecycle: booked → upcoming → confirmed → in-progress → done
  • A video call room opens automatically when the appointment is onboarded — no manual setup
  • Patients and specialists can review and complete all forms tied to the appointment in one place
  • After completion, patients can leave a star rating — low ratings trigger an alert for the admin to review
  • Appointment history is permanent and soft-deletable only — clinical records are never erased

How it works

The two-phase booking model

Booking and patient onboarding are intentionally separate:

Phase 1 — Public booking (no login required)
  Patient picks a time and fills in name, email, phone
  → patient_persons record created with name and phone
  → Appointment created with status: booked
  → contact_email stored for confirmation notification

Phase 2 — Onboarding (admin or specialist)
  Staff opens the booking and registers the patient
  → Clerk account created (if not existing)
  → patient_persons.user_id linked to the new account
  → Patient record (org-patient link) created
  → Required forms generated automatically, pre-filled from patient_persons profile
  → Video room created
  → Status: booked → upcoming

This design lets clinics accept bookings from people who don't yet have an account, which is the most common real-world situation.

Lifecycle at a glance

StatusWhat it means
bookedBooking confirmed, contact info captured, no patient account yet
upcomingPatient onboarded, forms ready, video room active
confirmedPatient confirmed they'll attend
inprogressSpecialist has opened the session
doneSession complete, forms signed
cancelledAppointment cancelled
noshowPatient didn't attend

Forms on appointments

Forms come from two sources and are merged automatically:

  1. Service forms — defined on the service being booked (intrinsic to the procedure)
  2. Calendar forms — additional forms specific to the booking channel (e.g., a promotional disclaimer)

Form types that can exist on an appointment: surveys, disclaimers, parameters, analysis, advice, report, prescription.

Reviews

After an appointment is done, the patient can submit a rating (1–5 stars) and optional comment. Ratings below 5 trigger an alert in the org dashboard. Admins acknowledge the alert after reviewing.


Technical Reference

Everything below is intended for developers.

Key schema additions

Service & Calendar references:

  • service_id (UUID) — always set; defines what was booked
  • calendar_id (UUID, nullable) — which calendar was used (NULL for direct registrations)

Contact info (pre-onboarding):

  • contact_email — stored for booking confirmation emails before the patient has an account
  • booking_client_id — anonymous client ID used for rate limiting
  • contact_name and contact_phone are not stored here — they live on patient_persons, created at booking time

Add-ons:

  • additional_service_ids (UUID[]) — services added during appointment
  • additional_product_ids (UUID[]) — physical products sold

Multi-session plans:

  • patient_service_plan_id (bigint, nullable) — links to enrolled service plan
  • plan_session_number (int) — "Session 3 of 10"

Status machine

State transitions have validation and side effects:

TransitionSide effects
bookedupcomingCreate patient + user (if new), generate forms, create Daily.co room
upcomingconfirmedNotify specialist
any → cancelled / noshowDelete Daily.co room
reinstated from cancelled/noshowRecreate Daily.co room

See Lifecycle → for the full state machine with all validations.

Videocall integration

  • Room name format: restartix-{orgID}-{appointmentID}
  • Expires at appointment.ended_at
  • Deleted automatically on cancellation or noshow
  • Recreated on reinstatement

See Videocall → for Daily.co integration details.

Calendar views

  • Month view: aggregate appointment counts per day
  • Week view: full appointment details with time slots
  • Filtering: by specialist, status, date range
  • RLS applied: patients see own appointments, specialists see assigned, admins see all

Forms generation on onboarding

1. Collect service_forms WHERE service_id = appointment.service_id
2. Collect calendar_forms WHERE calendar_id = appointment.calendar_id
3. Merge and deduplicate
4. Generate form instances with snapshotted fields and auto-fill from patient profile

Patient identity on appointments

Appointments reference patient_person_id (not user_id). This supports:

  • Patients without accounts — a daughter booking for her elderly father who has no login
  • Family management — one login managing appointments for multiple people

The RLS helper current_user_patient_person_ids() returns all patient person IDs the current user can act on behalf of (themselves + managed dependents), so patients and their managers can see the appointments they're involved in.

Access control

Patients can only see their own appointments (and those of anyone they manage). Specialists see appointments assigned to them. Admins see all appointments in their org. Enforced by RLS.