Skip to content

Three cleaning touchpoints

The cleaning workflow keys everything off the departure date (not arrival) because cleaning happens after the guest leaves. Three touchpoints, designed to escalate progressively as departure approaches.

Touchpoint 1: Heads-up

Fires immediately on workflow spawn (runCleaningHeadsUp in booking-flag.ts).

Purpose: tell the cleaner a booking exists so they can plan.

Send rules:

  • Email always sent
  • SMS only if days-to-arrival < 10 days
  • Last-minute (<2 days): aggressive — both channels + escalation watch

Idempotent: skips if cleanings.heads_up_sent_at is set AND arrival/departure dates haven’t changed since the prior send.

Body:

New booking at {Property}. Stay: {arrival} → {departure}. Next arrival on this unit: {next_arrival} OR No next booking yet. Cleaning needed after guest departs {departure}. Tap to confirm: {clean-ack URL}

Touchpoint 2: T-2 reminder

Fires at departure − 2 days, 16:00Z (10am MT). Email + SMS always.

Purpose: 2 days before the cleaner needs to show up — reminder that this booking is coming up.

Skip rule: 5-day-recent-ack rule. If the cleaner ack’d any prior touchpoint within 5 days, skip — they’re aware.

Touchpoint 3: Time-commit

Fires at departure-eve, 16:00Z (10am MT).

Purpose: get a specific time commitment from the cleaner — what time will the unit be ready?

Two variants based on turnover_days:

  • Same-day turnover (next guest arrives the same day): show a time-picker on /clean-ack with 5 options (12pm / 1pm / 2pm / 3pm / 4pm). The cleaner must commit to a specific time so Bill can manage guest expectations.
  • Gap-day (1+ days before next guest): show a simple “I’ll do it” confirm button. Time pressure is lower.

Skip rule: same 5-day-recent-ack.

State columns

All in the cleanings D1 table:

ColumnSet by
heads_up_sent_atWorkflow on heads-up send
heads_up_ack_at/clean-ack POST action=confirm-heads-up
t2_reminder_sent_atWorkflow on T-2 send
t2_reminder_ack_at/clean-ack POST action=confirm-t2
time_commit_sent_atWorkflow on time-commit send
eta_at/clean-ack POST action=ack (same-day picker)
ack_at/clean-ack POST action=ack or commit-flexible
complete_at/clean-ack POST action=complete
issue_summary/forms/clean POST

Feature flags

  • cleaner-sms — currently shadow_mode=1. SMSes route to Bill instead of the cleaner with a [shadow → name phone] prefix. Flip to 0 once cleaners are ready to receive directly.
  • cleaner-email — same pattern; redirects to Bill’s email.

These let Bill see exactly what each cleaner would receive before flipping live.

Source

  • src/workflows/booking-flag.tsrunCleaning* methods
  • src/lib/cleanings.ts — D1 CRUD
  • src/routes/clean-ack.ts — the 6-state page + POST handlers
  • Tests: test/routes/clean-ack.test.ts (39 cases)