Use case
Some properties need to review a guest's request before accepting payment and creating a reservation. The guest selects dates and an offer, submits contact/application information, and receives a request acknowledgement. Staff then reviews, approves, or rejects it. Approval revalidates availability and price; only successful payment creates the reservation.
This differs from instant booking and from demand capture after a sellout. It should be an opt-in property mode, while existing booking-engine behavior remains unchanged by default.
Current HAIP primitives
At baseline 922bea056e89f75cc476c327c040400767c0446b:
- the booking engine creates a reservation through the instant booking path;
waitlist_entries is non-inventory-deducting and already stores dates, occupancy, room/rate references, guest contact details, and active -> offered -> converted/cancelled/expired state;
WaitlistService.convert() checks availability and returns needsBooking: true, but does not perform a public request workflow or a payment-safe conversion;
- waitlist routes are staff-authenticated and there is no request-specific public management token.
Relevant code:
packages/database/src/schema/demand-capture.ts
apps/api/src/modules/waitlist/waitlist.service.ts
apps/api/src/modules/waitlist/waitlist.controller.ts
apps/api/src/modules/booking-engine/booking-engine.service.ts
Required invariants
- Request mode is property-configurable; existing properties continue using instant booking.
- Submitting a request never creates a reservation or reduces availability.
- A public booking key may submit a request but cannot enumerate requests.
- Public follow-up access is scoped to one high-entropy request token stored only as a hash.
- Staff review, rejection, withdrawal, and expiry are explicit and auditable states.
- Approval recalculates the authoritative quote and rechecks availability.
- A failed or incomplete payment creates no reservation.
- Retrying approval cannot create a second payment or reservation.
- All reads and transitions remain property-scoped.
- Existing instant-booking API and widget behavior remain backward compatible.
Domain-model decision requested
Should this workflow:
- generalize
waitlist_entries into a broader non-deducting demand/request aggregate; or
- introduce a separate
booking_requests aggregate and leave waitlist semantics focused on unavailable demand?
A booking request needs review/payment states, an immutable quote snapshot, structured application data, consent metadata, public token scope, and conversion identifiers. Those requirements may make a separate aggregate safer, but we do not want to duplicate an existing HAIP domain concept without maintainer direction.
Proposed contribution boundaries after approval
PR A — domain and persistence
- Add the approved aggregate/state machine and property
bookingMode: instant | request configuration.
- Add tenant-scope, transition, and non-deducting behavior tests.
- No Stripe or widget behavior in this PR.
PR B — submission and review
- Add public submit/read/withdraw routes scoped by booking key plus request token.
- Add staff list/review/reject routes and the minimal dashboard queue.
- Switch the public widget's completion behavior only when request mode is enabled.
- No card storage or approval-time payment in this PR.
Later payment PRs
- Add SetupIntent/off-session consent, idempotent approval-time capture, and SCA recovery behind the accepted request model.
- Never deploy an incomplete payment sequence as a production request flow.
Questions for maintainers
- Is waitlist the intended aggregate for this use case, or should request-first booking be separate?
- Which HAIP knowledge-base sections define request/option bookings and conversion?
- Should a request be allowed when availability is currently zero, or is that exclusively waitlist behavior?
- Which existing staff permissions should govern review and approval?
- Where should immutable quote/application snapshots live under HAIP's retention model?
- Is
bookingMode the preferred property-level switch, or should request behavior attach to an offer/rate plan?
We can provide one focused, test-backed PR at a time after the aggregate boundary is confirmed.
Use case
Some properties need to review a guest's request before accepting payment and creating a reservation. The guest selects dates and an offer, submits contact/application information, and receives a request acknowledgement. Staff then reviews, approves, or rejects it. Approval revalidates availability and price; only successful payment creates the reservation.
This differs from instant booking and from demand capture after a sellout. It should be an opt-in property mode, while existing booking-engine behavior remains unchanged by default.
Current HAIP primitives
At baseline
922bea056e89f75cc476c327c040400767c0446b:waitlist_entriesis non-inventory-deducting and already stores dates, occupancy, room/rate references, guest contact details, andactive -> offered -> converted/cancelled/expiredstate;WaitlistService.convert()checks availability and returnsneedsBooking: true, but does not perform a public request workflow or a payment-safe conversion;Relevant code:
packages/database/src/schema/demand-capture.tsapps/api/src/modules/waitlist/waitlist.service.tsapps/api/src/modules/waitlist/waitlist.controller.tsapps/api/src/modules/booking-engine/booking-engine.service.tsRequired invariants
Domain-model decision requested
Should this workflow:
waitlist_entriesinto a broader non-deducting demand/request aggregate; orbooking_requestsaggregate and leave waitlist semantics focused on unavailable demand?A booking request needs review/payment states, an immutable quote snapshot, structured application data, consent metadata, public token scope, and conversion identifiers. Those requirements may make a separate aggregate safer, but we do not want to duplicate an existing HAIP domain concept without maintainer direction.
Proposed contribution boundaries after approval
PR A — domain and persistence
bookingMode: instant | requestconfiguration.PR B — submission and review
Later payment PRs
Questions for maintainers
bookingModethe preferred property-level switch, or should request behavior attach to an offer/rate plan?We can provide one focused, test-backed PR at a time after the aggregate boundary is confirmed.