Example: Booking System
Availability, reservations, reminders, and no double-bookings — a complete scheduling app with the flow that makes conflicts impossible.
Booking looks simple until two people grab the same slot at once. This example shows the model, the conflict-proof reservation flow, and the reminder machinery.
Data Model
- resources — what gets booked (rooms, tables, staff): name, capacity, opening hours, timezone.
- bookings — one document per reservation:
Booking Document
{
"_meta": {},
"customer_guid": "b9ee6a631b24e78d1aa48aef0dc067fff7bfbacd24a56ef4ed1f08e537d48b6bd02",
"customer_name": "sami b",
"end": 1782364800,
"reminder_sent": false,
"resource_guid": "e01ff8643394371a8544d2c9f8a1b3e5d70892c4f6a0b8d1e3f5a7c9b2d4e6f8a0b2",
"resource_name": "meeting room 2",
"start": 1782361200,
"status": "confirmed"
}Resource and customer are denormalized onto the booking — calendar views show names without joins (see Storage Examples).
Checking Availability
- Query the resource's bookings overlapping the requested window:
start < requested_endANDend > requested_start— two range filters on the same query viaquery_bool_range_field. - No overlaps → slot is free. Overlaps → return the conflicting bookings so the UI can show why.
- Generate the day's available slots from opening hours minus confirmed bookings, in the function — not in the page.
No Double-Booking
- The reservation flow first re-checks overlap (never trust the page's earlier check).
- Then it creates the booking with a status transition inside one mutation set — mutations process sequentially per document, so the last check and the write can't interleave (see mutations).
- On conflict: reply 409 with the overlapping booking — see error conventions.
- Cancellation is a status change to
cancelled, never a delete — the audit trail and no-show stats survive.
Reminders
- A
schedule_repeating_eventruns hourly: query confirmed bookings starting within the next 24h wherereminder_sent = false. - Send each with the email pattern from Email System Setup, then set
reminder_sent = true— idempotent even if the run repeats. - Customers manage their own bookings with
user_current→ term query oncustomer_guid.
