openapi: 3.0.3
info:
  title: API Gestión de Firma Digital - Imagina Energía
  description: |
    Endpoints para gestionar el ciclo de vida de solicitudes de firma digital.
    
    Estos endpoints te permiten:
    - 🔄 **Reenviar solicitudes** de firma (recordatorios)
    - 🔍 **Consultar el estado** de procesos de firma en tiempo real
    - 👥 **Obtener información** detallada de todos los firmantes
    - � **Auditar el proceso** con datos de fecha/hora de firma
    
    **Características principales:**
    - ✅ Respuestas síncronas (< 2 segundos)
    - ✅ Validación automática de permisos por canal
    - ✅ Información detallada de firmantes y sus estados
    - ✅ Notificaciones automáticas cuando se completa la firma
    
    **Requisitos previos:**
    - El contrato debe haber sido enviado a firma previamente con `POST /firma`
    - Debes tener el `circuito_id` que se devolvió en la respuesta inicial
    - Tu canal JWT debe tener permisos sobre el contrato asociado
    
  version: 1.0.0
  contact:
    email: api.agentes@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/reenviar:
    post:
      summary: Reenviar Solicitud de Firma
      description: |
        Reenvía una solicitud de firma existente al cliente.
        
        **Casos de uso:**
        - El cliente no recibió el email/SMS inicial
        - Necesitas enviar un recordatorio de firma pendiente
        - El enlace original expiró y necesitas generar uno nuevo
        
        **Validación de permisos:**
        El sistema verifica automáticamente que tu canal JWT tenga autorización sobre el contrato asociado al `circuito_id`. Si no tienes permisos, recibirás un error 403.
        
        **Comportamiento:**
        - ✅ **Síncrono:** Respuesta inmediata tras enviar el recordatorio
        - ✅ **Sin límite de reenvíos:** Puedes llamarlo las veces necesarias
        - ⚠️ **Buenas prácticas:** Evita reenviar muy frecuentemente (mín. 1 hora entre reenvíos)
        
      tags:
        - Gestión de Firma
      operationId: postReenviarFirma
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [circuito_id]
              properties:
                circuito_id:
                  type: string
                  description: |
                    ID de la solicitud de firma en el sistema.
                    
                    Este ID se obtiene del campo `firma_result.circuito_id` en la respuesta de `POST /firma`.
                  example: "123456"
                mode:
                  type: string
                  description: |
                    Modo de firma a utilizar en el reenvío.
                    
                    **Valores permitidos:**
                    - `ds`: Drawing Signature (firma dibujada) - más común
                    - `os`: One-Time Certificate (certificado de un solo uso)
                    - `ud`: Upload & Draw (subir documento y firma dibujada)
                    
                    Por defecto: `ds`
                  enum: [ds, os, ud]
                  default: ds
                  example: "ds"
                referencia_externa:
                  type: string
                  maxLength: 100
                  description: |
                    Tu referencia interna para tracking de esta operación.
                    
                    Útil para debugging y trazabilidad en tus logs.
                  example: "REENVIO-2024-001"
            examples:
              basico:
                summary: Reenvío básico
                value:
                  circuito_id: "123456"
              completo:
                summary: Reenvío con referencia
                value:
                  circuito_id: "123456"
                  mode: "ds"
                  referencia_externa: "REENVIO-2024-001"
      responses:
        '200':
          description: Solicitud reenviada exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  request_id:
                    type: integer
                    description: ID interno del request para trazabilidad
                    example: 789
                  circuito_id:
                    type: string
                    description: ID de la solicitud de firma
                    example: "123456"
                  estado:
                    type: string
                    description: Estado de la operación de reenvío
                    example: "reenviada"
                  mensaje:
                    type: string
                    description: Mensaje descriptivo del resultado
                    example: "Solicitud de firma reenviada exitosamente"
                  referencia_externa:
                    type: string
                    nullable: true
                    description: Tu referencia interna si fue proporcionada
                    example: "REENVIO-2024-001"
              examples:
                success:
                  summary: Respuesta exitosa
                  value:
                    request_id: 789
                    circuito_id: "123456"
                    estado: "reenviada"
                    mensaje: "Solicitud de firma reenviada exitosamente"
                    referencia_externa: "REENVIO-2024-001"
        '400':
          description: Parámetros inválidos o faltantes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "El parámetro circuito_id es requerido"
                request_id: 790
        '401':
          description: Token JWT ausente o inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Authentication failed"
        '403':
          description: Sin permisos sobre el circuito_id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Canal 'mi-canal' no autorizado para circuito_id '123456'. Este circuito pertenece al canal 'otro-canal'"
                request_id: 791
                circuito_id: "123456"
        '404':
          description: Circuito_id no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Circuito no encontrado"
                request_id: 792
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /firma/health:
    get:
      summary: Health Check del Servicio de Gestión de Firma
      description: |
        Endpoint de verificación del estado del servicio de gestión de firma.
        
        Útil para monitoreo y health checks. No requiere autenticación.
      tags:
        - Gestión de Firma
      operationId: getFirmaHealth
      security: []
      responses:
        '200':
          description: Servicio disponible
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: Estado del servicio
                    example: "ok"
                  service:
                    type: string
                    description: Nombre del servicio
                    example: "evidence-api"
                  version:
                    type: string
                    description: Versión del servicio
                    example: "1.0.0"
              example:
                status: "ok"
                service: "evidence-api"
                version: "1.0.0"

  /firma/{circuito_id}:
    get:
      summary: Consultar Estado de Firma
      description: |
        Obtiene información detallada del estado actual de una solicitud de firma.
        
        **Información incluida:**
        - 📊 Estado general de la solicitud (pendiente, en_proceso, completado, rechazado)
        - 👥 Listado completo de firmantes con su estado individual
        - ✅ Quién ha firmado y quién está pendiente
        - 📅 Fecha/hora exacta de inicio y completado del proceso
        - 📅 Fecha/hora de cada firma individual
        
        **Validación de permisos:**
        El sistema verifica que tu canal JWT tenga autorización sobre el contrato asociado.
        
        **Notificación automática:**
        Cuando todos los firmantes completan su firma:
        - El contrato cambia a Estado: 1, Subestado: 50 (Firmado)
        - Se envía un webhook automático si tienes configuradas notificaciones
        
      tags:
        - Gestión de Firma
      operationId: getEstadoFirma
      parameters:
        - name: circuito_id
          in: path
          required: true
          description: ID de la solicitud de firma
          schema:
            type: string
          example: "123456"
        - name: referencia_externa
          in: query
          required: false
          description: Tu referencia interna para tracking
          schema:
            type: string
            maxLength: 100
          example: "CONSULTA-001"
      responses:
        '200':
          description: Estado obtenido exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  request_id:
                    type: integer
                    description: ID interno del request para trazabilidad
                    example: 790
                  circuito_id:
                    type: string
                    description: ID de la solicitud de firma
                    example: "123456"
                  estado:
                    type: string
                    description: Estado general de la solicitud
                    enum: [pendiente, en_proceso, completado, rechazado]
                    example: "en_proceso"
                  en_proceso:
                    type: boolean
                    description: Indica si al menos un firmante ha iniciado el proceso
                    example: true
                  fecha_inicio:
                    type: string
                    format: date-time
                    description: Fecha y hora de inicio del proceso de firma (formato ISO 8601)
                    example: "2024-06-09T10:30:00+02:00"
                  fecha_completado:
                    type: string
                    format: date-time
                    nullable: true
                    description: Fecha y hora de completado (null si aún no completado)
                    example: null
                  firmantes:
                    type: array
                    description: Listado de todos los firmantes
                    items:
                      type: object
                      properties:
                        email:
                          type: string
                          format: email
                          description: Email del firmante
                          example: "juan.perez@example.com"
                        estado:
                          type: string
                          description: Estado del firmante
                          enum: [firmado, pendiente]
                          example: "firmado"
                        fecha_firma:
                          type: string
                          format: date-time
                          nullable: true
                          description: Timestamp ISO 8601 de cuándo firmó (null si no ha firmado)
                          example: "2024-06-09T15:45:32+02:00"
                  referencia_externa:
                    type: string
                    nullable: true
                    description: Tu referencia interna si fue proporcionada
                    example: "CONSULTA-001"
              examples:
                en_proceso:
                  summary: Proceso en curso (firmante pendiente)
                  value:
                    request_id: 790
                    circuito_id: "123456"
                    estado: "en_proceso"
                    en_proceso: true
                    fecha_inicio: "2024-06-09T10:30:00+02:00"
                    fecha_completado: null
                    firmantes:
                      - email: "juan.perez@example.com"
                        estado: "pendiente"
                        fecha_firma: null
                    referencia_externa: "CONSULTA-001"
                completado:
                  summary: Proceso completado (todos firmaron)
                  value:
                    request_id: 791
                    circuito_id: "123456"
                    estado: "completado"
                    en_proceso: false
                    fecha_inicio: "2024-06-09T10:30:00+02:00"
                    fecha_completado: "2024-06-09T18:06:40+02:00"
                    firmantes:
                      - email: "juan.perez@example.com"
                        estado: "firmado"
                        fecha_firma: "2024-06-09T18:06:40+02:00"
                    referencia_externa: "CONSULTA-001"
        '401':
          description: Token JWT ausente o inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Authentication failed"
        '403':
          description: Sin permisos sobre el circuito_id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Canal 'mi-canal' no autorizado para circuito_id '123456'. Este circuito pertenece al canal 'otro-canal'"
                request_id: 793
                circuito_id: "123456"
        '404':
          description: Circuito_id no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Error en Evidence API: Solicitud no encontrada"
                request_id: 794
                circuito_id: "999999"
        '500':
          description: Error interno del servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: "Error interno: Database connection failed"
                request_id: 795
                circuito_id: "123456"

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        Token JWT que se obtiene al autenticarse.
        
        El token debe incluir los claims:
        - `sub`: UUID del usuario
        - `canal_nombre`: Nombre del canal
        - `canal_id`: ID numérico del canal
        
        Para más información, consulta la documentación de autenticación.

  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
          description: Descripción del error
        request_id:
          type: integer
          description: ID del request para trazabilidad (puede ser null en algunos casos)
          nullable: true
        circuito_id:
          type: string
          description: ID del circuito si está relacionado con el error
          nullable: true
        referencia_externa:
          type: string
          description: Tu referencia externa si fue proporcionada
          nullable: true

tags:
  - name: Gestión de Firma
    description: |
      Endpoints para gestionar el ciclo de vida de solicitudes de firma digital.
      
      Estos endpoints complementan el endpoint inicial de firma (`POST /firma`) permitiéndote:
      - Reenviar solicitudes cuando sea necesario
      - Consultar el estado en tiempo real
      - Obtener información detallada de firmantes y sus estados
      - Auditar el proceso completo con fechas y estados
