# Tenancy Data Model ## Entity Relationship Overview ``` ┌──────────────┐ │ Platform │ └──────┬───────┘ │ 1:N ▼ ┌──────────────┐ ┌─────────────────┐ │ Merchant │────▶│ MerchantDomain │ └──────┬───────┘ 1:N └─────────────────┘ │ 1:N ▼ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ │ Store │────▶│ StoreUser │────▶│ Role │ └──────┬───────┘ 1:N └──────┬──────┘ └──────────────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ User │ │ └──────────────┘ │ ├────▶ StoreDomain (1:N) └────▶ StorePlatform (N:M bridge to Platform) ``` ## Core Entities ### Platform Top-level SaaS instance. All merchants and stores belong to a platform. | Column | Type | Description | |--------|------|-------------| | `id` | Integer | Primary key | | `name` | String | Platform name | | `code` | String | Unique platform code | | `is_active` | Boolean | Platform enabled/disabled | ### Merchant Business entity that owns one or more stores. | Column | Type | Description | |--------|------|-------------| | `id` | Integer | Primary key | | `name` | String | Business name | | `owner_user_id` | Integer | FK to User — the merchant owner | | `contact_email` | String | Primary contact email | | `is_active` | Boolean | Merchant active status | ### Store A storefront belonging to a merchant. Central entity for multi-tenant scoping. | Column | Type | Description | |--------|------|-------------| | `id` | Integer | Primary key | | `merchant_id` | Integer | FK to Merchant | | `name` | String | Store name | | `code` | String | Unique store code (used in URLs) | | `is_active` | Boolean | Store active status | ### User Admin users at platform, merchant, or store level. | Column | Type | Description | |--------|------|-------------| | `id` | Integer | Primary key | | `email` | String | Unique email | | `username` | String | Username | | `role` | UserRole | `super_admin`, `platform_admin`, `merchant_owner`, `store_member` | | `hashed_password` | String | Bcrypt password hash | | `is_active` | Boolean | Account active status | ### StoreUser Membership link between users and stores, with role assignment. | Column | Type | Description | |--------|------|-------------| | `id` | Integer | Primary key | | `store_id` | Integer | FK to Store | | `user_id` | Integer | FK to User | | `role_id` | Integer | FK to Role (NULL for owners) | | `is_active` | Boolean | Membership active | | `invitation_token` | String | Pending invitation token | | `invitation_accepted_at` | DateTime | When invitation was accepted | ### Role Permission roles for store team members. | Column | Type | Description | |--------|------|-------------| | `id` | Integer | Primary key | | `store_id` | Integer | FK to Store | | `name` | String | Role name (Manager, Staff, etc.) | | `permissions` | JSON | Array of permission strings | ## Supporting Entities ### AdminPlatform Links admin users to platforms they can manage. ### StorePlatform N:M bridge between stores and platforms. ### StoreDomain Custom domain configuration for stores. ### MerchantDomain Custom domain configuration for merchants. ### EmailVerificationToken Tokens for verifying email addresses during registration. ### UserPasswordResetToken Tokens for password reset flow. ### AdminAuditLog Audit trail for admin actions. ### AdminSession Active admin login sessions. ### AdminSetting Platform/store-level admin settings (key-value). ### PlatformAlert System alerts displayed to platform admins. ### PlatformModule Tracks which modules are enabled per platform. ### ApplicationLog Application log entries for the monitoring module. ## Key Relationships - A **Platform** has many **Merchants** (via StorePlatform) - A **Merchant** has many **Stores** and one **owner User** - A **Store** has many **StoreUsers** (team members) - A **StoreUser** has one **Role** (except owners who have all permissions) - **User.role** determines the user type: `super_admin` > `platform_admin` > `merchant_owner` > `store_member`