Skip to main content

Overview

Appointments are the core entity of the Medical Appointments API. They represent scheduled meetings between patients and doctors at specific time slots. Each appointment is linked to a time block, which defines the date and time of the meeting.

Appointment Model

The appointment data structure is defined in the Prisma schema:
model Appointment {
  id          Int               @id @default(autoincrement())
  date        DateTime
  timeBlockId Int               @unique
  patientId   Int
  doctorId    Int
  status      AppointmentStatus @default(PENDING)
  notes       String?
  reason      String?
  createdAt   DateTime          @default(now())
  updatedAt   DateTime          @updatedAt

  timeBlock TimeBlock @relation(fields: [timeBlockId], references: [id])
  patient   User      @relation("PatientAppointments", fields: [patientId], references: [id])
  doctor    User      @relation("DoctorAppointments", fields: [doctorId], references: [id])

  @@unique([timeBlockId, patientId])
}

Field Descriptions

id
integer
Auto-incrementing unique identifier for the appointment.
date
DateTime
The scheduled date and time for the appointment. This is automatically set to match the time block’s startTime.
timeBlockId
integer
required
Reference to the time block being reserved. This field is unique, ensuring each time block can only have one appointment.
patientId
integer
required
Reference to the patient user booking the appointment.
doctorId
integer
required
Reference to the doctor user who will conduct the appointment.
status
AppointmentStatus
default:"PENDING"
Current status of the appointment. See Appointment Lifecycle for possible values.
notes
string
Optional notes about the appointment, typically added by the patient or doctor.
reason
string
Optional field describing the reason for the appointment.

Appointment Lifecycle

Appointments progress through different statuses defined by the AppointmentStatus enum:
enum AppointmentStatus {
  PENDING
  CONFIRMED
  CANCELLED
  COMPLETED
}

Status Definitions

1

PENDING

Initial state when an appointment is created. The appointment is awaiting confirmation from the doctor or admin.
2

CONFIRMED

The doctor or admin has confirmed the appointment. Both parties are expected to attend at the scheduled time.
3

CANCELLED

The appointment has been cancelled by either the patient, doctor, or admin. The time block may become available again.
4

COMPLETED

The appointment has occurred and is marked as completed. This is typically set after the appointment date has passed.

Relationships

Appointments connect three key entities:

Patient Relationship

Each appointment belongs to one patient. The patientId field references a User with the PATIENT role:
patient User @relation("PatientAppointments", fields: [patientId], references: [id])

Doctor Relationship

Each appointment is assigned to one doctor. The doctorId field references a User with the DOCTOR role:
doctor User @relation("DoctorAppointments", fields: [doctorId], references: [id])

Time Block Relationship

Each appointment occupies exactly one time block. The relationship is one-to-one:
timeBlock TimeBlock @relation(fields: [timeBlockId], references: [id])
The timeBlockId field has a @unique constraint, ensuring that each time block can only be reserved for one appointment.

Creating Appointments

Appointments are created through the reservation service. The process validates:
  1. Patient exists and has PATIENT role
  2. Doctor exists and has DOCTOR role
  3. Time block exists and is available
  4. No conflicting appointment exists for the time block
Example from /home/daytona/workspace/source/src/services/reservationService.js:21:
return prisma.appointment.create({
  data: {
    reason,
    notes,
    date: timeBlock.startTime,
    patient: { connect: { id: patientId } },
    doctor: { connect: { id: doctorId } },
    timeBlock: { connect: { id: timeBlockId } },
  }
});
The date field is automatically populated from the associated time block’s startTime to ensure consistency.

Constraints

Unique Constraint

The schema enforces a unique constraint on [timeBlockId, patientId]:
@@unique([timeBlockId, patientId])
This prevents a patient from booking the same time block multiple times.

Referential Integrity

All foreign key relationships use onDelete: Restrict, preventing deletion of:
  • Users who have appointments
  • Time blocks that are reserved

Querying Appointments

To retrieve appointments with full details, include related entities:
const appointment = await prisma.appointment.findUnique({
  where: { id: appointmentId },
  include: {
    patient: true,
    doctor: true,
    timeBlock: true
  }
});
This returns complete information about the appointment, including patient details, doctor details, and the specific time slot.

Build docs developers (and LLMs) love