erp-core/docs/04-modelado/domain-models/billing-domain.md

309 lines
18 KiB
Markdown

# Modelo de Dominio: Billing (MGN-015)
**Módulo:** MGN-015 - Billing y Suscripciones SaaS
**Fecha:** 2025-12-06
**Estado:** ✅ Implementado
---
## Diagrama de Entidades
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ BILLING DOMAIN │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ subscription_plans │ │ tenants │ │
│ │ (Global) │ │ (from auth) │ │
│ ├──────────────────────┤ ├──────────────────────┤ │
│ │ id │ │ id │ │
│ │ code │◄────────│ │ │
│ │ name │ └──────────┬───────────┘ │
│ │ price_monthly │ │ │
│ │ price_yearly │ │ 1 │
│ │ max_users │ │ │
│ │ max_companies │ ▼ │
│ │ features (JSONB) │ ┌──────────────────────┐ │
│ └──────────┬───────────┘ │ subscriptions │ │
│ │ ├──────────────────────┤ │
│ │ 1 │ id │ │
│ │ │ tenant_id │──┐ │
│ ▼ │ plan_id │ │ │
│ ┌──────────────────────┐ │ status │ │ │
│ │ subscriptions │◄────────│ billing_cycle │ │ │
│ │ │ │ current_period_start │ │ │
│ └──────────────────────┘ │ current_period_end │ │ │
│ │ stripe_subscription_id│ │ │
│ └──────────┬───────────┘ │ │
│ │ │ │
│ │ 1 │ │
│ ▼ │ │
│ ┌──────────────────────┐ │ │
│ │ subscription_history │ │ │
│ ├──────────────────────┤ │ │
│ │ id │ │ │
│ │ subscription_id │ │ │
│ │ event_type │ │ │
│ │ previous_plan_id │ │ │
│ │ new_plan_id │ │ │
│ │ metadata (JSONB) │ │ │
│ └──────────────────────┘ │ │
│ │ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │ │
│ │ tenant_owners │ │ payment_methods │ │ │
│ ├──────────────────────┤ ├──────────────────────┤ │ │
│ │ id │ │ id │ │ │
│ │ tenant_id │◄────────│ tenant_id │◄─┤ │
│ │ user_id │ │ type │ │ │
│ │ ownership_type │ │ card_last_four │ │ │
│ │ billing_email │ │ card_brand │ │ │
│ └──────────────────────┘ │ is_default │ │ │
│ │ stripe_payment_method_id│ │ │
│ └──────────────────────┘ │ │
│ │ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │ │
│ │ invoices │ │ payments │ │ │
│ ├──────────────────────┤ ├──────────────────────┤ │ │
│ │ id │◄────────│ id │ │ │
│ │ tenant_id │◄────────│ tenant_id │◄─┤ │
│ │ subscription_id │ │ invoice_id │ │ │
│ │ invoice_number │ │ payment_method_id │ │ │
│ │ status │ │ amount │ │ │
│ │ subtotal │ │ status │ │ │
│ │ tax_amount │ │ paid_at │ │ │
│ │ total │ │ stripe_payment_intent_id│ │ │
│ │ cfdi_uuid │ └──────────────────────┘ │ │
│ └──────────┬───────────┘ │ │
│ │ │ │
│ │ 1..* │ │
│ ▼ │ │
│ ┌──────────────────────┐ │ │
│ │ invoice_lines │ │ │
│ ├──────────────────────┤ │ │
│ │ id │ │ │
│ │ invoice_id │ │ │
│ │ description │ │ │
│ │ quantity │ │ │
│ │ unit_price │ │ │
│ │ amount │ │ │
│ └──────────────────────┘ │ │
│ │ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │ │
│ │ coupons │ │ coupon_redemptions │ │ │
│ │ (Global) │ ├──────────────────────┤ │ │
│ ├──────────────────────┤ │ id │ │ │
│ │ id │◄────────│ coupon_id │ │ │
│ │ code │ │ tenant_id │◄─┤ │
│ │ discount_type │ │ subscription_id │ │ │
│ │ discount_value │ │ redeemed_at │ │ │
│ │ max_redemptions │ └──────────────────────┘ │ │
│ │ valid_from │ │ │
│ │ valid_until │ │ │
│ └──────────────────────┘ │ │
│ │ │
│ ┌──────────────────────┐ │ │
│ │ usage_records │ │ │
│ ├──────────────────────┤ │ │
│ │ id │ │ │
│ │ tenant_id │◄──────────────────────────────────┘ │
│ │ subscription_id │ │
│ │ metric_type │ │
│ │ quantity │ │
│ │ billing_period │ │
│ └──────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Entidades
### 1. subscription_plans (Planes de Suscripción)
**Propósito:** Define los planes disponibles para los tenants.
**Alcance:** Global (no tiene tenant_id)
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| id | UUID | Identificador único |
| code | VARCHAR(50) | Código único (free, basic, professional, enterprise) |
| name | VARCHAR(100) | Nombre del plan |
| price_monthly | DECIMAL | Precio mensual |
| price_yearly | DECIMAL | Precio anual |
| max_users | INTEGER | Límite de usuarios (NULL = ilimitado) |
| max_companies | INTEGER | Límite de empresas |
| max_storage_gb | INTEGER | Límite de almacenamiento |
| features | JSONB | Features habilitadas |
| trial_days | INTEGER | Días de prueba |
| is_default | BOOLEAN | Plan por defecto |
### 2. subscriptions (Suscripciones)
**Propósito:** Suscripción activa de cada tenant.
**Restricción:** Solo 1 suscripción por tenant.
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| id | UUID | Identificador único |
| tenant_id | UUID | FK a auth.tenants |
| plan_id | UUID | FK a subscription_plans |
| status | ENUM | trialing, active, past_due, paused, cancelled, suspended, expired |
| billing_cycle | ENUM | monthly, quarterly, semi_annual, annual |
| current_period_start | TIMESTAMP | Inicio del período actual |
| current_period_end | TIMESTAMP | Fin del período actual |
| stripe_subscription_id | VARCHAR | ID de Stripe |
### 3. tenant_owners (Propietarios)
**Propósito:** Usuarios que pueden gestionar billing del tenant.
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| tenant_id | UUID | FK a auth.tenants |
| user_id | UUID | FK a auth.users |
| ownership_type | VARCHAR | owner, billing_admin |
| billing_email | VARCHAR | Email de facturación |
### 4. payment_methods (Métodos de Pago)
**Propósito:** Métodos de pago registrados por tenant.
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| tenant_id | UUID | FK a auth.tenants |
| type | ENUM | card, bank_transfer, paypal, oxxo, spei |
| card_last_four | VARCHAR(4) | Últimos 4 dígitos |
| card_brand | VARCHAR | visa, mastercard, amex |
| is_default | BOOLEAN | Método por defecto |
| stripe_payment_method_id | VARCHAR | ID de Stripe |
### 5. invoices (Facturas)
**Propósito:** Facturas de suscripción.
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| tenant_id | UUID | FK a auth.tenants |
| invoice_number | VARCHAR | Número de factura |
| status | ENUM | draft, open, paid, void, uncollectible |
| subtotal | DECIMAL | Subtotal |
| tax_amount | DECIMAL | Impuestos |
| total | DECIMAL | Total |
| cfdi_uuid | VARCHAR | UUID del CFDI (México) |
### 6. payments (Pagos)
**Propósito:** Pagos recibidos.
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| tenant_id | UUID | FK a auth.tenants |
| invoice_id | UUID | FK a invoices |
| amount | DECIMAL | Monto pagado |
| status | ENUM | pending, processing, succeeded, failed, cancelled, refunded |
| stripe_payment_intent_id | VARCHAR | ID de Stripe |
### 7. coupons (Cupones)
**Propósito:** Cupones de descuento.
**Alcance:** Global
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| code | VARCHAR | Código del cupón |
| discount_type | VARCHAR | percent, fixed |
| discount_value | DECIMAL | Valor del descuento |
| max_redemptions | INTEGER | Máximo de usos |
| valid_from | TIMESTAMP | Válido desde |
| valid_until | TIMESTAMP | Válido hasta |
### 8. usage_records (Registros de Uso)
**Propósito:** Tracking de uso para billing por consumo.
| Atributo | Tipo | Descripción |
|----------|------|-------------|
| tenant_id | UUID | FK a auth.tenants |
| metric_type | VARCHAR | users, storage_gb, api_calls |
| quantity | DECIMAL | Cantidad consumida |
| billing_period | DATE | Período de facturación |
---
## Estados de Suscripción
```
┌─────────┐
│ trialing│
└────┬────┘
│ (trial ends)
┌─────────┐ ┌─────────┐ ┌─────────┐
│ paused │◄───│ active │───►│past_due │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ │ │ (payment fails)
│ ▼ ▼
│ ┌─────────┐ ┌─────────┐
└───────►│cancelled│ │suspended│
└─────────┘ └────┬────┘
┌─────────┐
│ expired │
└─────────┘
```
---
## Funciones de Negocio
### get_tenant_plan(tenant_id)
```sql
SELECT plan_code, plan_name, max_users, features, subscription_status
FROM billing.get_tenant_plan(tenant_id);
```
### can_add_user(tenant_id)
```sql
SELECT billing.can_add_user(tenant_id);
-- Returns: true/false
```
### has_feature(tenant_id, feature)
```sql
SELECT billing.has_feature(tenant_id, 'crm');
-- Returns: true/false
```
---
## Integración con Stripe
| Campo | Propósito |
|-------|-----------|
| stripe_customer_id | ID del customer en Stripe |
| stripe_subscription_id | ID de la suscripción en Stripe |
| stripe_payment_method_id | ID del método de pago |
| stripe_payment_intent_id | ID del payment intent |
| stripe_invoice_id | ID de la factura en Stripe |
---
## Features JSONB Structure
```json
{
"inventory": true,
"sales": true,
"financial": true,
"purchase": true,
"crm": false,
"projects": false,
"reports_basic": true,
"reports_advanced": false,
"api_access": false,
"white_label": false,
"priority_support": false
}
```
---
**Generado por:** Requirements-Analyst
**Fecha:** 2025-12-06