# TRACEABILITY-MGN-015: Billing y Suscripciones
# Matriz de trazabilidad entre requerimientos, especificaciones, y artefactos
# Fecha: 2025-11-24

module:
  id: MGN-015
  name: Billing y Suscripciones
  description: Gestión de suscripciones, pagos, facturación y límites para SaaS multi-tenant
  priority: P0
  total_story_points: 55

# Requerimientos Funcionales
requirements:
  - id: RF-MGN-015-001
    name: Gestión de Planes de Suscripción
    priority: P0
    story_points: 8
    document: ../requerimientos-funcionales/mgn-015/RF-MGN-015-001-gestion-planes-suscripcion.md
    specifications:
      backend:
        - ET-MGN-015-001
    database:
      tables:
        - billing.subscription_plans
      functions: []
      triggers: []
    api_endpoints:
      - GET /api/v1/billing/plans
      - GET /api/v1/billing/plans/:id
      - POST /api/v1/billing/plans
      - PUT /api/v1/billing/plans/:id
      - DELETE /api/v1/billing/plans/:id
      - PATCH /api/v1/billing/plans/:id/toggle
    actors:
      - super_admin
      - platform_admin
    dependencies:
      requires: []
      blocks:
        - RF-MGN-015-002

  - id: RF-MGN-015-002
    name: Gestión de Suscripciones de Tenant
    priority: P0
    story_points: 13
    document: ../requerimientos-funcionales/mgn-015/RF-MGN-015-002-gestion-suscripciones-tenant.md
    specifications:
      backend:
        - ET-MGN-015-002
    database:
      tables:
        - billing.subscriptions
        - billing.subscription_history
        - billing.tenant_owners
      functions:
        - billing.get_tenant_plan(tenant_id)
      triggers:
        - log_subscription_change
    api_endpoints:
      - GET /api/v1/billing/subscription
      - GET /api/v1/billing/subscriptions (admin)
      - POST /api/v1/billing/subscription/upgrade
      - POST /api/v1/billing/subscription/downgrade
      - POST /api/v1/billing/subscription/cancel
      - POST /api/v1/billing/subscription/reactivate
      - PUT /api/v1/billing/subscription/billing-cycle
      - GET /api/v1/billing/subscription/history
    actors:
      - tenant_owner
      - super_admin
      - system (renovaciones)
    dependencies:
      requires:
        - RF-MGN-015-001
      blocks:
        - RF-MGN-015-003
    jobs:
      - subscription-renewal.job.ts (diario)

  - id: RF-MGN-015-003
    name: Gestión de Métodos de Pago
    priority: P0
    story_points: 8
    document: ../requerimientos-funcionales/mgn-015/RF-MGN-015-003-metodos-pago.md
    specifications:
      backend:
        - ET-MGN-015-003
    database:
      tables:
        - billing.payment_methods
      functions: []
      triggers: []
    api_endpoints:
      - GET /api/v1/billing/payment-methods
      - POST /api/v1/billing/payment-methods/setup-intent
      - POST /api/v1/billing/payment-methods
      - PATCH /api/v1/billing/payment-methods/:id/default
      - DELETE /api/v1/billing/payment-methods/:id
    actors:
      - tenant_owner
    integrations:
      - name: Stripe
        type: payment_gateway
        endpoints:
          - PaymentMethods
          - SetupIntents
          - Customers
    webhooks:
      - POST /api/v1/webhooks/stripe
    dependencies:
      requires:
        - RF-MGN-015-002
      blocks:
        - RF-MGN-015-004

  - id: RF-MGN-015-004
    name: Facturación y Cobros
    priority: P0
    story_points: 13
    document: ../requerimientos-funcionales/mgn-015/RF-MGN-015-004-facturacion-cobros.md
    specifications:
      backend:
        - ET-MGN-015-004
    database:
      tables:
        - billing.invoices
        - billing.invoice_lines
        - billing.payments
      functions: []
      triggers:
        - update_invoice_totals
    api_endpoints:
      - GET /api/v1/billing/invoices
      - GET /api/v1/billing/invoices/:id
      - GET /api/v1/billing/invoices/:id/pdf
      - GET /api/v1/billing/invoices/:id/xml
      - POST /api/v1/billing/invoices/:id/request-cfdi
      - POST /api/v1/billing/invoices/:id/retry-payment
      - POST /api/v1/billing/invoices/:id/credit-note (admin)
    actors:
      - tenant_owner
      - super_admin
      - system (generación automática)
    integrations:
      - name: Stripe
        type: payment_gateway
        endpoints:
          - PaymentIntents
      - name: PAC
        type: cfdi_provider
        options:
          - Facturama
          - SW Sapien
          - Finkok
    dependencies:
      requires:
        - RF-MGN-015-002
        - RF-MGN-015-003
      blocks:
        - RF-MGN-015-005
    jobs:
      - invoice-generation.job.ts (diario)
      - payment-retry.job.ts (cada hora)

  - id: RF-MGN-015-005
    name: Registro de Uso y Métricas
    priority: P1
    story_points: 8
    document: ../requerimientos-funcionales/mgn-015/RF-MGN-015-005-registro-uso-metricas.md
    specifications:
      backend:
        - ET-MGN-015-005
    database:
      tables:
        - billing.usage_records
      functions:
        - billing.can_add_user(tenant_id)
        - billing.can_add_company(tenant_id)
        - billing.has_feature(tenant_id, feature)
        - billing.get_current_usage(tenant_id)
      triggers: []
    api_endpoints:
      - GET /api/v1/billing/usage
      - GET /api/v1/billing/usage/history
      - GET /api/v1/billing/usage/check
      - GET /api/v1/billing/features
      - GET /api/v1/billing/features/:feature
      - GET /api/v1/admin/billing/usage (admin)
    actors:
      - tenant_owner
      - admin
      - any_authenticated_user
      - super_admin
    middlewares:
      - checkUserLimit
      - checkCompanyLimit
      - requireFeature
    dependencies:
      requires:
        - RF-MGN-015-001
        - RF-MGN-015-002
      blocks: []
    jobs:
      - record-usage.job.ts (cada 6 horas)

  - id: RF-MGN-015-006
    name: Modo Single-Tenant
    priority: P1
    story_points: 5
    document: ../requerimientos-funcionales/mgn-015/RF-MGN-015-006-modo-single-tenant.md
    specifications:
      backend: []
    database:
      tables: []
      functions: []
      triggers: []
    api_endpoints: []
    actors:
      - system_admin (on-premise)
    configuration:
      env_vars:
        - DEPLOYMENT_MODE=single_tenant
        - DISABLE_PUBLIC_REGISTRATION=true
        - DISABLE_BILLING_UI=true
    dependencies:
      requires:
        - RF-MGN-015-001
      blocks: []

# Especificaciones Técnicas
specifications:
  backend:
    - id: ET-MGN-015-001
      name: API de Planes de Suscripción
      document: ../especificaciones-tecnicas/backend/mgn-015/ET-MGN-015-001-api-planes-suscripcion.md
      implements:
        - RF-MGN-015-001
      components:
        - src/modules/billing/plans/plans.controller.ts
        - src/modules/billing/plans/plans.service.ts
        - src/modules/billing/plans/plans.routes.ts
        - src/modules/billing/plans/plans.validation.ts

    - id: ET-MGN-015-002
      name: API de Suscripciones
      document: ../especificaciones-tecnicas/backend/mgn-015/ET-MGN-015-002-api-suscripciones.md
      implements:
        - RF-MGN-015-002
      components:
        - src/modules/billing/subscriptions/subscriptions.controller.ts
        - src/modules/billing/subscriptions/subscriptions.service.ts
        - src/modules/billing/subscriptions/subscriptions.routes.ts
        - src/modules/billing/subscriptions/subscriptions.validation.ts

    - id: ET-MGN-015-003
      name: API de Métodos de Pago
      document: ../especificaciones-tecnicas/backend/mgn-015/ET-MGN-015-003-api-metodos-pago.md
      implements:
        - RF-MGN-015-003
      components:
        - src/modules/billing/payment-methods/payment-methods.controller.ts
        - src/modules/billing/payment-methods/payment-methods.service.ts
        - src/modules/billing/payment-methods/payment-methods.routes.ts
        - src/modules/billing/payment-methods/payment-methods.validation.ts

    - id: ET-MGN-015-004
      name: API de Facturación
      document: ../especificaciones-tecnicas/backend/mgn-015/ET-MGN-015-004-api-facturacion.md
      implements:
        - RF-MGN-015-004
      components:
        - src/modules/billing/invoices/invoices.controller.ts
        - src/modules/billing/invoices/invoices.service.ts
        - src/modules/billing/invoices/invoices.routes.ts
        - src/modules/billing/invoices/invoices.validation.ts
        - src/modules/billing/services/pac.service.ts

    - id: ET-MGN-015-005
      name: API de Uso y Métricas
      document: ../especificaciones-tecnicas/backend/mgn-015/ET-MGN-015-005-api-uso-metricas.md
      implements:
        - RF-MGN-015-005
      components:
        - src/modules/billing/usage/usage.controller.ts
        - src/modules/billing/usage/usage.service.ts
        - src/modules/billing/usage/usage.routes.ts
        - src/shared/middleware/usage-limit.middleware.ts

# Base de Datos
database:
  schema: billing
  ddl_file: ../../../../apps/database/ddl/10-billing.sql

  tables:
    - name: billing.subscription_plans
      description: Definición de planes disponibles
      rls: false
      tenant_scoped: false
      columns_count: 17
      references:
        - RF-MGN-015-001

    - name: billing.tenant_owners
      description: Propietarios de cuenta por tenant
      rls: true
      tenant_scoped: true
      columns_count: 10
      references:
        - RF-MGN-015-002

    - name: billing.subscriptions
      description: Suscripciones activas por tenant
      rls: true
      tenant_scoped: true
      columns_count: 18
      references:
        - RF-MGN-015-002

    - name: billing.payment_methods
      description: Métodos de pago tokenizados
      rls: true
      tenant_scoped: true
      columns_count: 14
      references:
        - RF-MGN-015-003

    - name: billing.invoices
      description: Facturas generadas
      rls: true
      tenant_scoped: true
      columns_count: 22
      references:
        - RF-MGN-015-004

    - name: billing.invoice_lines
      description: Líneas de detalle de factura
      rls: true
      tenant_scoped: false
      columns_count: 10
      references:
        - RF-MGN-015-004

    - name: billing.payments
      description: Registro de pagos/transacciones
      rls: true
      tenant_scoped: true
      columns_count: 13
      references:
        - RF-MGN-015-004

    - name: billing.usage_records
      description: Métricas de uso por período
      rls: true
      tenant_scoped: true
      columns_count: 9
      references:
        - RF-MGN-015-005

    - name: billing.coupons
      description: Cupones de descuento
      rls: false
      tenant_scoped: false
      columns_count: 14
      references:
        - RF-MGN-015-004

    - name: billing.coupon_redemptions
      description: Cupones canjeados por tenant
      rls: true
      tenant_scoped: true
      columns_count: 6
      references:
        - RF-MGN-015-004

    - name: billing.subscription_history
      description: Historial de cambios de suscripción
      rls: true
      tenant_scoped: true
      columns_count: 10
      references:
        - RF-MGN-015-002

  enums:
    - billing.subscription_status
    - billing.billing_cycle
    - billing.payment_method_type
    - billing.invoice_status
    - billing.payment_status
    - billing.discount_type

  functions:
    - name: billing.get_tenant_plan
      params: "(tenant_id UUID)"
      returns: "billing.subscription_plans"
      description: Obtiene el plan actual del tenant
      references:
        - RF-MGN-015-002

    - name: billing.can_add_user
      params: "(tenant_id UUID)"
      returns: "BOOLEAN"
      description: Verifica si puede agregar usuario
      references:
        - RF-MGN-015-005

    - name: billing.can_add_company
      params: "(tenant_id UUID)"
      returns: "BOOLEAN"
      description: Verifica si puede agregar empresa
      references:
        - RF-MGN-015-005

    - name: billing.has_feature
      params: "(tenant_id UUID, feature VARCHAR)"
      returns: "BOOLEAN"
      description: Verifica si feature está habilitada
      references:
        - RF-MGN-015-005

    - name: billing.get_current_usage
      params: "(tenant_id UUID)"
      returns: "JSONB"
      description: Obtiene uso actual del tenant
      references:
        - RF-MGN-015-005

# Integraciones Externas
integrations:
  - id: INT-001
    name: Stripe
    type: payment_gateway
    required_for:
      - RF-MGN-015-003
      - RF-MGN-015-004
    config:
      env_vars:
        - STRIPE_SECRET_KEY
        - STRIPE_PUBLISHABLE_KEY
        - STRIPE_WEBHOOK_SECRET
    webhooks:
      - payment_method.updated
      - payment_method.card_automatically_updated
      - customer.source.expiring

  - id: INT-002
    name: PAC (CFDI)
    type: fiscal_provider
    required_for:
      - RF-MGN-015-004
    config:
      env_vars:
        - PAC_PROVIDER
        - PAC_USER
        - PAC_PASSWORD
        - PAC_SANDBOX
    options:
      - Facturama
      - SW Sapien
      - Finkok

# Jobs Programados
scheduled_jobs:
  - id: JOB-001
    name: subscription-renewal
    schedule: "0 1 * * *"  # Diario 01:00
    description: Procesa renovaciones de suscripciones
    references:
      - RF-MGN-015-002

  - id: JOB-002
    name: invoice-generation
    schedule: "0 0 * * *"  # Diario 00:00
    description: Genera facturas 1 día antes de renovación
    references:
      - RF-MGN-015-004

  - id: JOB-003
    name: payment-retry
    schedule: "0 * * * *"  # Cada hora
    description: Reintenta pagos fallidos (días 1, 3, 7)
    references:
      - RF-MGN-015-004

  - id: JOB-004
    name: record-usage
    schedule: "0 */6 * * *"  # Cada 6 horas
    description: Registra métricas de uso por tenant
    references:
      - RF-MGN-015-005

# Matriz de Trazabilidad Resumida
traceability_matrix:
  RF-MGN-015-001:
    specifications: [ET-MGN-015-001]
    tables: [billing.subscription_plans]
    endpoints: 6

  RF-MGN-015-002:
    specifications: [ET-MGN-015-002]
    tables: [billing.subscriptions, billing.subscription_history, billing.tenant_owners]
    endpoints: 8
    jobs: 1

  RF-MGN-015-003:
    specifications: [ET-MGN-015-003]
    tables: [billing.payment_methods]
    endpoints: 5
    integrations: [Stripe]

  RF-MGN-015-004:
    specifications: [ET-MGN-015-004]
    tables: [billing.invoices, billing.invoice_lines, billing.payments, billing.coupons, billing.coupon_redemptions]
    endpoints: 7
    jobs: 2
    integrations: [Stripe, PAC]

  RF-MGN-015-005:
    specifications: [ET-MGN-015-005]
    tables: [billing.usage_records]
    endpoints: 6
    jobs: 1
    functions: 4

  RF-MGN-015-006:
    specifications: []
    tables: []
    endpoints: 0
    config: [DEPLOYMENT_MODE, DISABLE_PUBLIC_REGISTRATION, DISABLE_BILLING_UI]

# Notas
notes:
  - Los planes (subscription_plans) son globales, no tienen tenant_id ni RLS
  - Todas las demás tablas tienen RLS y requieren tenant_id en el contexto
  - El modo single_tenant usa el plan "single_tenant" con todos los features habilitados
  - Las facturas y XMLs de CFDI deben mantenerse por mínimo 5 años
  - Nunca almacenar datos sensibles de tarjetas (PCI-DSS)
