# TRACEABILITY.yml - OQI-005 Pagos y Stripe
# Mapeo de requerimientos a implementación

version: "1.1.0"
epic: OQI-005
name: "Sistema de Pagos con Stripe"
updated: "2026-01-25"
status: in_progress

# Resumen de trazabilidad
summary:
  total_requirements: 6
  total_specs: 6
  total_user_stories: 10
  total_files_to_implement: 35
  test_coverage: "TBD"
  story_points: 40

# Mapeo de Requerimientos Funcionales
requirements:
  RF-PAY-001:
    name: "Suscripciones"
    status: pending
    specs:
      - ET-PAY-001
      - ET-PAY-002
    user_stories:
      - US-PAY-001
      - US-PAY-002
    implementation:
      backend:
        - path: apps/backend/src/modules/payments/services/subscription.service.ts
          description: "Servicio de suscripciones"
          methods:
            - getPlans
            - createSubscription
            - cancelSubscription
            - updateSubscription
            - getActiveSubscription
            - resumeSubscription
        - path: apps/backend/src/modules/payments/controllers/payments.controller.ts
          methods:
            - getPlans
            - subscribe
            - cancelSubscription
            - getMySubscription
        - path: apps/backend/src/modules/payments/payments.routes.ts
          routes:
            - "GET /payments/plans"
            - "POST /payments/subscribe"
            - "GET /payments/subscription"
            - "DELETE /payments/subscription"
            - "POST /payments/subscription/resume"
      frontend:
        - path: apps/frontend/src/modules/settings/pages/Billing.tsx
          description: "Página de facturación"
        - path: apps/frontend/src/modules/payments/components/PlanSelector.tsx
          description: "Selector de planes"
        - path: apps/frontend/src/modules/payments/components/SubscriptionCard.tsx
          description: "Tarjeta de suscripción"
        - path: apps/frontend/src/modules/payments/components/PlanComparison.tsx
          description: "Comparador de planes"
      database:
        - path: apps/database/schemas/05_financial_schema.sql
          tables:
            - subscription_plans
            - subscriptions
            - subscription_features
          enums:
            - plan_interval_enum
            - subscription_status_enum
    external:
      - service: Stripe Subscriptions
        usage: "Gestión de suscripciones recurrentes"
    tests:
      - path: apps/backend/tests/payments/subscription.service.test.ts
        status: pending

  RF-PAY-002:
    name: "Checkout"
    status: in_progress
    specs:
      - ET-PAY-002
      - ET-PAY-005
    user_stories:
      - US-PAY-005
    implementation:
      backend:
        - path: apps/backend/src/modules/payments/services/checkout.service.ts
          description: "Servicio de checkout"
          methods:
            - createCheckoutSession
            - getCheckoutSession
            - processPayment
            - handleSuccess
            - handleCancel
        - path: apps/backend/src/modules/payments/controllers/payments.controller.ts
          methods:
            - createCheckout
            - getCheckoutStatus
        - path: apps/backend/src/modules/payments/payments.routes.ts
          routes:
            - "POST /payments/checkout"
            - "GET /payments/checkout/:sessionId"
            - "GET /payments/checkout/success"
            - "GET /payments/checkout/cancel"
      frontend:
        - path: apps/frontend/src/modules/payments/pages/Checkout.tsx
          description: "Página de checkout"
        - path: apps/frontend/src/modules/payments/pages/CheckoutSuccess.tsx
          description: "Página de éxito"
        - path: apps/frontend/src/modules/payments/pages/CheckoutCancel.tsx
          description: "Página de cancelación"
        - path: apps/frontend/src/modules/payments/components/CheckoutForm.tsx
          description: "Formulario de checkout"
        - path: apps/frontend/src/components/payments/StripeElementsWrapper.tsx
          description: "Wrapper PCI-DSS compliant para Stripe Elements"
          status: done
          created: "2026-01-25"
          loc: 220
          exports:
            - StripeElementsWrapper
            - withStripeElements
            - useStripeAvailable
          types:
            - StripeConfig
        - path: apps/frontend/src/components/payments/InvoicePreview.tsx
          description: "Vista previa de factura pre-checkout"
          status: done
          created: "2026-01-25"
          loc: 350
          types:
            - InvoiceLineItem
            - InvoiceDiscount
            - InvoiceTax
            - InvoicePreviewData
      database:
        - path: apps/database/schemas/05_financial_schema.sql
          tables:
            - checkout_sessions
            - purchases
          enums:
            - checkout_status_enum
            - purchase_type_enum
    external:
      - service: Stripe Checkout
        usage: "Checkout hosted por Stripe"
    tests:
      - path: apps/backend/tests/payments/checkout.service.test.ts
        status: pending
    tasks:
      - id: TASK-2026-01-25-OQI-005-PAYMENTS-ADVANCED
        description: "StripeElementsWrapper e InvoicePreview"
        status: done

  RF-PAY-003:
    name: "Wallet Digital"
    status: pending
    specs:
      - ET-PAY-001
      - ET-PAY-004
    user_stories: []
    implementation:
      backend:
        - path: apps/backend/src/modules/payments/services/wallet.service.ts
          description: "Servicio de wallet"
          methods:
            - getWallet
            - addFunds
            - withdrawFunds
            - transferFunds
            - getTransactions
            - getBalance
        - path: apps/backend/src/modules/payments/controllers/payments.controller.ts
          methods:
            - getWallet
            - addToWallet
            - withdrawFromWallet
            - getWalletHistory
        - path: apps/backend/src/modules/payments/payments.routes.ts
          routes:
            - "GET /payments/wallet"
            - "POST /payments/wallet/add"
            - "POST /payments/wallet/withdraw"
            - "GET /payments/wallet/transactions"
      frontend:
        - path: apps/frontend/src/modules/payments/components/WalletCard.tsx
          description: "Tarjeta de wallet"
        - path: apps/frontend/src/modules/payments/components/AddFundsModal.tsx
          description: "Modal para agregar fondos"
        - path: apps/frontend/src/modules/payments/components/WalletHistory.tsx
          description: "Historial de wallet"
      database:
        - path: apps/database/schemas/05_financial_schema.sql
          tables:
            - wallets
            - wallet_transactions
          enums:
            - wallet_transaction_type_enum
    tests:
      - path: apps/backend/tests/payments/wallet.service.test.ts
        status: pending

  RF-PAY-004:
    name: "Facturación"
    status: pending
    specs:
      - ET-PAY-004
    user_stories:
      - US-PAY-007
    implementation:
      backend:
        - path: apps/backend/src/modules/payments/services/invoice.service.ts
          description: "Servicio de facturación"
          methods:
            - getInvoices
            - getInvoiceById
            - downloadInvoice
            - sendInvoice
            - generateInvoicePDF
        - path: apps/backend/src/modules/payments/controllers/payments.controller.ts
          methods:
            - getInvoices
            - getInvoice
            - downloadInvoice
        - path: apps/backend/src/modules/payments/payments.routes.ts
          routes:
            - "GET /payments/invoices"
            - "GET /payments/invoices/:id"
            - "GET /payments/invoices/:id/download"
      frontend:
        - path: apps/frontend/src/modules/payments/components/InvoiceList.tsx
          description: "Lista de facturas"
        - path: apps/frontend/src/modules/payments/components/InvoiceCard.tsx
          description: "Tarjeta de factura"
      database:
        - path: apps/database/schemas/05_financial_schema.sql
          tables:
            - invoices
            - invoice_items
          enums:
            - invoice_status_enum
    tests:
      - path: apps/backend/tests/payments/invoice.service.test.ts
        status: pending

  RF-PAY-005:
    name: "Webhooks de Stripe"
    status: pending
    specs:
      - ET-PAY-003
    user_stories: []
    implementation:
      backend:
        - path: apps/backend/src/modules/payments/services/webhook.service.ts
          description: "Servicio de webhooks"
          methods:
            - handleWebhook
            - verifySignature
            - processPaymentIntent
            - processSubscription
            - processInvoice
            - processDispute
        - path: apps/backend/src/modules/payments/controllers/payments.controller.ts
          methods:
            - handleStripeWebhook
        - path: apps/backend/src/modules/payments/payments.routes.ts
          routes:
            - "POST /payments/webhook"
        - path: apps/backend/src/modules/payments/handlers/webhook.handlers.ts
          description: "Handlers por tipo de evento"
      database:
        - path: apps/database/schemas/05_financial_schema.sql
          tables:
            - webhook_events
          enums:
            - webhook_event_type_enum
    tests:
      - path: apps/backend/tests/payments/webhook.service.test.ts
        status: pending

  RF-PAY-006:
    name: "Reembolsos"
    status: in_progress
    specs:
      - ET-PAY-002
      - ET-PAY-006
    user_stories: []
    implementation:
      backend:
        - path: apps/backend/src/modules/payments/services/refund.service.ts
          description: "Servicio de reembolsos"
          methods:
            - requestRefund
            - processRefund
            - getRefunds
            - cancelRefund
        - path: apps/backend/src/modules/payments/controllers/payments.controller.ts
          methods:
            - requestRefund
            - getRefunds
        - path: apps/backend/src/modules/payments/payments.routes.ts
          routes:
            - "POST /payments/refunds"
            - "GET /payments/refunds"
            - "GET /payments/refunds/:id"
      frontend:
        - path: apps/frontend/src/components/payments/RefundRequestModal.tsx
          description: "Modal de solicitud de reembolso"
          status: done
          created: "2026-01-25"
          loc: 480
          types:
            - RefundEligibility
            - RefundRequestData
            - RefundReason
        - path: apps/frontend/src/components/payments/RefundList.tsx
          description: "Lista paginada de reembolsos con filtros"
          status: done
          created: "2026-01-25"
          loc: 450
          types:
            - Refund
            - RefundStatus
      database:
        - path: apps/database/schemas/05_financial_schema.sql
          tables:
            - refunds
          enums:
            - refund_status_enum
            - refund_reason_enum
    external:
      - service: Stripe Refunds
        usage: "Procesamiento de reembolsos"
    tests:
      - path: apps/backend/tests/payments/refund.service.test.ts
        status: pending
    tasks:
      - id: TASK-2026-01-25-OQI-005-PAYMENTS-ADVANCED
        description: "Frontend components para reembolsos"
        status: done

# Métodos de pago soportados
payment_methods:
  - type: card
    brands: [visa, mastercard, amex]
    regions: [global]
  - type: bank_transfer
    brands: [spei]
    regions: [mexico]
  - type: wallet
    brands: [apple_pay, google_pay]
    regions: [global]
  - type: oxxo
    brands: [oxxo]
    regions: [mexico]

# Planes de suscripción
subscription_plans:
  - code: FREE
    name: "Free"
    price: 0
    interval: month
    features:
      - "Acceso básico a charts"
      - "1 watchlist"
      - "Paper trading limitado"
  - code: PRO
    name: "Pro Trader"
    price: 499
    currency: MXN
    interval: month
    features:
      - "Charts avanzados"
      - "Watchlists ilimitadas"
      - "Paper trading completo"
      - "Señales ML básicas"
  - code: PREMIUM
    name: "Premium"
    price: 999
    currency: MXN
    interval: month
    features:
      - "Todo de Pro"
      - "Señales ML premium"
      - "Copilot AI"
      - "Soporte prioritario"
  - code: ENTERPRISE
    name: "Enterprise"
    price: custom
    interval: month
    features:
      - "Todo de Premium"
      - "API access"
      - "White-label"
      - "SLA dedicado"

# Mapeo de archivos de configuración
config_files:
  backend:
    - path: apps/backend/src/modules/payments/payments.module.ts
      description: "Módulo de pagos"
    - path: apps/backend/src/modules/payments/validators/payments.validators.ts
      description: "Validadores Zod"
    - path: apps/backend/src/modules/payments/types/payments.types.ts
      description: "Tipos TypeScript"
    - path: apps/backend/src/config/stripe.config.ts
      description: "Configuración de Stripe"
  frontend:
    - path: apps/frontend/src/modules/payments/stores/payments.store.ts
      description: "Store de pagos Zustand"
    - path: apps/frontend/src/modules/payments/hooks/usePayments.ts
      description: "Hook principal de pagos"
    - path: apps/frontend/src/modules/payments/services/payments.api.ts
      description: "Cliente API de pagos"

# Dependencias externas
external_dependencies:
  npm_backend:
    - name: stripe
      version: "^14.0.0"
      usage: "SDK de Stripe"
    - name: pdfkit
      version: "^0.14.0"
      usage: "Generación de facturas PDF"
  npm_frontend:
    - name: "@stripe/stripe-js"
      version: "^2.2.0"
      usage: "Stripe.js"
    - name: "@stripe/react-stripe-js"
      version: "^2.4.0"
      usage: "Componentes React de Stripe"

# APIs de terceros
third_party_apis:
  - name: Stripe API
    docs: https://stripe.com/docs/api
    usage:
      - Payment Intents
      - Customers
      - Subscriptions
      - Invoices
      - Webhooks
      - Refunds
      - Payment Methods
  - name: Stripe Checkout
    docs: https://stripe.com/docs/payments/checkout
    usage:
      - Hosted checkout pages
      - One-time payments
      - Subscription checkout

# Endpoints API
api_endpoints:
  base_path: /api/v1/payments
  endpoints:
    # Planes
    - method: GET
      path: /plans
      requirement: RF-PAY-001
      auth: false
    # Suscripciones
    - method: POST
      path: /subscribe
      requirement: RF-PAY-001
      auth: true
    - method: GET
      path: /subscription
      requirement: RF-PAY-001
      auth: true
    - method: DELETE
      path: /subscription
      requirement: RF-PAY-001
      auth: true
    # Checkout
    - method: POST
      path: /checkout
      requirement: RF-PAY-002
      auth: true
    - method: GET
      path: /checkout/:sessionId
      requirement: RF-PAY-002
      auth: true
    # Wallet
    - method: GET
      path: /wallet
      requirement: RF-PAY-003
      auth: true
    - method: POST
      path: /wallet/add
      requirement: RF-PAY-003
      auth: true
    - method: POST
      path: /wallet/withdraw
      requirement: RF-PAY-003
      auth: true
    # Facturas
    - method: GET
      path: /invoices
      requirement: RF-PAY-004
      auth: true
    - method: GET
      path: /invoices/:id/download
      requirement: RF-PAY-004
      auth: true
    # Webhooks
    - method: POST
      path: /webhook
      requirement: RF-PAY-005
      auth: false
      note: "Verificación por signature"
    # Reembolsos
    - method: POST
      path: /refunds
      requirement: RF-PAY-006
      auth: true
    # Métodos de pago
    - method: GET
      path: /payment-methods
      requirement: RF-PAY-002
      auth: true
    - method: POST
      path: /payment-methods
      requirement: RF-PAY-002
      auth: true
    - method: DELETE
      path: /payment-methods/:id
      requirement: RF-PAY-002
      auth: true

# Webhook events
webhook_events:
  - event: payment_intent.succeeded
    handler: handlePaymentSuccess
  - event: payment_intent.payment_failed
    handler: handlePaymentFailed
  - event: customer.subscription.created
    handler: handleSubscriptionCreated
  - event: customer.subscription.updated
    handler: handleSubscriptionUpdated
  - event: customer.subscription.deleted
    handler: handleSubscriptionCancelled
  - event: invoice.paid
    handler: handleInvoicePaid
  - event: invoice.payment_failed
    handler: handleInvoiceFailed
  - event: charge.refunded
    handler: handleRefund
  - event: charge.dispute.created
    handler: handleDispute

# Dependencias de épicas
dependencies:
  blocks:
    - epic: OQI-002
      reason: "Compra de cursos"
      type: partial
    - epic: OQI-004
      reason: "Depósitos en cuentas de inversión"
  blocked_by:
    - epic: OQI-001
      reason: "Requiere autenticación de usuarios"

# Notas y decisiones
notes:
  - "Stripe como único proveedor de pagos inicial"
  - "OXXO habilitado solo para México"
  - "Webhooks con retry automático y idempotency"
  - "Precios en MXN con conversión automática"
  - "Facturas generadas automáticamente"
  - "Período de gracia de 3 días para suscripciones fallidas"
  - "Reembolsos procesados en 5-10 días hábiles"
