# Module Boundaries

> Architecture only. Module inventory → [module-registry.md](../module-registry.md)

## Core Platform

**Owns:** tenants, domains, plans, features, subscriptions, entitlement checks, service/module registry, internal service tokens, outbox/inbox (core), audit log, core users, tenant memberships (operational), onboarding, public tenant-site resolution.

**Must not own:** business journals, CRM entities, restaurant menus, file blobs, SMS campaigns.

## Identity & Access

**Owns:** user profiles linked to Keycloak, identity-layer memberships, OIDC BFF (config/token/me), mobile OTP handoff/session redeem, Keycloak admin sync.

**Must not own:** workspace onboarding lifecycle, plan/subscription, operational tenant roles source of truth (Core).

## Frontend

**Owns:** UI, theme application, client-side auth redirects, dashboards, onboarding wizard UX.

**Must not own:** business rules, direct DB access, SQLAlchemy/Alembic, entitlement computation.

## Future Business Modules

Each module (Accounting, CRM, Restaurant, Ecommerce, …) owns its database and domain APIs. Cross-module coupling is API/event only. Financial postings go only through Accounting Posting Engine ([ADR-010](adr/ADR-010.md)).

### CRM (Sales CRM)

**Owns:** Lead, Contact, Organization (business account), Opportunity, Pipeline, PipelineStage, SalesActivity, Task, Meeting, CallLog, Sales Timeline, Comment/Mention, Bookmark, Sales Team, Playbook, Forecast, Goal, Target, Win/Loss, Quote (sales), CRM publish events.

**Must not own:** Automation/workflows, Customer360, Marketing, Notification delivery, Messaging, Communication, Helpdesk, Analytics, AI, Identity, Accounting, Inventory, Restaurant, Marketplace, Files, Search, Loyalty, Sports Center.

### Loyalty (Enterprise Loyalty Platform)

**Owns:** LoyaltyProgram, MembershipTier, Member, PointAccount (shell; ledger in later phases), Reward catalog shell, Campaign shell, Loyalty audit, Loyalty publish events.

**Must not own:** CRM sales entities, Accounting postings, Notification delivery, Identity, Wallet UI (frontend), Restaurant/Marketplace/Ecommerce/Sports Center domain data — those modules consume Loyalty via API/Events only.

### Communication (Enterprise Communication Platform)

**Owns:** Provider configs, sender numbers, message templates, manual contacts, dynamic contact-source configs, messages, queue/DLQ, delivery timeline, provider logs, OTP challenges, webhook receipts, communication audit; outbound provider adapters.

**Must not own:** CRM/Loyalty/Restaurant/Marketplace/Sports Center business entities; must not be embedded inside those modules. Auth OTP path in Core remains separate until explicitly migrated.

### Sports Center Platform

**Owns:** Sports members, memberships/membership types, coaches, attendance/access devices, bookings, facilities/courts/equipment, programs/workouts, competitions/sports events, locker/medical/nutrition shells as scoped, sports reports/analytics shells, sports_center publish events, integrations adapters (client-side only).

**Must not own:** Accounting journals/Posting Engine, Sales CRM aggregates, Loyalty ledger/campaigns, Communication providers, Core tenant membership, Restaurant/Ecommerce domains, product AI platform, Automation engine.

## Shared Library (`backend/shared-lib`)

**Owns:** JWT validation helpers, phone normalization, event envelope types, shared exceptions/responses.

**Must not own:** tenant business workflows or service-specific repositories.

## Boundary Rules

1. No cross-database foreign keys.
2. No importing another service's models.
3. Feature gates use Core entitlement API.
4. Frontend talks to public/versioned APIs only.
5. Providers are integrated behind module/provider adapters — see [integration-architecture.md](integration-architecture.md).

## Related Documents

- [Service Architecture](service-architecture.md)
- [ADR-001](adr/ADR-001.md) · [ADR-002](adr/ADR-002.md) · [ADR-007](adr/ADR-007.md) · [ADR-014](adr/ADR-014.md)
- [Module Registry](../module-registry.md)
- [Sports Center Roadmap](../sports-center-roadmap.md)
