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
| Journey | Actor and entry point | Initial authentication | Primary API boundaries | Notifications | Authoritative transition | Recovery |
|---|---|---|---|---|---|---|
| Account provisioning | Studio owner at signup | Anonymous, then magic link | account signup, magic-link consumption, account settings | Magic link and welcome email | account active; owner membership active | Reissue unused/expired magic link; support may suspend the tenant |
| Staff management | Owner in /admin/users | Owner session | invitations, memberships, roles, ownership transfer | Invitation, role change, removal | account membership and role assignment | Owner revokes invitation or membership; ownership transfer requires a second owner |
| Public discovery | Visitor at a tenant-slug consumer URL | Anonymous | public tenant, published events, instances, products | None | Read-only; no state transition | Unknown/inactive slug returns a non-enumerating 404 |
| New attendee onboarding | Visitor during checkout or booking | Anonymous, then account-scoped magic link | attendee registration, account selection, session | Magic link and welcome email | user plus attendee membership active | Resume original return URL after a replacement magic link |
| Returning attendee login | Attendee from consumer login | Anonymous, then magic link | login, memberships, account selection | Magic link | account-scoped authenticated session | Explicit account picker when the email belongs to several tenants |
| Drop-in booking | Attendee on an instance | Attendee session | availability, purchase, provider callback, booking | Receipt and booking confirmation | payment paid, then booking confirmed idempotently | Failed payment creates no booking; retry uses a new payment attempt |
| Class-pass booking | Attendee on products or schedule | Attendee session | pass purchase, entitlement, booking | Receipt and booking confirmation | entitlement active; confirmed booking decrements credit once | Failed booking retains credit; eligible timely cancellation restores it once |
| Subscription lifecycle | Attendee on products and access | Attendee session | subscription purchase, eligibility, booking, renewal, cancellation, reactivation | Receipt, renewal, failure, cancellation | paid-through subscription entitlement | Three retries in a three-day grace period, then suspension and explicit reactivation |
| Schedule exception | Administrator in programme admin | Administrator or owner session | series, instance exception, affected bookings | Change or cancellation email | instance exception plus preserved booking history | Administrator restores/moves instance and notifications remain auditable |
| Support and reconciliation | Administrator in support view | Administrator or owner session | payment lookup, audit history, refund | Refund receipt | refund record and corresponding entitlement adjustment | Retry failed refund; never erase original payment or booking records |
Approved domain decisions
| Area | First-release decision |
|---|---|
| Public catalogue | Read-only endpoints are required for active tenant-by-slug, published events, dated instances with availability, and active products. |
| Registration | Attendee self-registration is allowed only through an explicit active tenant slug or invitation. |
| Multi-tenant email | One normalized email may belong to several tenants. Authentication identifies the user; account selection establishes tenant scope. |
| Products | Drop-in, finite class pass, and monthly subscription are in scope. Workshops use drop-in semantics. Teacher training and arbitrary product types are deferred. |
| Eligibility | Empty eligibleEventIds means every published, bookable event in the product's tenant. A populated list is an allow-list. Audience/group restrictions still apply. |
| Duplicate bookings | At most one confirmed booking per attendee and instance. Repeated idempotent requests return the existing result. |
| Booking window | Default opens when the instance is published and closes at instance start. A tenant may configure earlier opening/closing. |
| Capacity | Confirmed bookings cannot exceed capacity. Waitlists and deliberate overbooking are deferred. |
| Cancellation | Tenant-configurable deadline, default two hours before start. Timely cancellation restores finite credit once; late cancellation does not. |
| Refunds | No automatic money refund for attendee cancellation. Owners/admins may issue auditable full or partial refunds. |
| Subscription billing | Purchase-day monthly anchor; three retries across a three-day grace period; suspend after paid-through date when all fail. |
| Subscription cancellation | Cancel at period end: no further renewal, access retained through paid-through date. Reactivation before expiry preserves anchor; later reactivation is a new purchase. |
| Schedule changes | Moved bookings follow the moved instance. Cancelled instances preserve bookings as cancelled-by-studio and restore finite credits; administrators decide money refunds. |
| Teacher access | Teachers read assigned events and their rosters only. They do not manage products, payments, tenant settings, or unrelated attendee records. |
| Locale and finance | DKK, Europe/Copenhagen, Danish and English, Danish VAT-ready receipts, and account-local date presentation. |
| Branding and returns | Tenant display name/logo and allow-listed HTTPS consumer return URLs are required. Custom domains are deferred. |
| Notifications | Transactional email is required for magic links, invitations, purchases, bookings, schedule changes, cancellations, renewal outcomes, and refunds. |
Permission matrix
| Capability | Owner | Administrator | Teacher | Attendee | Anonymous |
|---|---|---|---|---|---|
| Read public catalogue | yes | yes | yes | yes | yes |
| Manage tenant settings and return URLs | yes | no | no | no | no |
| Transfer ownership | yes | no | no | no | no |
| Invite/remove staff and attendees | yes | yes | no | no | no |
| Manage events, series, locations, and durations | yes | yes | assigned-event view only | no | no |
| Read roster | yes | yes | assigned events only | own booking only | no |
| Manage products and eligibility | yes | yes | no | no | no |
| Purchase and manage own access | yes | yes | yes | yes | no |
| Create/cancel own booking | yes | yes | yes | yes | no |
| Refund and reconcile payments | yes | yes | no | no | no |
| Read audit history | yes | yes | no | own receipts only | no |
Authoritative state transitions
Booking
| From | Event | To | Side effects |
|---|---|---|---|
| none | eligible booking with paid or active entitlement | confirmed | reserve capacity; consume finite credit once |
| confirmed | timely attendee cancellation | cancelled | release capacity; restore finite credit once |
| confirmed | late attendee cancellation | cancelled-late | release capacity; retain consumed credit |
| confirmed | studio cancels instance | cancelled-by-studio | release capacity; restore finite credit; notify |
| confirmed | instance moves | confirmed | booking follows instance; notify |
Payment
| From | Event | To | Side effects |
|---|---|---|---|
| pending | signed provider success | paid | activate entitlement or allow atomic booking completion |
| pending | provider rejection/expiry | failed | no entitlement or booking |
| paid | authorized full refund | refunded | record provider reference; adjust entitlement |
| paid | authorized partial refund | partially-refunded | record amount and provider reference |
Entitlement and subscription
| From | Event | To | Side effects |
|---|---|---|---|
| pending | payment paid | active | snapshot price, cadence, eligibility, anchor and paid-through |
| active | renewal paid | active | extend paid-through and next renewal |
| active | cancellation requested | cancelling | retain access through paid-through; disable future renewal |
| active | renewal fails | grace | schedule three retries and notify |
| grace | retry paid | active | clear failure and extend paid-through |
| grace | retries exhausted after paid-through | suspended | reject new entitlement-funded bookings |
| cancelling | paid-through reached | expired | reject new bookings |
| suspended/expired | approved reactivation | active | use 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 money refunds for attendee 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-*remaindraftuntil 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.