Every held booking carries its own hold_expires, stamped as the line is created and never revisited. A basket built over several minutes therefore does not expire, it crumbles: the line held first lapses while its siblings survive, and the order is left holding fewer lines than the booker chose. A basket whose lines come from resources with different hold_ttl values carries several windows at once.
The module already assumes a single basket-wide deadline everywhere except in storage. HeldCookie::value() collapses the lines to their earliest deadline for the client, and the calendar reads it as one number. WorkflowHoldOwnership exists only to stop a line added mid-run carrying a clock its siblings do not have, which its own docblock describes as an order that behaves two ways at the same moment.
Proposed: the hold deadline moves to yoyaku_transaction, and holding a line outside a transaction stops being possible. One clock per order, re-armed as the basket changes and bounded by a total lifetime. Its length is configured per booking channel, per tenant, then site wide, so BookingResource::hold_ttl goes; an empty value at any level means holds never lapse, which is how manual approval is expressed.
The example workflow stops taking the clock away. yoyaku_suspend_holds and WorkflowHoldOwnership are removed, the form step derives its deadline from the basket, and expiry becomes a signal the step routes on rather than a teardown hidden in the reconciler. Every timeout converges on unlock and expire; only an explicit cancellation reaches the cancel step.
Pre-1.0, so no update hooks: reinstall is the upgrade path.
Issue fork yoyaku-3615440
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 commentedComment #5
mably commented