Skip to content

Booking

A lightweight, concurrency-safe resource booking and availability API for Drupal 11.

Booking is the missing capacity-safe layer for reservations. It gives any module a small set of entities and a service API to:

  • define resources (rooms, equipment, events, …);
  • publish availability slots, each split into one or more categories (the "sub-slots": Adult / Child / VIP, Standard / Premium, …) with their own capacity;
  • take bookings that reserve capacity without ever overbooking - even under concurrent requests - using a hold → confirm lifecycle with automatic expiry.

Why it exists

Most Drupal booking solutions count rows to decide availability, which races under load and double-books the last place. Booking treats per-category capacity as a first-class, concurrency-safe concern: every hold checks and reserves capacity atomically inside a database transaction with a row lock.

flowchart LR
    subgraph Consumers
        UI[yoyaku_calendar / booking_webform]
        WF[Orchestra workflow]
        PAY[Payment / Commerce]
    end
    Consumers -->|hold / confirm / release| API[BookingManager API]
    API -->|FOR UPDATE txn| DB[(Capacity = Category)]
    API -->|dispatches| EV[Lifecycle events]
    EV --> Consumers

What it is not

  • Not a UI builder - the core is headless. Calendars and forms live in submodules.
  • Not a payment system - price, deposits, currency and tax are consumer concerns. The engine stays money-agnostic; see Deposits and payment.
  • Not a scheduler - recurrence is an optional layer that materialises concrete slots; see Recurrence.

Quick mental model

Concept One-liner
Resource A bookable thing, with defaults and a booking window.
Slot A concrete time window of a resource.
Category A named capacity pool inside a slot. Capacity lives here.
Booking Consumes capacity on a category. held → confirmed, or freed.
Tenant The realm a row belongs to (default: default).

Requirements

  • Drupal ^11.3
  • PHP >=8.3
  • drupal:options (core)

Next steps