openapi: "3.1.0"
info:
  title: FolhaFácil API
  version: "1.0.0"
  description: |
    API para processamento de folha de pagamento brasileira.
    Suporte completo a INSS, IRRF, FGTS, 13º salário, férias e eSocial.

    Base URL: `https://folhafacil.com/api/v1`

servers:
  - url: https://folhafacil.com/api/v1
    description: Produção
  - url: http://localhost:3000/api/v1
    description: Desenvolvimento

security:
  - ApiKeyAuth: []

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: |
        Chave de API gerada em `/api/tenant/api-keys`.
        Formato: `ff_prod_<base64url>`

  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
          description: Mensagem de erro
      required:
        - error

    Employee:
      type: object
      properties:
        id:
          type: string
        matricula:
          type: string
        nome:
          type: string
        cpf:
          type: string
        email:
          type: string
          nullable: true
        dataNascimento:
          type: string
          format: date-time
        dataAdmissao:
          type: string
          format: date-time
        status:
          type: string
          enum: [ATIVO, FERIAS, AFASTADO, DEMITIDO]
        cargo:
          type: object
          nullable: true
          properties:
            id:
              type: string
            nome:
              type: string
        departamento:
          type: object
          nullable: true
          properties:
            id:
              type: string
            nome:
              type: string
        dependents:
          type: array
          items:
            $ref: "#/components/schemas/Dependent"
        _count:
          type: object
          properties:
            dependents:
              type: integer

    Dependent:
      type: object
      properties:
        id:
          type: string
        employeeId:
          type: string
        nome:
          type: string
        cpf:
          type: string
          nullable: true
        dataNascimento:
          type: string
          format: date-time
        grauParentesco:
          type: string

    CreateEmployeeInput:
      type: object
      required:
        - nome
        - cpf
        - dataNascimento
        - dataAdmissao
        - salarioBase
      properties:
        nome:
          type: string
        cpf:
          type: string
        dataNascimento:
          type: string
          format: date
        dataAdmissao:
          type: string
          format: date
        salarioBase:
          type: number
        cargo:
          type: string
        departamento:
          type: string

    Payroll:
      type: object
      properties:
        id:
          type: string
        competencia:
          type: string
        ano:
          type: integer
        tipo:
          type: string
          enum: [MENSAL, DECIMO_TERCEIRO, FERIAS]
        status:
          type: string
          enum: [DRAFT, PROCESSING, APPROVED, SUBMITTED, PAID]
        totalBruto:
          type: number
        totalDescontos:
          type: number
        totalLiquido:
          type: number
        totalEncargosEmpregador:
          type: number
        createdAt:
          type: string
          format: date-time

    GeneratePayrollInput:
      type: object
      required:
        - competencia
      properties:
        competencia:
          type: string
          description: Competência no formato YYYY-MM
        tipo:
          type: string
          enum: [MENSAL, DECIMO_TERCEIRO, FERIAS]
          default: MENSAL

    PayrollItem:
      type: object
      properties:
        id:
          type: string
        employee:
          $ref: "#/components/schemas/EmployeeBrief"
        salarioBase:
          type: number
        horasTrabalhadas:
          type: number
        inssEmpregado:
          type: number
        irrf:
          type: number
        fgts:
          type: number
        salarioLiquido:
          type: number

    EmployeeBrief:
      type: object
      properties:
        id:
          type: string
        nome:
          type: string
        cpf:
          type: string
        matricula:
          type: string
        pis:
          type: string
          nullable: true
        salarioBase:
          type: number
        cargo:
          type: object
          nullable: true
          properties:
            nome:
              type: string
        departamento:
          type: object
          nullable: true
          properties:
            nome:
              type: string

    Document:
      type: object
      properties:
        id:
          type: string
        tenantId:
          type: string
        employeeId:
          type: string
          nullable: true
        tipo:
          type: string
          enum: [HOLERITE, INFORME_RENDIMENTOS, TERMO_RESCISAO, CTPS_DIGITAL, LGPD_CONSENT, CONTRATO_TRABALHO]
        filePath:
          type: string
        geradoEm:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        employee:
          type: object
          nullable: true
          properties:
            id:
              type: string
            nome:
              type: string
            matricula:
              type: string

    Report:
      type: object
      properties:
        employees:
          type: object
          properties:
            total:
              type: integer
            active:
              type: integer
        currentPayroll:
          type: object
          nullable: true
          properties:
            bruto:
              type: number
            liquido:
              type: number
            descontos:
              type: number
        yearly:
          type: object
          properties:
            totalPago:
              type: number
            mesesProcessados:
              type: integer
            payrolls:
              type: array
              items:
                type: object
                properties:
                  competencia:
                    type: string
                  totalLiquido:
                    type: number
                  status:
                    type: string
        documents:
          type: integer
        pendingESocial:
          type: integer

paths:
  /employees:
    get:
      summary: Listar funcionários
      description: Retorna a lista de funcionários do tenant ativo.
      security:
        - ApiKeyAuth:
            - employees:read
      responses:
        "200":
          description: Lista de funcionários
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Employee"
        "401":
          description: API key ausente ou inválida
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: Escopo insuficiente
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

    post:
      summary: Criar funcionário
      description: Cria um novo funcionário no tenant ativo.
      security:
        - ApiKeyAuth:
            - employees:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateEmployeeInput"
      responses:
        "201":
          description: Funcionário criado
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Employee"
        "400":
          description: Dados inválidos
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente
        "409":
          description: CPF já cadastrado

  /employees/{id}:
    get:
      summary: Detalhes do funcionário
      description: Retorna os detalhes de um funcionário específico, incluindo cargo, departamento e dependentes.
      security:
        - ApiKeyAuth:
            - employees:read
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
          description: ID do funcionário
      responses:
        "200":
          description: Detalhes do funcionário
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Employee"
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente
        "404":
          description: Funcionário não encontrado

  /employees/{id}/history:
    get:
      summary: Histórico completo do funcionário
      description: Retorna o histórico completo do funcionário, incluindo alterações de cargo, salário, departamento, afastamentos, férias e desligamento.
      security:
        - ApiKeyAuth:
            - employees:read
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
          description: ID do funcionário
      responses:
        "200":
          description: Histórico do funcionário
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      employee:
                        $ref: "#/components/schemas/Employee"
                      payrollHistory:
                        type: array
                        items:
                          $ref: "#/components/schemas/Payroll"
                      contractChanges:
                        type: array
                        items:
                          type: object
                          properties:
                            data:
                              type: string
                              format: date-time
                            tipo:
                              type: string
                            descricao:
                              type: string
                      absences:
                        type: array
                        items:
                          type: object
                          properties:
                            dataInicio:
                              type: string
                              format: date
                            dataFim:
                              type: string
                              format: date
                            tipo:
                              type: string
                      termination:
                        type: object
                        nullable: true
                        properties:
                          dataDesligamento:
                            type: string
                            format: date
                          motivo:
                            type: string
                          saldoRescisorio:
                            type: number
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente
        "404":
          description: Funcionário não encontrado

  /payroll:
    get:
      summary: Listar folhas de pagamento
      description: Retorna as folhas de pagamento do tenant ativo.
      security:
        - ApiKeyAuth:
            - payroll:read
      parameters:
        - in: query
          name: competencia
          schema:
            type: string
          description: Filtrar por competência (YYYY-MM)
        - in: query
          name: tipo
          schema:
            type: string
            enum: [MENSAL, DECIMO_TERCEIRO, FERIAS]
          description: Filtrar por tipo de folha
      responses:
        "200":
          description: Lista de folhas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Payroll"
        "401":
          description: API key ausente ou inválida

  /payroll/generate:
    post:
      summary: Gerar folha de pagamento
      description: Gera uma nova folha de pagamento para todos os funcionários ativos.
      security:
        - ApiKeyAuth:
            - payroll:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GeneratePayrollInput"
      responses:
        "201":
          description: Folha gerada com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: "#/components/schemas/Payroll"
                  message:
                    type: string
        "400":
          description: Dados inválidos
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente
        "409":
          description: Folha já existe para esta competência/tipo

  /payroll/{id}:
    get:
      summary: Detalhes da folha de pagamento
      description: Retorna os detalhes de uma folha de pagamento, incluindo todos os itens.
      security:
        - ApiKeyAuth:
            - payroll:read
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
          description: ID da folha de pagamento
      responses:
        "200":
          description: Detalhes da folha
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: "#/components/schemas/Payroll"
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente
        "404":
          description: Folha não encontrada

  /documents:
    get:
      summary: Listar documentos
      description: Retorna a lista de documentos do tenant ativo.
      security:
        - ApiKeyAuth:
            - documents:read
      parameters:
        - in: query
          name: tipo
          schema:
            type: string
          description: Filtrar por tipo de documento
        - in: query
          name: employeeId
          schema:
            type: string
          description: Filtrar por funcionário
      responses:
        "200":
          description: Lista de documentos
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Document"
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente

  /reports:
    get:
      summary: Relatórios e indicadores
      description: Retorna um resumo com indicadores do tenant ativo.
      security:
        - ApiKeyAuth:
            - reports:read
      responses:
        "200":
          description: Relatório
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Report"
        "401":
          description: API key ausente ou inválida
        "403":
          description: Escopo insuficiente
