Skip to content

First-client scope and journeys

This document is the decision baseline for the first yoga-studio client. It defines what later implementation issues may assume and what remains outside the first release. The executable identifiers live in specs/first-client-journeys.feature.md.

Journey map

JourneyActor and entry pointInitial authenticationPrimary API boundariesNotificationsAuthoritative transitionRecovery
Account provisioningStudio administrator at signupAnonymous, then magic linkaccount signup, magic-link consumption, account settingsMagic link and welcome emailaccount active; administrator membership activeReissue unused/expired magic link; support may suspend the tenant
Staff managementAdministrator in /admin/usersAdministrator sessioninvitations, memberships, personasInvitation and removalaccount membership and persona assignmentAdministrator revokes invitation or membership
Public discoveryVisitor at a tenant-slug consumer URLAnonymouspublic tenant, published events, instances, productsNoneRead-only; no state transitionUnknown/inactive slug returns a non-enumerating 404
New attendee onboardingVisitor during checkout or bookingAnonymous, then account-scoped magic linkattendee registration, account selection, sessionMagic link and welcome emailuser plus attendee membership activeResume original return URL after a replacement magic link
Returning attendee loginAttendee from consumer loginAnonymous, then magic linklogin, memberships, account selectionMagic linkaccount-scoped authenticated sessionExplicit account picker when the email belongs to several tenants
Drop-in bookingAttendee on an instanceAttendee sessionavailability, purchase, provider callback, bookingReceipt and booking confirmationpayment paid, then booking confirmed idempotentlyFailed payment creates no booking; retry uses a new payment attempt
Drop-in cancellationAttendee in personal booking historyAttendee sessionbooking cancellation, MobilePay reimbursement, personal payment historyCancellation and reimbursement receiptbooking timestamped as cancelled; remaining payment reimbursed once; both ledger entries identify the exact class and productFailed reimbursement rolls back cancellation so it can be retried safely
Class-pass bookingAttendee on products or scheduleAttendee sessionpass purchase, entitlement, bookingReceipt and booking confirmationentitlement active; confirmed booking decrements credit onceFailed booking retains credit; eligible timely cancellation restores it once
Subscription lifecycleAttendee on products and accessAttendee sessionsubscription purchase, eligibility, booking, renewal, cancellation, reactivationReceipt, renewal, failure, cancellationpaid-through subscription entitlementThree retries in a three-day grace period, then suspension and explicit reactivation
Schedule exceptionAdministrator in programme adminAdministrator sessionseries, instance exception, affected bookingsChange or cancellation emailinstance exception plus preserved booking historyAdministrator restores/moves instance and notifications remain auditable
Support and reconciliationAdministrator in support viewAdministrator sessionpayment lookup, audit history, refundRefund receiptrefund record and corresponding entitlement adjustmentRetry failed refund; never erase original payment or booking records

Approved domain decisions

AreaFirst-release decision
Public catalogueRead-only endpoints are required for active tenant-by-slug, published events, dated instances with availability, and active products.
RegistrationAttendee self-registration is allowed only through an explicit active tenant slug or invitation.
Multi-tenant emailOne normalized email may belong to several tenants. Authentication identifies the user; account selection establishes tenant scope.
ProductsDrop-in, finite class pass, and monthly subscription are in scope. Workshops use drop-in semantics. Teacher training and arbitrary product types are deferred.
EligibilityEmpty eligibleEventIds means every published, bookable event in the product's tenant. A populated list is an allow-list. Audience/group restrictions still apply.
Duplicate bookingsAt most one confirmed booking per attendee and instance. Repeated idempotent requests return the existing result.
Booking windowDefault opens when the instance is published and closes at instance start. A tenant may configure earlier opening/closing.
CapacityConfirmed bookings cannot exceed capacity. Waitlists and deliberate overbooking are deferred.
CancellationTenant-configurable deadline, default two hours before start. Timely cancellation restores finite credit once; late cancellation does not.
RefundsCancelling a paid drop-in automatically reimburses its remaining amount exactly once. Administrators may issue other auditable full or partial refunds.
Subscription billingPurchase-day monthly anchor; three retries across a three-day grace period; suspend after paid-through date when all fail.
Subscription cancellationCancel at period end: no further renewal, access retained through paid-through date. Reactivation before expiry preserves anchor; later reactivation is a new purchase.
Schedule changesMoved bookings follow the moved instance. Cancelled instances preserve bookings as cancelled-by-studio and restore finite credits; administrators decide money refunds.
PersonasEvery account membership is either attendee or administrator. Owners and teachers use the administrator persona with full administration access for now.
Locale and financeDKK, Europe/Copenhagen, Danish and English, Danish VAT-ready receipts, and account-local date presentation.
Branding and returnsTenant display name/logo and allow-listed HTTPS consumer return URLs are required. Custom domains are deferred.
NotificationsTransactional email is required for magic links, invitations, purchases, bookings, schedule changes, cancellations, renewal outcomes, and refunds.

Permission matrix

CapabilityAdministratorAttendeeAnonymous
Read public catalogueyesyesyes
Manage tenant settings and return URLsyesnono
Invite/remove staff and attendeesyesnono
Manage events, series, locations, and durationsyesnono
Read rosteryesown booking onlyno
Manage products and eligibilityyesnono
Purchase and manage own accessyesyesno
Create/cancel own bookingyesyesno
Refund and reconcile paymentsyesnono
Read audit historyyesown receipts onlyno

Authoritative state transitions

Booking

FromEventToSide effects
noneeligible booking with paid or active entitlementconfirmedreserve capacity; consume finite credit once
confirmedtimely attendee cancellationcancelledtimestamp cancellation; release capacity; restore finite credit or reimburse a paid drop-in once
confirmedlate attendee cancellationcancelled-latetimestamp cancellation; release capacity; retain consumed finite credit; reimburse a paid drop-in once
confirmedstudio cancels instancecancelled-by-studiorelease capacity; restore finite credit; notify
confirmedinstance movesconfirmedbooking follows instance; notify

Payment

FromEventToSide effects
pendingsigned provider successpaidactivate entitlement or allow atomic booking completion
pendingprovider rejection/expiryfailedno entitlement or booking
paidauthorized full refundrefundedrecord provider reference; adjust entitlement
paidauthorized partial refundpartially-refundedrecord amount and provider reference

Entitlement and subscription

FromEventToSide effects
pendingpayment paidactivesnapshot price, cadence, eligibility, anchor and paid-through
activerenewal paidactiveextend paid-through and next renewal
activecancellation requestedcancellingretain access through paid-through; disable future renewal
activerenewal failsgraceschedule three retries and notify
graceretry paidactiveclear failure and extend paid-through
graceretries exhausted after paid-throughsuspendedreject new entitlement-funded bookings
cancellingpaid-through reachedexpiredreject new bookings
suspended/expiredapproved reactivationactiveuse preserved anchor only when still inside paid period; otherwise create new purchase

All transitions store tenant, actor or worker identity, timestamp, correlation identifier, provider reference where relevant, and before/after state.

First-release scope

Included:

  • Tenant provisioning, staff invitations, role management, and explicit ownership transfer.
  • Public tenant/event/product discovery and tenant-scoped attendee authentication.
  • Drop-in, class-pass, and monthly-subscription purchasing through MobilePay.
  • Capacity-safe booking, duplicate prevention, cancellation deadlines, and credit restoration.
  • Recurring programme exceptions with affected-attendee notification.
  • Subscription renewal, retry, grace, cancellation-at-period-end, and reactivation.
  • Administrator payment/booking reconciliation, refunds, and audit history.
  • DKK, Danish/English, Europe/Copenhagen, VAT-ready receipts, and transactional email.

Deferred:

  • Waitlists, overbooking, custom domains, multiple currencies, non-Danish tax regimes.
  • Password/social authentication, attendee account merging, family/shared passes.
  • Arbitrary product types, resource scheduling, payroll, accounting exports, SMS/push.
  • Automatic refunds beyond paid drop-in booking cancellation and advanced dunning.

Approval record

  • Product-owner direction: approved for specification through the repository request to implement issue #10.
  • First-client stakeholder approval: pending. This document and FIRST-CLIENT-JOURNEYS-* remain draft until a named stakeholder confirms the decisions.
  • Implementation status: the public catalogue, tenant-scoped attendee registration and selection, ownership transfer, booking policies, cancellation outcomes, subscription recovery, refunds, and audit lookup are executable API contracts with integration or Playwright coverage. Live provider onboarding and stakeholder acceptance remain release gates.

Booking SaaS implementation documentation