openapi: 3.0.3
info:
  title: Módulo Técnicos API
  version: 1.0.0
  description: API RESTful para cadastro e gestão de técnicos.
servers:
  - url: http://localhost:8000
    description: Local dev
security:
  - bearerAuth: []
paths:
  /api/cadastros/tecnicos:
    get:
      summary: Listar técnicos
      parameters:
        - in: query
          name: q
          schema: { type: string }
        - in: query
          name: page
          schema: { type: integer, minimum: 1, default: 1 }
        - in: query
          name: limit
          schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
      responses:
        '200':
          description: Lista paginada de técnicos
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/Technician' }
                  page: { type: integer }
                  limit: { type: integer }
                  total: { type: integer }
    post:
      summary: Criar técnico
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/TechnicianCreate' }
      responses:
        '201':
          description: Técnico criado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id: { type: integer }
        '422': { description: Falha de validação }
  /api/cadastros/tecnicos/{id}:
    get:
      summary: Obter técnico por ID
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: integer }
      responses:
        '200':
          description: Técnico
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { $ref: '#/components/schemas/Technician' }
        '404': { description: Não encontrado }
    put:
      summary: Atualizar técnico
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: integer }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/TechnicianUpdate' }
      responses:
        '200':
          description: Atualizado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id: { type: integer }
    delete:
      summary: Excluir técnico
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: integer }
      responses:
        '204': { description: Excluído }
        '409': { description: Conflito/Restrição }
  /api/cadastros/tecnicos/{id}/service-history:
    post:
      summary: Adicionar registro de serviço ao histórico do técnico
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: integer }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                service_id: { type: integer, nullable: true }
                description: { type: string }
                amount: { type: number }
                executed_at: { type: string, format: date-time }
                source: { type: string, default: servico }
                reference_id: { type: integer, nullable: true }
      responses:
        '201':
          description: Serviço registrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      commission_amount: { type: number }
  /api/cadastros/tecnicos/{id}/comissoes:
    get:
      summary: Obter comissões agregadas por período
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: integer }
        - in: query
          name: from
          schema: { type: string, format: date }
        - in: query
          name: to
          schema: { type: string, format: date }
      responses:
        '200':
          description: Totais
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      services: { type: integer }
                      total_amount: { type: number }
                      total_commission: { type: number }
  /api/cadastros/tecnicos/relatorios/produtividade:
    get:
      summary: Relatório de produtividade de técnicos
      parameters:
        - in: query
          name: from
          schema: { type: string, format: date }
        - in: query
          name: to
          schema: { type: string, format: date }
      responses:
        '200':
          description: Ranking por comissão
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        technician_id: { type: integer }
                        nome: { type: string }
                        services: { type: integer }
                        total_amount: { type: number }
                        total_commission: { type: number }
  /api/cadastros/tecnicos/export/payments:
    get:
      summary: Exportar pagamentos em CSV
      parameters:
        - in: query
          name: from
          schema: { type: string, format: date }
        - in: query
          name: to
          schema: { type: string, format: date }
      responses:
        '200':
          description: CSV
          content:
            text/csv:
              schema:
                type: string
  /api/cadastros/tecnicos/identify:
    get:
      summary: Identificar técnico por código PDV (query)
      parameters:
        - in: query
          name: code
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Técnico identificado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id: { type: integer }
                      nome: { type: string }
                      enabled: { type: integer }
        '404': { description: Não encontrado }
  /api/cadastros/tecnicos/identify/{code}:
    get:
      summary: Identificar técnico por código PDV (path)
      parameters:
        - in: path
          name: code
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Técnico identificado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id: { type: integer }
                      nome: { type: string }
                      enabled: { type: integer }
        '404': { description: Não encontrado }

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    Technician:
      type: object
      properties:
        id: { type: integer }
        nome: { type: string }
        cpf: { type: string }
        rg: { type: string }
        rg_uf: { type: string, nullable: true }
        email: { type: string, nullable: true }
        telefone: { type: string }
        bank_name: { type: string, nullable: true }
        bank_agencia: { type: string, nullable: true }
        bank_conta: { type: string, nullable: true }
        bank_type: { type: string, nullable: true, enum: [corrente, poupanca] }
        comissao_percent: { type: number, nullable: true }
        commission_method: { type: string, nullable: true, enum: [por_servico, por_valor] }
        monthly_limit: { type: number, nullable: true }
        enabled: { type: integer }
        inactivated_at: { type: string, format: date-time, nullable: true }
        pdv_code: { type: string, nullable: true }
        rfid_code: { type: string, nullable: true }
        created_at: { type: string, format: date-time, nullable: true }
    TechnicianCreate:
      type: object
      required: [nome, cpf, rg, telefone]
      properties:
        nome: { type: string, minLength: 3 }
        cpf: { type: string }
        rg: { type: string }
        rg_uf: { type: string, nullable: true }
        email: { type: string, nullable: true, format: email }
        telefone: { type: string }
        bank_name: { type: string, nullable: true }
        bank_agencia: { type: string, nullable: true }
        bank_conta: { type: string, nullable: true }
        bank_type: { type: string, nullable: true, enum: [corrente, poupanca] }
        pix_key: { type: string, nullable: true }
        comissao_percent: { type: number, nullable: true, minimum: 1, maximum: 99 }
        commission_method: { type: string, nullable: true, enum: [por_servico, por_valor] }
        monthly_limit: { type: number, nullable: true, minimum: 0 }
        enabled: { type: integer, enum: [0,1], default: 1 }
        inactivated_at: { type: string, format: date-time, nullable: true }
        pdv_code: { type: string, nullable: true }
        rfid_code: { type: string, nullable: true }
    TechnicianUpdate:
      type: object
      properties:
        nome: { type: string, minLength: 3 }
        cpf: { type: string }
        rg: { type: string }
        rg_uf: { type: string, nullable: true }
        email: { type: string, nullable: true, format: email }
        telefone: { type: string }
        bank_name: { type: string, nullable: true }
        bank_agencia: { type: string, nullable: true }
        bank_conta: { type: string, nullable: true }
        bank_type: { type: string, nullable: true, enum: [corrente, poupanca] }
        pix_key: { type: string, nullable: true }
        comissao_percent: { type: number, nullable: true, minimum: 1, maximum: 99 }
        commission_method: { type: string, nullable: true, enum: [por_servico, por_valor] }
        monthly_limit: { type: number, nullable: true, minimum: 0 }
        enabled: { type: integer, enum: [0,1] }
        inactivated_at: { type: string, format: date-time, nullable: true }
        pdv_code: { type: string, nullable: true }
        rfid_code: { type: string, nullable: true }