MIGRATION_PLAN — bff-tenant-booking-service
Sibling: SERVICE_OVERVIEW · DATA_MODEL · DEPLOYMENT_TOPOLOGY
This BFF is Phase 1 greenfield — no legacy bff-tenant-booking-service predecessor exists. There is, however, a tenant-onboarding ramp: each tenant moves from a legacy booking surface (third-party plugin, prior PMS booking widget, manual phone bookings) onto this BFF. This document treats per-tenant onboarding as a migration.
1. Scope
| In | Out |
|---|---|
| Per-tenant cutover from legacy booking widget to this BFF | Domain data migration (handled by reservation-service, pricing-service, inventory-service migrations) |
| Custom-domain provisioning + DNS cutover | Tenant onboarding lifecycle (handled by tenant-service) |
| Theme configuration cutover | Theme migration (handled by theme-config-service) |
| Telemetry pipeline activation | Search index population (handled by search-aggregation-service) |
| Booking funnel template + flow config seed |
2. Phases (per tenant)
Phase 0 ── tenant signed; tenant-service provisioned ─────┐
│
Phase 1 ── theme + flow config in stage ──────────────────┤
│
Phase 2 ── canary tenant subdomain in prod (no traffic) ─┤
│
Phase 3 ── soft-launch (1% real traffic via tenant CMS) ┤
│
Phase 4 ── full cutover (DNS flip on tenant marketing pages) ┤
│
Phase 5 ── custom-domain (optional) ─────────────────────┘
| Phase | Duration | Exit |
|---|---|---|
| 0 | continuous | tenant + property data exists |
| 1 | 1 week | theme + flow config validated by tenant + CSM |
| 2 | 3 days | canary subdomain serves test bookings end-to-end |
| 3 | 7 days | 1% traffic for 7 days with conversion parity vs. legacy ≥ 90% |
| 4 | 1 day | DNS flip; war-room |
| 5 | 1 week | custom-domain TLS + DNS verified |
3. Pre-cutover preparation per tenant
3.1 Theme + flow config
CSM works with tenant to author theme + flow config in theme-config-service. Required deliverables:
- Logo (SVG, max 200 KiB).
- Favicon (ICO + PNG 32x32, 192x192, 512x512).
- Brand colors (validated for WCAG AA contrast against surfaces).
- Locales supported (must include at least one of
ps-AF,fa-AF,en-US,ar-AE,ur-PK,tr-TR). - Currencies supported (must include at least one).
- Payment methods enabled in
tenant-service. - Cancellation, privacy, T&C policies (markdown; localized).
CI gate theme-readiness.spec.ts asserts tenant config is complete before allowing the canary subdomain to serve bookings.
3.2 Property + inventory + rate plans
Out of scope for this migration plan but must be completed before this BFF cuts over:
- Properties created in
property-service. - Room types defined.
- Rate plans published in
pricing-service. - Allocations seeded in
inventory-service.
3.3 Canary subdomain provisioning
gcloud run domain-mappings create \
--service bff-tenant-booking-asia-south1 \
--domain <tenantSlug>.melmastoon.ghasi.io \
--region asia-south1
Cert Manager auto-provisions a managed cert (DNS-validated). Cutover completes in ~ 30 min.
3.4 Telemetry channel verification
- Confirm
melmastoon.bff.tenant.*events for the new tenant land in BigQuery. - Confirm dashboards show the new tenant in the per-tenant drill-down.
4. Booking-flow cutover (Phase 4)
4.1 Sequence
- T-7 days: war-room channel created; tenant CSM informed.
- T-3 days: capacity audit (estimate first-week traffic; raise instance min if > 5 RPS expected).
- T-1 day: DNS TTLs reduced to 60 s on legacy domain.
- T-0:
- Promote prod release if any pending.
- Tenant updates marketing page CTA buttons from legacy widget URL to the new tenant subdomain.
- Optional custom-domain CNAME flipped if Phase 5 included.
- T+24 h: war-room closed if conversion parity ≥ 95%.
4.2 Rollback
Within 30 min: tenant reverts marketing page CTA back to legacy widget. The BFF continues to serve direct-link traffic; no harm done.
Beyond 30 min: per-tenant feature flag bff_tenant_booking_enabled[<tenantId>] = false returns 503 + MELMASTOON.BFF.TENANT.MIGRATION_PAUSED for that tenant; tenant marketing reverts; investigation continues.
5. Multi-tenant rollout calendar
Tenants onboard in waves to control blast radius:
| Wave | Tenants | Start |
|---|---|---|
| Wave 1 (canary) | 2 design-partner tenants | Week 1 |
| Wave 2 (early adopters) | 5 tenants | Week 3 |
| Wave 3 (early majority) | 15 tenants | Week 7 |
| Wave 4 (general availability) | remaining tenants | Week 12 |
Each wave gates on: Wave SLOs met for prior wave for 14 days.
6. Schema migrations (this service)
| Migration | Description |
|---|---|
0001_init.sql | outbox, inbox, idempotency, schema_migrations |
0002_booking_draft_snapshots.sql | Cold mirror table |
0003_handoff_arrival_log.sql | Handoff arrival ledger |
0004_indexes_pass_2.sql | Index tuning after first load test |
0005_rls_policies.sql | RLS on tenant-scoped tables |
0006_seed_dev_tenants.sql | (dev/seed only) |
0007_outbox_partitioning.sql | (Phase 2) outbox monthly partitioning |
All Drizzle-managed; idempotent; rollback files where reversible.
7. Telemetry-pipeline activation
For each new tenant:
- Confirm
melmastoon.bff.tenant.bootstrap.served.v1lands inanalytics-serviceBigQuery. - Verify the tenant appears in
Funnel healthdashboard within 24 h of first booking. - Per-tenant alert thresholds calibrated after 14 days of baseline data.
8. Custom-domain cutover (Phase 5, optional)
[T-7d] Tenant submits CNAME record:
booking.tenanthotel.com CNAME ghs.googlehosted.com
[T-3d] We provision Cert Manager managed cert (DNS-01 validated).
[T-1d] Tenant updates SPF, MTA-STS, CAA records (advised).
[T-0] Tenant updates marketing page; we monitor uptime; war-room.
[T+7d] Customer-facing communication sent confirming GA on custom domain.
Rollback: tenant CNAME removed; traffic falls back to subdomain or legacy widget; cert remains provisioned for re-use.
9. Cutover (initial GA, all-tenant)
For the initial multi-tenant GA (wave-by-wave above), the cutover is per tenant; there is no single "all tenants flip at once" event. Each wave gates on prior-wave SLOs.
10. Post-cutover hardening (per wave)
- Tighten Cloud Armor rules based on first-week traffic shape.
- Tune cache TTLs based on observed cache-hit ratios.
- Calibrate per-tenant rate-limit defaults.
- Confirm Pub/Sub topic-level cost matches projection.
- Run a second DR drill at T+30 days from Wave 1.
- Update this document with deviations + lessons.
11. Decommission of legacy widgets
Legacy booking widgets are tenant-owned (typically third-party plugins). Decommission is the tenant's choice; we recommend:
- Keep legacy URL for 90 days as safety net.
- Track legacy widget conversions; once < 1% of total, propose decommission to CSM.
- Tenant decommissions; we update tenant CMS guidelines.