Files
orion/app/modules/billing/docs/data-model.md
Samir Boulahtit f141cc4e6a docs: migrate module documentation to single source of truth
Move 39 documentation files from top-level docs/ into each module's
docs/ folder, accessible via symlinks from docs/modules/. Create
data-model.md files for 10 modules with full schema documentation.
Replace originals with redirect stubs. Remove empty guide stubs.

Modules migrated: tenancy, billing, loyalty, marketplace, orders,
messaging, cms, catalog, inventory, hosting, prospecting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:38:37 +01:00

139 lines
5.5 KiB
Markdown

# Billing Data Model
## Entity Relationship Overview
```
┌───────────────────┐
│ SubscriptionTier │
└────────┬──────────┘
│ 1:N
┌───────────────────┐ ┌──────────────────────┐
│ TierFeatureLimit │ │ MerchantSubscription │
│ (feature limits) │ │ (per merchant+plat) │
└───────────────────┘ └──────────┬───────────┘
┌──────────┼──────────────┐
▼ ▼ ▼
┌────────────┐ ┌──────────┐ ┌─────────────┐
│ BillingHist│ │StoreAddOn│ │FeatureOverride│
└────────────┘ └──────────┘ └─────────────┘
┌────────────┐
│AddOnProduct│
└────────────┘
┌──────────────────────┐
│StripeWebhookEvent │ (idempotency tracking)
└──────────────────────┘
```
## Core Entities
### SubscriptionTier
Defines available subscription plans with pricing and Stripe integration.
| Column | Type | Description |
|--------|------|-------------|
| `id` | Integer | Primary key |
| `code` | String | Unique tier code (`essential`, `professional`, `business`, `enterprise`) |
| `name` | String | Display name |
| `price_monthly_cents` | Integer | Monthly price in cents |
| `price_annual_cents` | Integer | Annual price in cents (optional) |
| `stripe_product_id` | String | Stripe product ID |
| `stripe_price_monthly_id` | String | Stripe monthly price ID |
| `stripe_price_annual_id` | String | Stripe annual price ID |
| `display_order` | Integer | Sort order on pricing pages |
| `is_active` | Boolean | Available for subscription |
| `is_public` | Boolean | Visible to stores |
### TierFeatureLimit
Per-tier feature limits — each row links a tier to a feature code with a limit value.
| Column | Type | Description |
|--------|------|-------------|
| `id` | Integer | Primary key |
| `tier_id` | Integer | FK to SubscriptionTier |
| `feature_code` | String | Feature identifier (e.g., `max_products`) |
| `limit_value` | Integer | Numeric limit (NULL = unlimited) |
| `enabled` | Boolean | Whether feature is enabled for this tier |
### MerchantSubscription
Per-merchant+platform subscription state. Subscriptions are merchant-level, not store-level.
| Column | Type | Description |
|--------|------|-------------|
| `id` | Integer | Primary key |
| `merchant_id` | Integer | FK to Merchant |
| `platform_id` | Integer | FK to Platform |
| `tier_id` | Integer | FK to SubscriptionTier |
| `tier_code` | String | Tier code (denormalized for convenience) |
| `status` | SubscriptionStatus | `trial`, `active`, `past_due`, `cancelled`, `expired` |
| `stripe_customer_id` | String | Stripe customer ID |
| `stripe_subscription_id` | String | Stripe subscription ID |
| `trial_ends_at` | DateTime | Trial expiry |
| `period_start` | DateTime | Current billing period start |
| `period_end` | DateTime | Current billing period end |
### MerchantFeatureOverride
Per-merchant exceptions to tier defaults (e.g., enterprise custom limits).
| Column | Type | Description |
|--------|------|-------------|
| `id` | Integer | Primary key |
| `merchant_id` | Integer | FK to Merchant |
| `feature_code` | String | Feature identifier |
| `limit_value` | Integer | Override limit (NULL = unlimited) |
## Add-on Entities
### AddOnProduct
Purchasable add-on items (domains, SSL, email packages).
| Column | Type | Description |
|--------|------|-------------|
| `id` | Integer | Primary key |
| `code` | String | Unique add-on code |
| `name` | String | Display name |
| `category` | AddOnCategory | `domain`, `ssl`, `email` |
| `price_cents` | Integer | Price in cents |
| `billing_period` | BillingPeriod | `monthly` or `yearly` |
### StoreAddOn
Add-ons purchased by individual stores.
| Column | Type | Description |
|--------|------|-------------|
| `id` | Integer | Primary key |
| `store_id` | Integer | FK to Store |
| `addon_product_id` | Integer | FK to AddOnProduct |
| `config` | JSON | Configuration (e.g., domain name) |
| `stripe_subscription_item_id` | String | Stripe subscription item ID |
| `status` | String | `active`, `cancelled`, `pending_setup` |
## Supporting Entities
### BillingHistory
Invoice and payment history records.
### StripeWebhookEvent
Idempotency tracking for Stripe webhook events. Prevents duplicate event processing.
## Key Relationships
- A **SubscriptionTier** has many **TierFeatureLimits** (one per feature)
- A **Merchant** has one **MerchantSubscription** per Platform
- A **MerchantSubscription** references one **SubscriptionTier**
- A **Merchant** can have many **MerchantFeatureOverrides** (per-feature)
- A **Store** can purchase many **StoreAddOns**
- Feature limits are resolved: MerchantFeatureOverride > TierFeatureLimit > default