Appointment Domain - Workflow Narrative
A conversational guide to understanding scheduling workflows
What is the Appointment Domain?
The Appointment domain handles everything related to scheduling patient visits. It's the bridge between patient intent ("I need to see a doctor") and clinical reality (an actual encounter happening).
Scheduling in a healthcare setting is more complex than booking a restaurant reservation. You need to match patients with appropriate practitioners, check availability across clinics, respect time slot constraints, and handle the full lifecycle from booking through completion or cancellation.
The Scheduling Ecosystem
Three Key Concepts
The appointment system works with three interrelated concepts:
Practitioners have schedules attached to them. A schedule defines which days and times a practitioner is available at a given clinic. Dr. Smith might work Mondays and Wednesdays at the Main Clinic, and Tuesdays at the Downtown Clinic.
Time Slots are the granular booking units within a schedule. If Dr. Smith is available 9 AM to 5 PM on Mondays, that might be divided into 30-minute slots. Each slot has a start time, end time, and maximum booking capacity.
Clinic Assignments connect practitioners to clinics. A practitioner might be assigned to multiple clinics with different schedules at each.
Creating an Appointment
The Frontend Journey
A typical booking flow involves several steps. The user selects a practitioner (or searches by specialty), picks a date, sees available time slots, and confirms the booking.
Behind the API
When the booking is confirmed, a POST request hits AppointmentService.create_appointment(). The service receives appointment data including patient ID, practitioner ID, clinic ID, date, time, duration, and appointment type.
Validation Sequence
Before creating anything, the service runs validations:
- Patient Check: Does the patient exist and belong to this organization?
- Practitioner Check: Does the practitioner exist and are they available?
- Clinic Check: Is this practitioner assigned to this clinic?
- Time Slot Check: Is the requested time within the practitioner's schedule?
- Conflict Check: Is there an existing appointment at this time?
- Buffer Time Check: Does organization config require buffer time between appointments?
If any validation fails, the service returns an appropriate error explaining what went wrong.
The Creation
Once validated, the appointment is created with:
statusset to "booked"patient_idlinking to the patientpractitioner_idlinking to the providerclinic_idlinking to the locationappointment_datewith the scheduled timedurationin minutesappointment_type(follow-up, new patient, procedure, etc.)
Activity Event
An APPOINTMENT_CREATED activity event is fired. This includes details about who the appointment is with and when. If notifications are configured, the practitioner and potentially patient notification systems are triggered.
Cache Invalidation
The appointment cache for this practitioner and clinic is invalidated. The next availability check will reflect the newly booked slot.
Availability Checking
How Slots Are Calculated
When a user wants to see available times, the system calculates availability dynamically.
The AppointmentService.get_practitioner_slots() method works like this:
- Get the practitioner's schedule for the requested date
- Generate all possible time slots from that schedule
- Query existing appointments for that practitioner on that date
- Subtract booked slots from available slots
- Return the remaining available times
Buffer Time
Organizations can configure required buffer time between appointments. If a 15-minute buffer is set, a 9:00-9:30 appointment means the next slot can't start until 9:45.
This buffer time is cached per organization because it rarely changes and is checked frequently.
Slot Capacity
Some time slots allow multiple concurrent appointments. A group therapy session might allow 10 patients in the same slot, while individual consultations are one-at-a-time. The availability calculation respects this capacity setting.
Date Range Queries
For calendar views, get_practitioner_slots_range() returns availability across multiple days. This is optimized to batch-fetch appointments and calculate availability day by day.
Appointment Status Workflow
Status Progression
Appointments move through statuses:
- pending - Appointment requested but not confirmed
- booked - Confirmed and scheduled
- confirmed - Patient has confirmed they'll attend
- arrived - Patient has checked in
- in-progress - Appointment is happening
- completed - Appointment finished successfully
- cancelled - Appointment was cancelled
- no-show - Patient didn't show up
Status Transitions
The update_appointment_status() method handles status changes. Each transition might trigger different actions:
- booked → cancelled: The slot becomes available again
- booked → arrived: Patient check-in recorded
- arrived → in-progress: Often triggers encounter creation
- in-progress → completed: Encounter should be finalized
Status Change Events
Status changes trigger activity events. APPOINTMENT_STATUS_CHANGED includes the old status, new status, and reason if provided. This creates an audit trail and can trigger notifications.
For certain status changes like cancellations, notifications are especially important - the practitioner needs to know their schedule changed.
Updating Appointments
Rescheduling
The most common update is rescheduling - changing the date and time. The update_appointment() method handles this.
Rescheduling triggers the same validation as creation. The new time slot must be available, within the practitioner's schedule, and not conflicting with other appointments.
Other Updates
Beyond rescheduling, appointments can be updated to:
- Change the appointment type
- Add or modify notes
- Change the assigned practitioner (if the patient agrees)
- Update the duration
Conflict Prevention
If you try to reschedule to a time that's already booked, the system rejects the change. This prevents double-booking that would waste the practitioner's time.
Cancelling Appointments
The Cancellation Flow
Cancellations are a special kind of update. When update_appointment_status() is called with status "cancelled", additional logic kicks in.
The cancellation reason is captured - was this patient-initiated? Practice-initiated? Due to emergency? This data is valuable for analytics and understanding no-show patterns.
Slot Recovery
When an appointment is cancelled, the time slot becomes available again. Other patients can now book that time. This happens automatically as a result of the appointment status change.
Notifications
Cancellation almost always triggers notifications. The practitioner needs to know. The patient should receive confirmation. Care coordinators might need to help reschedule.
The activity event for cancellation has higher priority than normal appointment events.
Daily and Upcoming Views
Today's Appointments
The get_today_appointments() method returns all appointments for the current date. This powers the daily schedule view that practitioners open each morning.
Results are ordered by time, with patient names, appointment types, and statuses included. Eager loading brings in patient and clinic data efficiently.
Upcoming Appointments
get_upcoming_appointments() looks ahead over a date range. It supports filtering by practitioner (show me my schedule) or by patient (show me all this patient's future appointments).
For dashboard widgets, this supports optional summary statistics - counts by status, by appointment type, etc.
Performance
These queries hit frequently and need to be fast. Indexes on appointment_date, practitioner_id, and status ensure quick responses even with many appointments in the system.
Statistics and Analytics
Appointment Statistics
The get_appointment_stats() method aggregates appointment data for dashboards. Using database-level counting, it provides:
- Total appointments in period
- Breakdown by status (booked, completed, cancelled, no-show)
- Breakdown by appointment type
- Average appointments per day
- No-show rate percentage
These statistics help practices understand their scheduling patterns and identify problems (like high no-show rates).
Practitioner-Specific Stats
When a practitioner ID is provided, statistics are scoped to that practitioner. This lets individual providers see their own patterns - how many patients are they seeing, what's their completion rate, when are their busiest times?
Clinic-Based Availability
Multi-Clinic Scheduling
Large organizations have multiple clinics. The availability system handles this by querying clinic assignments.
get_available_clinics() returns which clinics have availability on a given date. It considers all practitioners assigned to each clinic and their schedules.
Clinic Slots
get_clinic_slots_range() returns availability for a specific clinic across a date range. This is useful for patients who want to visit a particular location regardless of provider.
The system aggregates availability across all practitioners at that clinic, showing when any provider is available.
The Appointment-Encounter Connection
From Appointment to Encounter
Many encounters originate from appointments. When a patient arrives for their scheduled visit, the workflow often transitions from appointment to encounter.
This can happen automatically. When appointment status changes to "arrived" or "in-progress", an encounter might be created with the appointment_id linking them.
Alternatively, staff might manually create an encounter and link it to the appointment.
Data Handoff
The appointment provides initial context for the encounter:
- Patient ID carries over
- Practitioner ID carries over
- Appointment date becomes encounter date
- Appointment type might influence encounter type
Status Coordination
When an encounter is finalized, the linked appointment should be marked completed. This bidirectional status management ensures consistency.
Key Takeaways
-
Scheduling is stateful - appointments move through a defined status progression
-
Availability is calculated - slots are derived from schedules minus bookings
-
Validation is thorough - multiple checks prevent invalid bookings
-
Multi-clinic support - practitioners can work at multiple locations
-
Buffer time is configurable - organizations can enforce spacing between appointments
-
Events drive notifications - status changes trigger activity events
-
Encounter connection - appointments often transition to clinical encounters
Next: Read about the Billing Domain to understand financial workflows