Skip to main content

J-13 — Onboard New Tenant (Single Hotel Operator)

One-liner: A new operator signs up, configures their property, theme, payments, lock vendor, and goes live in under a day.

1. Purpose

A new operator (single property) signs up to Melmastoon, completes onboarding (tenant identity, property setup, theme, payment provider, lock vendor, locale + currency), publishes their tenant booking site, and starts taking bookings the same day. Outcome: tenant live, theme published, booking site reachable on <slug>.melmastoon.app, Electron app primer ready, first booking demo passes.

2. Persona Context

  • Persona: Owner / Operator.
  • Surfaces: Control Plane Web (apps/web-control-plane), Electron Desktop (download + setup).
  • Primary BFFs: bff-control-plane-service.
  • Backing services: tenant-service, theme-config-service, payment-providers-adapter, lock-and-key-service, notification-service, identity-service.
  • Preconditions: Operator has email + phone; tenant slug is unique; payment provider account is creatable.
  • Trigger: Operator signs up at https://control.melmastoon.com/signup.

3. Entry Points

#EntryNotes
1Direct signupDefault
2Sales-led invite linkPre-filled fields
3Self-service trialP2

4. Screen-by-Screen Flow

4.1 SignupScreen

  • Layout: Email + phone, password / OTP, locale / currency picker, terms checkbox; "Create account" CTA.
  • Components: Form, OtpInput, LocaleSelect, CurrencySelect.
  • Offline: Disabled.
  • AI: None.
  • Errors: Email taken; OTP invalid.
  • Loading: Spinner.
  • A11y: Field labels; OTP keyboard-friendly.
  • RTL: Mirror.
  • Perf: Submit <= 1 s p95.
  • Telemetry: frontend.tenant.signup_completed.

4.2 TenantSetupWizardStep1Identity

  • Layout: Tenant name, slug picker (live availability check), country, timezone, languages spoken.
  • Components: SlugInput (live check), CountrySelect, TimezoneSelect, LanguageMultiSelect.
  • Offline: Disabled.
  • AI: None.
  • Errors: Slug taken -> live error; reserved slug rejected.
  • Loading: Slug check <= 200 ms debounced.
  • A11y: Live error announced.
  • RTL: Mirror.
  • Perf: Mount <= 200 ms.
  • Telemetry: frontend.tenant.identity_completed.

4.3 TenantSetupWizardStep2Property

  • Layout: Property name, address (autocomplete), GPS, room types editor (name, capacity, base rate, sample photos).
  • Components: AddressAutocomplete, RoomTypeEditor, PhotoUpload.
  • Offline: Disabled.
  • AI: Phase 2 — auto-fill room descriptions from photos.
  • Errors: Address invalid; rate invalid.
  • Loading: Photo upload progress.
  • A11y: Field labels; map preview alt-text.
  • RTL: Mirror.
  • Perf: Photo upload <= 10 s per file.
  • Telemetry: frontend.tenant.property_completed.

4.4 TenantSetupWizardStep3Theme

  • Layout: Logo upload, primary brand colour, font picker, layout preset, content blocks (intro, amenities, gallery, contact); live preview iframe.
  • Components: LogoUploader, ColorPicker, FontPicker, LayoutPresetPicker, BlockEditor, PreviewIframe.
  • Offline: Disabled.
  • AI: Phase 1 — palette suggestion from logo (HITL); Phase 2 — copy suggestions.
  • Errors: Contrast warning if combination fails AA.
  • Loading: Preview refresh <= 500 ms.
  • A11y: All editors keyboard-operable; preview iframe focus-trapped or labelled.
  • RTL: Mirror.
  • Perf: Preview iframe ready <= 1 s.
  • Telemetry: frontend.tenant.theme_configured.

4.5 TenantSetupWizardStep4Payments

  • Layout: Payment provider picker (Stripe / HBL / etc.); per-provider connect flow (OAuth or key entry); cash-on-arrival policy toggle; tax setup.
  • Components: ProviderConnectButton, Form, ToggleField, TaxRuleEditor.
  • Offline: Disabled.
  • AI: None.
  • Errors: Provider connect failure -> retry / different provider.
  • Loading: Connect flow varies by provider.
  • A11y: Connect status announced.
  • RTL: Mirror.
  • Perf: Provider connect <= 30 s wall-clock.
  • Telemetry: frontend.tenant.payments_connected { provider }.

4.6 TenantSetupWizardStep5LockVendor

  • Layout: Lock vendor picker (Salto / Onity / TTLock / "skip"); per-vendor connect; encoder driver download instructions.
  • Components: VendorPicker, ConnectButton, DriverDownloadCard.
  • Offline: Disabled.
  • AI: None.
  • Errors: Vendor connect failure -> retry.
  • Loading: Sub-second.
  • A11y: Driver download link announced; "skip" path clear.
  • RTL: Mirror.
  • Perf: Connect <= 10 s p95.
  • Telemetry: frontend.tenant.lock_configured { vendor }.

4.7 TenantSetupWizardStep6PublishAndTest

  • Layout: Final review; "Publish booking site" CTA; "Download Electron desktop app" CTA; "Make a test booking" link.
  • Components: FinalReviewCard, Button (variants).
  • Offline: Disabled.
  • AI: None.
  • Errors: Final validation gate.
  • Loading: Publish <= 5 s.
  • A11y: Review announces sections.
  • RTL: Mirror.
  • Perf: Publish <= 5 s p95.
  • Telemetry: frontend.tenant.published { tenantId }.

5. State Machine

6. Data Requirements

6.1 Server state

  • POST /api/v1/tenants (signup)
  • PATCH /api/v1/tenants/:id (per step)
  • POST /api/v1/themes/:tenantId/publish
  • POST /api/v1/payment-providers/:id/connect
  • POST /api/v1/lock-vendors/:id/connect
  • POST /api/v1/tenants/:id/go-live

6.2 Local persistence

  • Web app caches form drafts in IndexedDB; cleared on publish.

6.3 Idempotency

  • All mutations carry X-Idempotency-Key.

7. AI Behavior

SurfaceStepPurposeModelEdge / CloudHITLProvenanceFallback
ColorPickerStep 3Palette suggestion from logosmall image-to-paletteCloudCanonical cardPillManual selection
Copy suggestions (P2)Step 3Block copy suggestionssmall textCloudCanonical cardPillManual

8. Offline Behavior

  • Onboarding requires online.
  • Operator can save drafts and resume; resume token TTL 7 days.

9. Error States

ErrorTriggerUX shownRecoveryTelemetry
SLUG_TAKENLive checkInline errorUser picks anotherfrontend.tenant.slug_taken
PAYMENT_PROVIDER_CONNECT_FAILEDOAuth failureRetry banner; alternate provider optionUser retriesfrontend.tenant.payments_failed
THEME_CONTRAST_FAILCombination fails AAInline warning + suggested adjustmentsUser adjustsfrontend.tenant.theme_contrast_warn
PUBLISH_VALIDATION_FAILEDServer-side ruleBanner with field linkUser fixeserror.surfaced { code }

10. E2E Test Gates

  • Composite gate G-CP-1: signup -> identity -> property -> theme -> payments -> lock -> publish -> test booking ok.
  • Provider connect failure -> retry path.
  • Resume-from-draft flow.

11. Performance Requirements

MetricTarget
Each step mount<= 200 ms
Slug live check<= 200 ms debounced
Photo upload (per file)<= 10 s
Provider connect<= 30 s
Publish<= 5 s p95

12. Accessibility Requirements

  • All keyboard-completable.
  • Live preview iframe accessible with skip link.
  • Contrast warnings actionable.

13. Telemetry

Frontend events

  • frontend.tenant.signup_completed
  • frontend.tenant.{identity, property, theme}_completed
  • frontend.tenant.payments_connected { provider }
  • frontend.tenant.lock_configured { vendor }
  • frontend.tenant.published { tenantId }

Domain events emitted

  • melmastoon.tenant.created.v1
  • melmastoon.tenant.property.added.v1
  • melmastoon.theme.published.v1
  • melmastoon.tenant.live.v1

14. Success Criteria

  • Operator goes from signup to live in <= 1 day (mostly user time).
  • Booking site reachable on <slug>.melmastoon.app.
  • First test booking succeeds.
  • Electron app downloads and runs primer fetch successfully.

References