openapi: "3.1.0"
info:
  title: Telephony MiniApp — Requisicoes de Saida
  description: >
    Requisicoes de saida do nosso aplicativo para o externo (Acloud → MiniApp).
    Enviadas como requisicoes POST para o endpoint_url configurado na integracao.
    Authorization: Bearer {api_token}
  version: "1.0.0"

x-retry-policy:
  max_retries: 3
  strategy: exponential backoff
  delays_seconds: [1, 2, 4]

x-expected-response:
  success_codes: [200, 201, 202]
  description: >
    Qualquer resposta 2xx e considerada bem-sucedida.
    Erros 4xx nao sao reenviados. Erros 5xx sao reenviados conforme a politica de retentativas.

webhooks:

  call.init:
    post:
      summary: Iniciar chamada de saida
      description: >
        Solicita ao aplicativo externo que inicie uma chamada em nome de um funcionario.
        Enviado quando o usuario clica no botao de chamada na interface do Acloud.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - call.init
                payload:
                  $ref: '#/components/schemas/CallInitPayload'
            examples:
              call_init:
                summary: Iniciar chamada de funcionario para cliente
                value:
                  method: call.init
                  payload:
                    to: "+79995556677"
                    from: "101"
      responses:
        "200":
          description: Solicitacao de inicio de chamada aceita

  call.list:
    post:
      summary: Obter lista de chamadas
      description: >
        Solicita a lista de chamadas do periodo especificado.
        Usado para sincronizar chamadas do sistema externo.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - call.list
                payload:
                  $ref: '#/components/schemas/CallListPayload'
            examples:
              call_list_by_days:
                summary: Chamadas dos ultimos 7 dias
                value:
                  method: call.list
                  payload:
                    days_left: 7
              call_list_by_range:
                summary: Chamadas por periodo
                value:
                  method: call.list
                  payload:
                    from_date: "2026-04-01"
                    to_date: "2026-04-09"
      responses:
        "200":
          description: Lista de chamadas
          content:
            application/json:
              schema:
                type: object
                properties:
                  calls:
                    type: array
                    items:
                      $ref: '#/components/schemas/CallItem'
              examples:
                call_list_response:
                  summary: Lista de chamadas
                  value:
                    calls:
                      - call_id: call_abc123
                        direction: in
                        from: "+79990001234"
                        to: "101"
                        timestamp: "2026-04-09T10:30:00Z"
                        call_duration: 295
                        status: terminated
                        has_record: true
                      - call_id: call_abc124
                        direction: out
                        from: "102"
                        to: "+79991112233"
                        timestamp: "2026-04-09T11:00:00Z"
                        call_duration: 0
                        status: missed
                        has_record: false

  call.get:
    post:
      summary: Obter dados de uma chamada
      description: >
        Solicita os dados de uma chamada especifica pelo seu identificador.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - call.get
                payload:
                  $ref: '#/components/schemas/CallGetPayload'
            examples:
              call_get:
                summary: Obter chamada por ID
                value:
                  method: call.get
                  payload:
                    call_id: call_abc123
      responses:
        "200":
          description: Dados da chamada (null se nao encontrada)
          content:
            application/json:
              schema:
                type: object
                properties:
                  call:
                    oneOf:
                      - $ref: '#/components/schemas/CallItem'
                      - type: "null"
              examples:
                call_found:
                  summary: Chamada encontrada
                  value:
                    call:
                      call_id: call_abc123
                      direction: in
                      from: "+79990001234"
                      to: "101"
                      timestamp: "2026-04-09T10:30:00Z"
                      call_duration: 295
                      status: terminated
                      has_record: true
                call_not_found:
                  summary: Chamada nao encontrada
                  value:
                    call: null

  sip.employees.list:
    post:
      summary: Obter lista de funcionarios SIP
      description: >
        Solicita a lista de funcionarios configurados no sistema telefonico externo.
        Usado para mapear ramais de funcionarios para usuarios do Acloud.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - sip.employees.list
                payload:
                  type: object
                  description: Payload vazio
            examples:
              sip_employees_list:
                summary: Solicitar lista de funcionarios
                value:
                  method: sip.employees.list
                  payload: {}
      responses:
        "200":
          description: Lista de funcionarios SIP
          content:
            application/json:
              schema:
                type: object
                properties:
                  employees:
                    type: array
                    items:
                      $ref: '#/components/schemas/SipEmployee'
              examples:
                employees_list:
                  summary: Lista de funcionarios
                  value:
                    employees:
                      - id: "emp_001"
                        name: Joao Silva
                        email: joao@example.com
                        extension: "101"
                      - id: "emp_002"
                        name: Maria Silva
                        email: maria@example.com
                        extension: "102"

  integration.status:
    post:
      summary: Obter status da integracao
      description: >
        Verifica a disponibilidade e o status da integracao com o aplicativo externo.
        Usado para health check e diagnostico.
      x-headers:
        Content-Type: application/json
        Authorization: Bearer {api_token}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - method
                - payload
              properties:
                method:
                  type: string
                  enum:
                    - integration.status
                payload:
                  type: object
                  description: Payload vazio
            examples:
              integration_status:
                summary: Solicitacao de status da integracao
                value:
                  method: integration.status
                  payload: {}
      responses:
        "200":
          description: Status da integracao
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationStatusResponse'
              examples:
                status_active:
                  summary: Integracao ativa
                  value:
                    status: active
                    message: ""
                status_inactive:
                  summary: Integracao inativa
                  value:
                    status: inactive
                    message: "API token is invalid"


components:
  schemas:

    OutgoingEvent:
      type: object
      required:
        - method
        - payload
      properties:
        method:
          type: string
          enum:
            - call.init
            - call.list
            - call.get
            - sip.employees.list
            - integration.status
          description: Tipo de requisicao
        payload:
          oneOf:
            - $ref: '#/components/schemas/CallInitPayload'
            - $ref: '#/components/schemas/CallListPayload'
            - $ref: '#/components/schemas/CallGetPayload'
          discriminator:
            propertyName: method

    # ─── call.init ────────────────────────────────────────────────────────────

    CallInitPayload:
      type: object
      description: Parametros para iniciar uma chamada de saida
      required:
        - to
        - from
      properties:
        to:
          type: string
          description: Numero de telefone para ligar
          example: "+79995556677"
        from:
          type: string
          description: Ramal do funcionario (numero interno) em cujo nome a chamada e realizada
          example: "101"

    # ─── call.list ────────────────────────────────────────────────────────────

    CallListPayload:
      type: object
      description: >
        Parametros de filtragem para a lista de chamadas. Todos os campos sao opcionais.
        Se nao especificados — todas as chamadas disponiveis sao retornadas.
      properties:
        days_left:
          type: ["integer", "null"]
          description: Numero de dias para tras a partir da data atual para selecao de chamadas
          example: 7
        from_date:
          type: ["string", "null"]
          description: Data de inicio do periodo de selecao (formato YYYY-MM-DD)
          example: "2026-04-01"
        to_date:
          type: ["string", "null"]
          description: Data de fim do periodo de selecao (formato YYYY-MM-DD)
          example: "2026-04-09"

    # ─── call.get ─────────────────────────────────────────────────────────────

    CallGetPayload:
      type: object
      description: Parametros para obter os dados de uma chamada especifica
      required:
        - call_id
      properties:
        call_id:
          type: string
          description: Identificador unico da chamada no sistema externo
          example: call_abc123

    # ─── Shared types ─────────────────────────────────────────────────────────

    CallItem:
      type: object
      description: Dados de uma chamada do sistema externo
      required:
        - call_id
        - direction
        - from
        - to
        - timestamp
        - call_duration
        - status
        - has_record
      properties:
        call_id:
          type: string
          description: Identificador unico da chamada
          example: call_abc123
        direction:
          type: string
          enum:
            - in
            - out
          description: Direcao da chamada
        from:
          type: string
          description: Origem da chamada (numero de telefone ou ramal)
          example: "+79990001234"
        to:
          type: string
          description: Destinatario da chamada (numero de telefone ou ramal)
          example: "101"
        timestamp:
          type: string
          description: Data e hora da chamada no formato ISO 8601
          example: "2026-04-09T10:30:00Z"
        call_duration:
          type: integer
          description: Duracao da conversa em segundos
          example: 295
        status:
          type: string
          enum:
            - active
            - terminated
            - missed
          description: Status da chamada
        has_record:
          type: boolean
          description: Indicador de existencia de gravacao da chamada
          example: true
        record_url:
          type: string
          description: Link de download da gravacao da chamada
          example: https://dominio/call_id
          nullable: true

    SipEmployee:
      type: object
      description: Dados do funcionario no sistema SIP do aplicativo externo
      required:
        - id
        - name
        - email
        - extension
      properties:
        id:
          type: string
          description: Identificador unico do funcionario no sistema externo
          example: "emp_001"
        name:
          type: string
          description: Nome de exibicao do funcionario
          example: Joao Silva
        email:
          type: string
          description: Email do funcionario
          example: joao@example.com
        extension:
          type: string
          description: Numero SIP interno do funcionario
          example: "101"

    IntegrationStatusResponse:
      type: object
      description: Resposta a solicitacao de status da integracao
      required:
        - status
      properties:
        status:
          type: string
          enum:
            - active
            - inactive
          description: >
            Status atual da integracao.
            `active` — a integracao esta funcionando normalmente;
            `inactive` — a integracao esta indisponivel ou desativada.
        message:
          type: string
          description: Mensagem adicional de status (ex.: motivo da inatividade)
          example: ""
