Skip to Content

Scheduling

Dawn calculates availability from an offering and resolves the actual people, rooms, and equipment needed to deliver it. An appointment is only written after those assignments are checked again and reserved in the same database transaction.

The two levels

The configuration has two levels:

  1. Offering — a catalogue item at a site, with its booking duration, interval, notice, horizon, and operating schedule.
  2. Requirements — one or more timed steps, each requiring a quantity of candidate resources.

Resources are flat records with a person, site, room, or equipment kind. parentResourceId can express a useful two-level site relationship without creating different reservation systems for each kind.

Which schedule owns which hours

Schedules are reusable weekly windows in an IANA time zone. A dated override replaces that day’s weekly windows; an empty override closes the day.

AttachmentMeaningExample
Site resourceOpening hoursClinic is open Monday–Friday, 08:00–18:00
OfferingOperating hoursInitial consultations run Tuesday and Thursday mornings
Person, room, or equipmentResource hoursDr Meyer works Monday–Wednesday

An offering slot must fit inside both the site and offering schedules. Every assigned resource must also be free and, when it has a schedule, fit inside its own hours.

Catalogue products and services remain the commercial records. A booking_offering is the explicit bookable projection of one catalogue item at one site, so the same service can have different hours or policies at different sites. Physical products are not implicitly bookable; create an offering only when a catalogue item represents scheduled work.

Slot resolution

GET /v1/booking/offerings returns bookable choices. The client then calls GET /v1/booking/slots with an offering and a bounded time range. Each returned slot includes the exact assignments and their occupied intervals.

The engine:

  1. intersects the site and offering windows;
  2. walks the offering interval;
  3. resolves each step’s requirements against active candidates;
  4. rejects candidates outside their hours or overlapping a reservation; and
  5. returns the first complete assignment for each start time.

The API never asks a patient to select a database resource manually.

Write safety and performance

Appointment creation accepts only an assignment returned by the slot contract. The store reloads availability, verifies notice and horizon rules, compares the assignment, and writes the appointment, reservations, event, and outbox record atomically.

PostgreSQL exclusion constraints are the final concurrency authority. Active reservations for the same resource cannot overlap. Availability reads use the same tstzrange(starts_at, ends_at, '[)') expression, allowing the GiST index to serve both reads and conflict enforcement.

Availability is calculated on demand over a maximum 31-day request. Schedules, candidate resources, and reservations are loaded in batches rather than once per candidate or slot. Add caching or materialized availability only after measuring a real workload; the reservation constraint remains authoritative either way.

Last updated on