openapi: 3.0.3
info:
  title: API Firma Digital - Imagina Energía
  description: |
    Endpoint para enviar contratos existentes a firma digital.
    
    Este endpoint permite enviar contratos ya creados en el sistema para que sean firmados digitalmente por el cliente mediante email, SMS u OTP por email.
    
    **Características principales:**
    - ✅ Envío síncrono (respuesta inmediata)
    - ✅ Múltiples canales de envío (email, SMS, email OTP)
    - ✅ Reenvío permitido (útil si el cliente no recibió la comunicación)
    - ✅ Persistencia automática en base de datos
    - ✅ Trazabilidad con request_id y referencia_externa
    
  version: 1.0.0
  contact:
    email: serviciosistemas@imaginaenergia.com

servers:
  - url: https://pre-webhooks.imaginaenergia.com
    description: Servidor de PRE
  - url: https://webhooks.imaginaenergia.com
    description: Servidor de PRO

security:
  - BearerAuth: []

paths:
  /firma:
    post:
      summary: Enviar Contrato a Firma Digital
      description: |
        Envía un contrato existente para firma digital del cliente.
        
        El contrato debe haber sido creado previamente mediante el endpoint de contratación.
        Este endpoint simplemente dispara el proceso de firma, enviando la comunicación al cliente por el canal especificado.
        
        **Flujo de uso típico:**
        1. Crear contrato mediante `/contrato/residencial` o `/contrato/empresa` (con `no_enviar_firma: true`)
        2. Obtener el `contrato_id` de la respuesta
        3. Llamar a `/firma` con el `contrato_id` y canal deseado
        4. El cliente recibe el email/SMS con el enlace de firma
        
        **Comportamiento:**
        - ✅ **Síncrono:** La respuesta se devuelve inmediatamente tras enviar la firma
        - ✅ **Reenvío permitido:** Puedes llamar múltiples veces para el mismo contrato
        - ✅ **Sin callback:** No soporta procesamiento asíncrono (la operación es rápida < 1s)
        
      tags:
        - Firma Digital
      operationId: postFirma
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [contrato_id, canal_envio, direcciones_firma]
              properties:
                contrato_id:
                  type: integer
                  description: |
                    ID del contrato en el sistema que se desea enviar a firma.
                    
                    Este ID se obtiene del campo `contrato_result.id` en la respuesta del endpoint de contratación.
                  example: 369877
                  minimum: 1
                canal_envio:
                  type: string
                  description: |
                    Canal por el cual se enviará la firma digital al cliente.
                    
                    **Valores permitidos:**
                    - `email`: Envío por correo electrónico (más común)
                    - `sms`: Envío por mensaje de texto SMS
                    - `email_otp`: Envío por email con código OTP (One-Time Password)
                  enum: [email, sms, email_otp]
                  example: "email"
                direcciones_firma:
                  type: string
                  description: |
                    Email del cliente, teléfono móvil, o ambos separados por punto y coma (`;`).
                    
                    **Formatos válidos:**
                    - Email solo: `usuario@example.com`
                    - Teléfono solo: `606123456` o `+34606123456`
                    - Ambos: `usuario@example.com;606123456`
                    
                    **Validaciones:**
                    - Email: Formato RFC estándar (nombre@dominio.tld)
                    - Teléfono: 8-15 dígitos, opcional prefijo `+`
                  example: "cliente@example.com"
                  pattern: '^([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}|\+?[0-9]{8,15})(;([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}|\+?[0-9]{8,15}))?$'
                referencia_externa:
                  type: string
                  description: |
                    Referencia opcional del cliente para tracking interno.
                    
                    Este campo se devuelve en la respuesta y se almacena en la base de datos para trazabilidad.
                    Útil para vincular con IDs de CRM, tickets de soporte, o procesos internos.
                  example: "CRM-DEAL-12345"
                  maxLength: 255
            examples:
              email_simple:
                summary: Envío por email
                value:
                  contrato_id: 369877
                  canal_envio: "email"
                  direcciones_firma: "cliente@example.com"
                  referencia_externa: "REF-001"
              sms:
                summary: Envío por SMS
                value:
                  contrato_id: 369877
                  canal_envio: "sms"
                  direcciones_firma: "606123456"
              email_otp:
                summary: Email con OTP (Dual)
                value:
                  contrato_id: 369877
                  canal_envio: "email_otp"
                  direcciones_firma: "cliente@example.com;606123456"
              reenvio:
                summary: Reenvío de firma (cliente no recibió)
                value:
                  contrato_id: 369877
                  canal_envio: "email"
                  direcciones_firma: "cliente@example.com"
                  referencia_externa: "REENVIO-001"
      responses:
        '200':
          description: Firma enviada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  request_id:
                    type: integer
                    description: ID único del request en la base de datos webhooks.request_firma
                    example: 12345
                  firma_result:
                    type: object
                    description: Respuesta completa del sistema de gestión
                    properties:
                      status:
                        type: string
                        example: "success"
                      message:
                        type: string
                        example: "Contrato enviado para firma digital"
                  referencia_externa:
                    type: string
                    nullable: true
                    description: Referencia externa proporcionada en el request (si se envió)
                    example: "REF-001"
              examples:
                success:
                  summary: Respuesta exitosa
                  value:
                    request_id: 12345
                    firma_result:
                      status: "success"
                      message: "Contrato enviado para firma digital"
                    referencia_externa: "REF-001"
        '400':
          description: Error de validación en los parámetros
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missing_contrato_id:
                  summary: Falta contrato_id
                  value:
                    error: "Error de validación: El parámetro 'contrato_id' es requerido"
                    request_id: 12345
                    referencia_externa: null
                invalid_contrato_id:
                  summary: contrato_id inválido
                  value:
                    error: "Error de validación: El parámetro 'contrato_id' debe ser un número entero, recibido: abc"
                    request_id: 12345
                    referencia_externa: null
                missing_canal_envio:
                  summary: Falta canal_envio
                  value:
                    error: "Error de validación: El parámetro 'canal_envio' es requerido"
                    request_id: 12345
                    referencia_externa: "REF-001"
                invalid_canal_envio:
                  summary: canal_envio inválido
                  value:
                    error: "Error de validación: canal_envio debe ser uno de los siguientes: ['email', 'sms', 'email_otp']"
                    request_id: 12345
                    referencia_externa: "REF-001"
                missing_direcciones:
                  summary: Falta direcciones_firma
                  value:
                    error: "Error de validación: El parámetro 'direcciones_firma' es requerido"
                    request_id: 12345
                    referencia_externa: "REF-001"
                invalid_email_format:
                  summary: Formato de email inválido
                  value:
                    error: "Error de validación: Formato inválido en 'cliente@invalid'. Debe ser un email válido o teléfono válido (8-15 dígitos)"
                    request_id: 12345
                    referencia_externa: "REF-001"
                invalid_phone_format:
                  summary: Formato de teléfono inválido
                  value:
                    error: "Error de validación: Formato inválido en '123'. Debe ser un email válido o teléfono válido (8-15 dígitos)"
                    request_id: 12345
                    referencia_externa: "REF-001"
                invalid_json:
                  summary: JSON malformado
                  value:
                    error: "Error de request, no se reconoce el cuerpo JSON: Expecting value: line 1 column 1 (char 0)"
                    request_id: null
        '401':
          description: Error de autenticación (JWT inválido o faltante)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: "Authentication failed"
              examples:
                no_token:
                  summary: Token no proporcionado
                  value:
                    error: "Authentication failed"
                invalid_token:
                  summary: Token JWT inválido o expirado
                  value:
                    error: "Authentication failed"
        '404':
          description: Contrato no encontrado en el sistema
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                contrato_not_found:
                  summary: Contrato no existe
                  value:
                    error: "Error en firma digital: Error sending contract for signature: 404 Client Error: Not Found"
                    request_id: 12345
                    referencia_externa: "REF-001"
        '500':
          description: Error interno del servidor o comunicación con el sistema de gestión
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                api_error:
                  summary: Error en el sistema
                  value:
                    error: "Error en firma digital: Error sending contract for signature: 502 Bad Gateway"
                    request_id: 12345
                    referencia_externa: "REF-001"
                api_unavailable:
                  summary: Sistema no disponible
                  value:
                    error: "Error en firma digital: API_BASE_URL no está configurada en las variables de entorno"
                    request_id: 12345
                    referencia_externa: "REF-001"
                unexpected_error:
                  summary: Error inesperado
                  value:
                    error: "Error inesperado: Database connection failed"
                    request_id: 12345
                    referencia_externa: "REF-001"
  
  /firma/health:
    get:
      summary: Health Check del Servicio de Firma
      description: |
        Endpoint de verificación del estado del servicio de firma.
        
        Útil para monitoreo y health checks. No requiere autenticación.
      tags:
        - Firma Digital
      operationId: getFirmaHealth
      security: []
      responses:
        '200':
          description: Servicio disponible
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "ok"
                  service:
                    type: string
                    example: "firma"
                  message:
                    type: string
                    example: "Servicio de firma digital disponible"

components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Descripción del error ocurrido
        request_id:
          type: integer
          nullable: true
          description: ID del request en base de datos (null si el error ocurrió antes de persistir)
        referencia_externa:
          type: string
          nullable: true
          description: Referencia externa proporcionada en el request (si se envió)
      required:
        - error
  
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        Token JWT obtenido mediante el endpoint de autenticación.
        
        **Header requerido:**
        ```
        Authorization: Bearer {tu_token_jwt}
        ```
        
        El token se valida y extrae información del canal (sub, canal_id, canal_nombre, canal_api_token).

tags:
  - name: Firma Digital
    description: Operaciones relacionadas con el envío de contratos a firma digital
