The booking workflow was a per-resource setting (workflow, workflow_start, auto_confirm), which makes a multi-resource order ambiguous: an order can group bookings from several resources but runs one workflow, and the starter silently used the first line's resource. This moves the workflow to an order-level profile and starts it explicitly.
A new yoyaku_workflow_profile config entity holds the workflow and its auto-confirm policy, with a CRUD UI. The site default, a tenant, and a resource type each reference a profile by id; WorkflowProfileResolver resolves it type override, then tenant default, then site default.
The workflow no longer auto-starts on an order state. The payment states (locked, placed) are downstream of the workflow, so starting on them is circular, and a free order never locks. Instead WorkflowStarter::start($order) is called explicitly by a registration/checkout surface (the calendar Book button, later the cart Checkout) or an operator, and is idempotent. workflow_start and the WorkflowStartRequired constraint are removed.
One profile per order is enforced by a SingleWorkflowProfilePerOrder constraint on the transaction. The resource's workflow base fields are removed. Kernel-tested: the resolution chain and the full workflow lifecycle on the new model.
Groundwork for the multi-event booking cart. Follow-ups: tenant and resource-type profile pickers (their config entities have no admin forms yet), rejecting a cross-profile hold at add-to-basket, and moving the starter out of the EventSubscriber namespace.
Issue fork yoyaku-3611917
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedOpened merge request !52 against 1.x. Kernel-tested (15 tests, 242 assertions: the type/tenant/site resolution chain, and the full workflow lifecycle driven by an explicit start on the new profile model). Verified loading on a running site. Known follow-ups noted in the summary (tenant/resource-type profile pickers, add-to-basket constraint enforcement, starter namespace tidy).
Comment #5
mably commented