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:
- Offering — a catalogue item at a site, with its booking duration, interval, notice, horizon, and operating schedule.
- 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.
| Attachment | Meaning | Example |
|---|---|---|
| Site resource | Opening hours | Clinic is open Monday–Friday, 08:00–18:00 |
| Offering | Operating hours | Initial consultations run Tuesday and Thursday mornings |
| Person, room, or equipment | Resource hours | Dr 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:
- intersects the site and offering windows;
- walks the offering interval;
- resolves each step’s requirements against active candidates;
- rejects candidates outside their hours or overlapping a reservation; and
- 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.