openapi: 3.0.0
paths:
  /auth/register:
    post:
      operationId: AuthController_register
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RegisterDto"
      responses:
        "201":
          description: User successfully registered
        "409":
          description: User already exists
      summary: Register a new user
      tags:
        - auth
  /auth/login:
    post:
      operationId: AuthController_login
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LoginDto"
      responses:
        "200":
          description: User successfully logged in
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthResponseDto"
        "401":
          description: Invalid credentials
      summary: User login
      tags:
        - auth
  /auth/refresh:
    post:
      operationId: AuthController_refresh
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RefreshTokenDto"
      responses:
        "200":
          description: Token refreshed successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthResponseDto"
        "401":
          description: Invalid refresh token
      summary: Refresh access token
      tags:
        - auth
  /auth/profile:
    get:
      operationId: AuthController_getProfile
      parameters: []
      responses:
        "200":
          description: User profile retrieved successfully
        "401":
          description: Unauthorized
      security:
        - bearer: []
      summary: Get current user profile
      tags:
        - auth
  /evolution/inboxes:
    get:
      tags:
        - evolution
      summary: Listar inboxes WhatsApp/Evolution
      security:
        - bearer: []
      responses:
        "200":
          description: Inboxes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/EvolutionInbox"
    post:
      tags:
        - evolution
      summary: Vincular instância Evolution existente
      description: Não cria instância na Evolution. Valida e vincula uma instância já
        existente; se instanceName já existir localmente, atualiza o vínculo.
      security:
        - bearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateInboxDto"
      responses:
        "201":
          description: Inbox vinculada
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EvolutionInbox"
  /evolution/inboxes/{id}:
    patch:
      tags:
        - evolution
      summary: Editar vínculo local da instância
      security:
        - bearer: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateInboxDto"
      responses:
        "200":
          description: Inbox atualizada
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EvolutionInbox"
    delete:
      tags:
        - evolution
      summary: Excluir vínculo local da instância
      description: Remove apenas o vínculo local. Não exclui a instância na Evolution.
      security:
        - bearer: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Removida
  /evolution/conversations:
    get:
      tags:
        - evolution
      summary: Listar conversas WhatsApp
      security:
        - bearer: []
      parameters:
        - name: inboxId
          in: query
          required: false
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Conversas
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WhatsappConversation"
  /evolution/conversations/{id}/messages:
    get:
      tags:
        - evolution
      summary: Listar mensagens de uma conversa WhatsApp
      security:
        - bearer: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Mensagens
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WhatsappMessage"
  /evolution/conversations/{id}/reply:
    post:
      tags:
        - evolution
      summary: Responder conversa WhatsApp
      security:
        - bearer: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendReplyDto"
      responses:
        "201":
          description: Mensagem enviada
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WhatsappMessage"
      description: Envia mensagem via Evolution, salva localmente, emite socket e
        sincroniza status via webhook/polling.
  /evolution/test/send:
    post:
      tags:
        - evolution
      summary: Enviar mensagem de teste e criar conversa local
      security:
        - bearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendTestMessageDto"
      responses:
        "201":
          description: Teste enviado
      description: Envia mensagem de teste via Evolution, cria conversa local e
        sincroniza status via webhook/polling.
  /webhooks/evolution/{instanceName}:
    post:
      tags:
        - evolution-webhook
      summary: Webhook Evolution por instância
      parameters:
        - name: instanceName
          in: path
          required: true
          schema:
            type: string
        - name: secret
          in: query
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EvolutionWebhookPayload"
      responses:
        "200":
          description: Recebido
  /webhooks/evolution/{instanceName}/{eventName}:
    post:
      tags:
        - evolution-webhook
      summary: Webhook Evolution com evento no path
      parameters:
        - name: instanceName
          in: path
          required: true
          schema:
            type: string
        - name: eventName
          in: path
          required: true
          schema:
            type: string
            example: messages-upsert
        - name: secret
          in: query
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EvolutionWebhookPayload"
      responses:
        "200":
          description: Recebido
info:
  title: Easy Faxina API
  description: The Easy Faxina API description
  version: "1.0"
  contact: {}
tags:
  - name: evolution
  - name: evolution-webhook
servers: []
components:
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http
  schemas:
    RegisterDto:
      type: object
      properties:
        email:
          type: string
          example: user@example.com
        password:
          type: string
          example: password123
        phoneNumber:
          type: string
          example: "+5511999999999"
        whatsappNumber:
          type: string
          example: "+5511999999999"
      required:
        - email
        - password
    LoginDto:
      type: object
      properties:
        email:
          type: string
          example: user@example.com
        password:
          type: string
          example: password123
      required:
        - email
        - password
    AuthResponseDto:
      type: object
      properties:
        accessToken:
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        refreshToken:
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
        user:
          type: object
      required:
        - accessToken
        - refreshToken
        - user
    RefreshTokenDto:
      type: object
      properties:
        refreshToken:
          type: string
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
      required:
        - refreshToken
    CreateInboxDto:
      type: object
      properties:
        displayName:
          type: string
          example: Atendimento Principal
        instanceName:
          type: string
          example: Blazysoftware
        apiUrl:
          type: string
          example: https://evolution.example.com
        apiKey:
          type: string
          example: EVOLUTION_API_KEY
      required:
        - displayName
        - instanceName
        - apiUrl
        - apiKey
    UpdateInboxDto:
      type: object
      properties:
        displayName:
          type: string
          example: Atendimento Principal
        instanceName:
          type: string
          example: Blazysoftware
        apiUrl:
          type: string
          example: https://evolution.example.com
        apiKey:
          type: string
          example: EVOLUTION_API_KEY
      required:
        - displayName
        - instanceName
        - apiUrl
        - apiKey
    SendReplyDto:
      type: object
      properties:
        content:
          type: string
          example: Oi, em que posso ajudar?
      required:
        - content
    SendTestMessageDto:
      type: object
      properties:
        inboxId:
          type: string
          format: uuid
        number:
          type: string
          example: "5511999998888"
        content:
          type: string
          example: Mensagem de teste
      required:
        - inboxId
        - number
        - content
    EvolutionInbox:
      type: object
      properties:
        id:
          type: string
          format: uuid
        instanceName:
          type: string
        displayName:
          type: string
        apiUrl:
          type: string
        status:
          type: string
          enum:
            - CONNECTING
            - QR_CODE
            - CONNECTED
            - DISCONNECTED
            - LOGGED_OUT
        phoneNumber:
          type: string
          nullable: true
        profileName:
          type: string
          nullable: true
    WhatsappConversation:
      type: object
      properties:
        id:
          type: string
          format: uuid
        inboxId:
          type: string
          format: uuid
        remoteJid:
          type: string
          example: 5511999998888@s.whatsapp.net
        contactName:
          type: string
          nullable: true
        contactPhone:
          type: string
          nullable: true
        unreadCount:
          type: number
        lastMessageContent:
          type: string
          nullable: true
        lastMessageAt:
          type: string
          format: date-time
          nullable: true
    WhatsappMessage:
      type: object
      properties:
        id:
          type: string
          format: uuid
        conversationId:
          type: string
          format: uuid
        waMsgId:
          type: string
        type:
          type: string
          example: text
        content:
          type: string
          nullable: true
        direction:
          type: string
          enum:
            - INBOUND
            - OUTBOUND
        status:
          type: string
          enum:
            - PENDING
            - SENT
            - DELIVERED
            - READ
            - ERROR
        timestamp:
          type: number
    EvolutionWebhookPayload:
      type: object
      properties:
        event:
          type: string
          example: SEND_MESSAGE_UPDATE
          enum:
            - MESSAGES_UPSERT
            - MESSAGES_UPDATE
            - SEND_MESSAGE
            - SEND_MESSAGE_UPDATE
            - CONNECTION_UPDATE
        instance:
          type: string
          example: Blazysoftware
        data:
          type: object
