ADR-009: BookingConfirmed Trigger Condition โ DEPOSIT_PAID โ
Status: โ Approved โ 2026-04-10 Impacts:
schema-commerce.md(Hasura Event Trigger definition),level-3-domain-1-cross-context-event-contracts.md(ยง4 delivery contracts)
Context โ
The Booking lifecycle includes two payment confirmation states: DEPOSIT_PAID (deposit received) and FULLY_PAID (final payment complete). The domain model says the CostingSheet locks "when the operator confirms the first booking" โ but "confirmed" remained ambiguous and could mean either state.
The costing-pricing-separation ADR establishes that CostingSheet locking freezes costs (not prices). PriceMatrix versioning manages prices independently. However, locking costs early ensures the Soll baseline (cost forecast) stays stable for financial reconciliation.
Decision โ
DEPOSIT_PAID triggers the BookingConfirmed domain event for CostingSheet cost-locking purposes.
A deposit is a legal commitment to the published price in DACH contract law (ยง 651a BGB for package travel). Locking costs at deposit time ensures:
- The first commercial commitment establishes the Soll baseline
- The system freezes the cost forecast used for Soll/Ist reconciliation to the state at first commercial obligation
- No ambiguity in the event trigger โ
DEPOSIT_PAIDis a single, unambiguous state transition
Consequences โ
Positive:
BookingConfirmedfires oncommerce.bookings.statusโDEPOSIT_PAIDas a Hasura Event Trigger- The system disables cost editing on the CostingSheet after lock โ this is the Soll baseline
- Clear legal alignment with ยง 651a BGB contract law
Neutral:
- PriceMatrix versioning remains unaffected โ the operator can still publish new price versions after cost lock. They derive from the locked cost base, which is now stable.
- Existing bookings bind to their
price_matrix_idat checkout (costing-pricing-separation ADR ยง3) โ PriceMatrix versioning handles price guarantees, not CostingSheet locking.
Rejected alternative:
FULLY_PAIDas trigger: would allow cost edits during the deposit-to-full-payment window, but creates Soll instability and is legally questionable (deposit = contractual commitment under German package travel law).
Scope & Legal Contingency โ
This ADR defends one specific downstream effect: CostingSheet cost-locking on the operator-side Soll baseline. ยง 651a BGB provides the legal anchor for that โ the deposit binds the operator to the published price, so the cost forecast must be frozen at the moment of first commercial obligation.
It does not defend, and does not foreclose decisions about, the other downstream effects that commerce.bookings.status โ DEPOSIT_PAID currently triggers in the model:
| Downstream effect | Defended here? | Open legal dependency |
|---|---|---|
CostingSheet โ LOCKED | โ Yes (ยง 651a BGB) | โ |
FinancialLedger auto-creation | Not addressed (accounting fact, orthogonal to consumer law) | โ |
BookingConfirmed event โ confirmation PDF, Formblatt delivery, ticket issuance | โ No | Widerrufsrecht / ยง 312g Abs. 2 Nr. 9 BGB โ if the package-travel exemption does not apply, a 14-day cooling-off period sits between deposit and binding confirmation. See PRODUCT_payments-and-billing.md ยง4. |
| Deposit collection at this moment | โ No | ยง 651t BGB (Reisepreisabsicherung) โ for Pauschalreisen, Sicherungsschein delivery may be required before deposit may be collected. See PRODUCT_payments-and-billing.md ยง4. |
| Mollie marketplace deposit flow | โ No | PSD2 / ZAG (Zahlungsdiensteaufsichtsgesetz) โ whether Busflow may hold operator funds at all under Mollie's marketplace licence. See PRODUCT_payments-and-billing.md ยง4. |
Decoupling principle โ
The model treats each downstream effect as an independent concern consumed off the same trigger today, not as a single atomic transition. Concretely:
- The
BookingConfirmeddomain event is the integration contract for cost-lock, CRM sync, and customer-facing confirmation โ but its firing condition is a separate decision from theDEPOSIT_PAIDstate itself. - If legal review on Widerrufsrecht (ยง 312g) forces a "confirmed but withdrawable" sub-state,
BookingConfirmed(and ticketing, and confirmation messaging) can be re-bound to a later trigger (e.g.,DEPOSIT_PAID && withdrawal_window_expires_at < now()) without touching the cost-lock semantics this ADR establishes. - If ยง 651t forces Sicherungsschein-before-deposit ordering for Pauschalreisen, the constraint is enforced upstream of
DEPOSIT_PAID(insubmitCheckout/ Mollie deposit-creation), not by mutating this ADR.
This ADR's status remains Approved for cost-locking. The fan-out of other consequences from the same trigger remains contingent on resolution of the items listed above.