P5.M4c — early check-in workflow
runEarlyCheckinAvailabilityCheck in src/workflows/booking-flag.ts.
Fires at arrival − 2 days, 15:00Z (9am MT).
Decision tree
- Read pre-checkin submission. Skip if:
- No row OR
addon_early_checkin=0 - No
stripe_payment_intent_id - Already
payment_captured_atORpayment_status=canceled
- No row OR
- Combined add-on case (early + late both selected): send Bill a “combined-addon deferral” email and skip — M4d will handle both decisions when it fires at D-3.
- Back-to-back check —
fetchBookings(roomId, departureFrom:arrival, departureTo:arrival)— any booking departing on this booking’s arrival day? If yes:- Call
cancelPaymentIntent(release the auth) - Update
payment_status=canceled - Call
notifyGuestAddonDeclinedwith reason “back-to-back booking on your arrival day”
- Call
- No back-to-back: email Bill with capture / decline action URLs. Bill clicks → admin endpoints fire.
Admin endpoints
GET /admin/booking/{id}/addon-capture?addon=early_checkin:
- Authenticate (admin bearer or basic)
- Read pre-checkin submission
- If already captured OR cancelled → return early
capturePaymentIntent(intent_id)- Set
payment_status=succeeded,payment_captured_at=now - P5.M10 BA state mirror: also set Beds24 flag
ffaaaa“early check-in paid” +EarlyCheckIn=Yinfo code notifyGuestAddonConfirmed(email + SMS + Beds24 thread, with amount shown)
GET /admin/booking/{id}/addon-decline?addon=early_checkin&reason=...:
- Same auth + state checks
cancelPaymentIntent- Set
payment_status=canceled notifyGuestAddonDeclinedwith the supplied reason (defaults to “host declined”)
GET (not POST) so the email link works directly in the browser.
Email Bill receives
Subject: Decide: early check-in for {Property} (booking {id})
Body has booking info + two button-styled URLs:
- Green “Capture payment” → captures
- Red “Decline” → cancels
Guest notifications (M4e)
notifyGuestAddonConfirmed / notifyGuestAddonDeclined in
src/lib/addon-notify.ts. Dispatches across 3 channels:
- Mailgun email — always (if booking has email)
- Twilio SMS — only if booking has phone
- Beds24 thread message — always (for record + OTA routing)
BA AA mapping
| BA AA | Status |
|---|---|
| 287537 (CC lock-box) | T-0 in pre-arrival workflow |
| 287540 (SS lock-box) | T-0 in pre-arrival workflow |
| 290167 (TP arrival info) | T-0 in pre-arrival workflow |
| 289186 (Early check-in paid) | M4c capture endpoint sets BA flag + info code |
Source
src/workflows/booking-flag.ts—runEarlyCheckinAvailabilityChecksrc/routes/admin.ts—handleAddonCapture,handleAddonDeclinesrc/lib/addon-notify.ts— guest notify helpers- Tests:
test/workflows/addon-workflows.test.ts(5 cases for M4c)