Cross-context coupling is prohibited.
Sales must not instantiate Identity classes directly. Use public interfaces or subscribe to domain events.Context map
| Context | Primary directory | Key responsibility |
|---|---|---|
| Identity | app/Domain/Identity | Users, roles, and tenant membership |
| Auth | app/Domain/Auth | Credentials, OTP, social login, password reset |
| TenantGovernance | app/Domain/TenantGovernance | Tenant lifecycle, profile, and subscription status |
| Billing | app/Domain/Billing | Payments, subscription plans, and invoicing |
| Sales | app/Domain/Sales | Orders, cart, checkout, and payment status |
| Catalog | app/Domain/Catalog | Products, menu sections, modifiers, and pricing |
| Booking | app/Domain/Booking | Appointments, services, providers, and availability |
| Marketing | app/Domain/Marketing | Coupons, campaigns, announcements, and followers |
| Interactions | app/Domain/Interactions | WhatsApp, call, and map CTA tracking |
| Analytics | app/Domain/Analytics | Visit tracking and business metrics |
| Reviews | app/Domain/Reviews | Customer reviews and ratings |
| Directory | app/Domain/Directory | Public directory, cities, categories, and SEO |
| Search | app/Domain/Search | Search contracts and query strategies |
| AIEnrichment | app/Domain/AIEnrichment | AI profile optimization with budget control |
| Public | app/Domain/Public | Public-facing microsites and discovery pages |
Context details
Identity
Identity
Owns:
Application handlers:
UserEntity, UserRole enum, UserRepositoryInterfaceResponsibilities: User registration, profile management, tenant membership assignment, and reactivation. The canonical source of truth for who a user is.Key domain events:| Event | When it fires |
|---|---|
UserRegistered | A new user account is created |
UserDeleted | A user account is removed |
TenantRegistered | A new tenant is created alongside the owner user |
UserIdentityLinked | A social provider is linked to an existing account |
UserRegisteredViaSocial | A user registers via a social provider for the first time |
SocialIdentityLinked | A social identity record is attached to a user |
RegisterUserHandler, UpdateUserProfileHandler, ReactivateUserHandlerAuth
Auth
Owns:
Application handlers:
OneTimePassword entity, OTP lifecycle, social login flow, password reset, and session credentialsResponsibilities: Everything related to proving who you are — password verification, OTP generation and verification, social OAuth flows, and credential rotation.Key domain events:| Event | When it fires |
|---|---|
OtpGenerated | A one-time password is created for a user |
OtpVerified | A user successfully verifies an OTP |
UserPasswordChanged | A user’s password is reset or updated |
Auth\Handlers in app/Application/AuthTenantGovernance
TenantGovernance
Owns:
Application handlers:
TenantEntity, TenantRepositoryInterface, subscription state, tenant audit trailResponsibilities: Creating and managing tenant workspaces, enforcing subscription-gated features, running stale tenant audits, and reconciling subscription status.Key domain events:| Event | When it fires |
|---|---|
TenantCreated | A new tenant workspace is provisioned |
TenantUpdated | Tenant profile settings are changed |
TenantProfileEnhanced | AI enrichment updates the tenant profile |
TenantGovernance handlers in app/Application/TenantGovernanceBilling
Billing
Owns: Payment entities, subscription plans, billing gateways (via
Application handlers:
Gateways/ interfaces), and invoicing DTOsResponsibilities: Receiving and recording payments, tracking subscription upgrades and expirations, processing payment webhooks, and reconciling pending payment intents.Key domain events:| Event | When it fires |
|---|---|
PaymentReceived | A payment is successfully recorded |
PaymentFailed | A payment attempt fails |
PaymentReported | A manual payment is reported by the tenant |
PaymentWebhookReceived | An external payment webhook arrives |
SubscriptionUpgraded | A tenant’s plan is upgraded |
Payments handlers in app/Application/PaymentsSales
Sales
Owns:
Application handlers:
OrderEntity, OrderRepositoryInterface, order status machine, and cart stateResponsibilities: Creating and persisting orders, managing the full order lifecycle (pending → paid → shipped → cancelled), applying coupons and discounts, and tracking payment status.Key domain events:| Event | When it fires |
|---|---|
OrderCreated | A new order is placed |
OrderCancelled | An order is cancelled |
CartAbandoned | A cart session expires without checkout |
Sales handlers in app/Application/SalesCatalog
Catalog
Owns: Product contracts, catalog query interfaces, and product-change eventsResponsibilities: Defining the catalog contract for querying products, menu sections, modifiers, and price changes. Infrastructure implementations live in
Application handlers:
app/Infrastructure/Catalog.Key domain events:| Event | When it fires |
|---|---|
ProductPriceChanged | A product’s price is updated |
Products handlers in app/Application/ProductsBooking
Booking
Owns: Appointment lifecycle, service definitions, provider availability, and booking confirmationResponsibilities: Creating and managing appointments, enforcing availability slots, sending confirmations and reminders, and allowing public cancellation via signed URLs.Key domain events:
Application handlers: Booking handlers in
| Event | When it fires |
|---|---|
AppointmentCancelled | An appointment is cancelled by owner or customer |
app/Application (booking flows)Marketing
Marketing
Owns:
Coupon, Campaign, Announcement, follower lists, and loyalty contractsResponsibilities: Defining coupon rules (discount type, expiry, usage limits), managing email campaigns, publishing announcements, and tracking follower/lead relationships.Key domain events: Marketing events are consumed by downstream contexts (analytics, notifications). The Marketing domain owns the enums and contracts that define valid campaign and coupon states.Application handlers: Marketing handlers in app/Application/MarketingInteractions
Interactions
Owns:
Application handlers:
InteractionRecorded event, interaction repository interface, and CTA-type definitionsResponsibilities: Recording every customer-initiated CTA: WhatsApp button taps, phone call taps, and “get directions” map taps. These events feed the analytics read model.Key domain events:| Event | When it fires |
|---|---|
InteractionRecorded | A visitor taps a CTA on a business microsite |
Interactions handlers in app/Application/InteractionsAnalytics
Analytics
Owns:
Application handlers: Analytics handlers in
TenantAnalytic entity, analytics repository interface, and metric definitionsResponsibilities: Recording tenant visit counts, aggregating interaction metrics, syncing analytics to a read model, and providing data for the business dashboard and exportable reports.Key domain events:| Event | When it fires |
|---|---|
AnalyticsSynced | Analytics metrics are aggregated and written to the read model |
app/Application (analytics flows)Reviews
Reviews
Owns:
Application handlers:
Review entity, review repository interface, and rating constraintsResponsibilities: Allowing customers to submit reviews for tenant businesses, enforcing one-review-per-customer rules, and providing the review feed for public microsites.Key domain events:| Event | When it fires |
|---|---|
ReviewCreated | A customer submits a new review |
Reviews handlers in app/Application/ReviewsDirectory
Directory
Owns: Directory DTOs, city/category lookup contracts, and SEO-slug resolutionResponsibilities: Powering the public business directory, city landing pages, and category landing pages. Provides the contracts that the Infrastructure and HTTP layers implement for discovery queries.Key domain events: Directory is primarily a read-side context. It consumes events from
Identity and TenantGovernance to keep directory listings current.Search
Search
Owns: Search port interfaces and query strategy contractsResponsibilities: Defining the contract for full-text and filtered search across the tenant directory. The Infrastructure layer (
app/Infrastructure/Search) provides the concrete implementation (database or external search engine).Key domain events: Search is a read-side context that projects from other bounded contexts.AIEnrichment
AIEnrichment
Owns: AI prompt templates, enrichment data DTOs, and budget-control contractsResponsibilities: Generating and applying AI-suggested improvements to tenant profiles (description, SEO copy, category tagging). Every AI call is subject to a per-tenant budget cap, and all consumption is audited.Key domain events: Enrichment results trigger
TenantProfileEnhanced in the TenantGovernance context.Application handlers: AI handlers in app/Infrastructure/AI and queued via app/Application/ActionsPublic
Public
Owns: Public-facing microsite contracts, storefront query interfaces, and announcement deliveryResponsibilities: Serving the tenant microsite (
/t/{tenant}), the public landing page, and the discovery/explore pages. Provides read-model contracts that the Infrastructure layer fulfils with cached queries.Key domain events: Public is a read-side context. It reacts to TenantUpdated and ProductPriceChanged to invalidate cached microsites.How contexts communicate
Contexts are decoupled at the class level. Three patterns are used:Domain events via outbox
A handler appends a domain event to the outbox table inside its transaction. The outbox worker dispatches it after commit. Listeners in other contexts receive it asynchronously.
Public interfaces
A context exposes a narrow interface (e.g.,
TenantRepositoryInterface) that other Application handlers may depend on. The concrete implementation is in Infrastructure.Read models
Contexts that only need to query another context’s data do so through a dedicated read-model query (e.g., a Catalog query in the Sales checkout flow), never by importing the other context’s entities.