Daily flag-sync cron
DailyFlagSyncWorkflow (src/workflows/daily-flag-sync.ts) runs once
daily at 06:00Z (midnight MT). It’s the cold-start mechanism — if a
booking exists in Beds24 but has no BookingFlagWorkflow instance,
this cron spawns one.
What it does
- Read feature flag — skips if
daily-flag-sync.enabled=0 - Fetch bookings via Beds24 v2 API:
- Default horizon: 365 days forward
- Filter:
status IN (confirmed, new, request)
- For each booking: call
ensureBookingFlagWorkflow(env, b.id, { force: false })— spawns a new workflow only if none exists OR the existing one is errored/terminated. Healthy workflows (queued / running / paused / waiting / complete) are left alone so the cron doesn’t tear down + recreate every active booking every morning.
Why we still need it
Most new bookings arrive via the Beds24 booking-event push webhook, which spawns the workflow immediately. The cron is the safety net for:
- Push webhook misconfiguration — if the BA panel push setting gets disabled, this cron picks up new bookings within 24h
- Stale workflows — if a workflow instance was terminated without a respawn
- Recovery after outages — after a service blip, the cron re-establishes correct state next morning
Idempotency
ensureBookingFlagWorkflow terminates + respawns when force=true
(webhook + admin callers). All workflow phases handle respawn cleanly
via D1 / infoItem state checks before acting. With force=false (this
cron’s setting), healthy workflows are skipped so daily-sync only does
work when a workflow is actually missing or broken.
Manual one-shot
POST /admin/backfillSpawns the same workflow with triggeredBy=backfill, horizonDays=365.
Useful after schema changes or to force a full re-sync.
Shadow mode
daily-flag-sync.shadow_mode has been 0 (real) since Phase 2 went
live. Flipping to 1 causes the cron to write predictions but skip
the workflow spawns — emergency brake.