Winx - API Integração
  1. Raiz
Winx - API Integração
  • Raiz
    • Documentação de Integração
    • Companies
      • 📋 Listar Empresas
    • Filters
      • 📋 Listar Filtros
      • ➕ Criar Filtro
      • 🔍 Visualizar Filtro
      • ✏️ Atualizar Filtro
      • 🗑️ Excluir Filtro
    • Employees
      • 📋 Listar Funcionários
      • ➕ Criar Funcionário
      • 🔍 Visualizar Funcionário
      • ✏️ Atualizar Funcionário
      • 🗑️ Excluir Funcionário
    • Users
      • Permissions
        • 📋 Listar Permissões
        • ➕ Criar Permissão
        • 🔍 Visualizar Permissão
        • 🗑️ Excluir Permissão
      • Profile
        • 📋 Listar Perfis
        • ➕ Criar Perfil
        • 🔍 Visualizar Perfil
        • ✏️ Atualizar Perfil
        • 🗑️ Excluir Perfil
      • 📋 Listar Usuários
      • ➕ Criar Usuário
      • 🔍 Visualizar Usuário
      • ✏️ Atualizar Usuário
      • 🗑️ Excluir Usuário
  • Esquemas
    • Schemas
      • UserCreate
      • User
      • CampaignAccess
      • UserCollection
      • PermissionCreate
      • PermissionUpdate
      • ProfileCreate
      • Profile
      • ProfileCollection
      • Company
      • Filter
      • FilterCreate
      • FilterUpdate
      • EmployeeField
      • PaginationLinks
      • PaginationMeta
      • ErrorResponse
      • ValidationErrorResponse
    • Response
      • Unauthorized
      • Forbidden
      • NotFound
      • ValidationError
  1. Raiz

Documentação de Integração

API v1 - Documentação Oficial

Índice

  • Visão Geral
  • Solicitação de Acesso
  • Autenticação
  • Rate Limiting
  • Formato de Resposta
  • Endpoints
    • Companies
    • Filters
    • Employees
    • Users
  • Regras de Negócio Específicas
  • Comportamento de Soft Delete
  • Busca Inteligente
  • Limitações e Escopo
  • Códigos de Erro
  • Exemplos Práticos

Visão Geral

A API v1 da Winx é uma API REST para gerenciamento de empresas, funcionários e filtros, com foco em operações CRUD essenciais e conformidade com LGPD.

  • URL Base Sandbox: https://scenic-tokyo-3bje4ahyb4rd.on-vapor.com
  • URL Base Produção: https://bubbling-havana-prclnzvluehc.on-vapor.com
  • Versão Atual: v1
  • Formato: JSON
  • Charset: UTF-8

Solicitação de Acesso

🧪 Ambiente de Sandbox

Para obter acesso ao ambiente de desenvolvimento/homologação:

  1. Entre em contato: Solicite acesso via equipe técnica
  2. Forneça informações: Dados da empresa/projeto de integração
  3. Aguarde liberação: Credenciais de teste serão fornecidas
  4. Configure ambiente: Use URLs de sandbox para desenvolvimento

Características do Sandbox:

  • Ambiente isolado para testes
  • Dados não persistentes (podem ser resetados)
  • Rate limiting reduzido para desenvolvimento
  • Sem impacto em dados de produção

🚀 Ambiente de Produção

Para acesso ao ambiente de produção:

  1. Homologação completa: Finalize todos os testes no Sandbox
  2. Aprovação técnica: Validação dos casos de uso implementados
  3. Aprovação comercial: Definição de termos contratuais
  4. Configuração definitiva: Chaves de produção geradas no Dashboard

Requisitos para Produção:

  • Integração testada e validada no Sandbox
  • Casos de uso documentados e aprovados
  • Conformidade com LGPD: Implementação de controles de privacidade e proteção de dados
  • Monitoramento e tratamento de erros implementados

📞 Contato para Suporte

  • E-mail técnico: ti@winx.ai
  • Documentação: Consulte esta documentação para dúvidas técnicas
  • Tempo de resposta: 1-2 dias úteis para solicitações de acesso

Autenticação

🔑 Sistema de Chaves de Acesso

A API utiliza chaves de acesso geradas no Dashboard Administrativo da aplicação.

🌐 Dashboard Homologação: Dashboard Winx

🌐 Dashboard Produção: Dashboard Winx

📋 Processo de Geração

  1. Acesse o Dashboard: Entre na sua conta no Dashboard Winx
  2. Navegue até Chaves: Vá para a seção de gerenciamento de API
  1. Gere Nova Chave: Clique em "Gerar Nova Chave de Acesso"
  2. ⚠️ IMPORTANTE: Copie e salve a chave imediatamente
    • A chave é exibida apenas uma vez por segurança
    • Se perdida, deve ser excluída e gerada novamente
    • Não é possível recuperar chaves perdidas

🏢 Uma Chave Por Empresa

  • Cada empresa possui uma chave única
  • A chave identifica e autentica a empresa
  • Uso: Authorization: Bearer {sua-chave-de-acesso}

Headers Obrigatórios

Authorization: Bearer {sua-chave-de-acesso}
Content-Type: application/json
Accept: application/json

Header Opcional

Resource-Id: {uuid-da-empresa}

Quando usar Resource-Id:

  • Token de empresa matriz operando em filial
  • Token de usuário especificando empresa alvo
  • Se omitido, usa a empresa autenticada principal

🔄 Gerenciamento de Chaves

# ✅ Exemplo de uso correto
GET /v1/companies
Authorization: Bearer wjnx_sk_live_1234567890abcdefghijklmnop
Content-Type: application/json
Accept: application/json

🗑️ Revogação: Para revogar acesso, exclua a chave no Dashboard e gere uma nova.

🔄 Rotação: Recomenda-se rotacionar chaves periodicamente por segurança.

Rate Limiting

⚡ Limites de Requisições

  • 500 requisições por minuto por chave de acesso
  • Aplicado globalmente em todos os endpoints
  • Limite conservador para início, pode ser ajustado conforme necessidade

🎯 Justificativa do Limite

Por que 500/min?

  • Início conservador: Permite operações normais sem sobrecarregar a infraestrutura
  • Monitoramento ativo: Limites são ajustados baseado em uso real
  • Escalabilidade gradual: Evita picos inesperados que comprometam todos os clientes

📊 Casos de Uso Típicos

CenárioRequisições/minStatus
Sincronização pequena (< 100 funcionários)~5-20✅ Bem dentro do limite
Sincronização média (100-1000 funcionários)~50-200✅ Dentro do limite
Importação grande (1000+ funcionários)~300-500⚠️ Pode necessitar otimização
Operação massiva (10000+ funcionários)500+❌ Contate suporte técnico

🔄 Ajuste de Limites

Para casos especiais:

  • Contate: ti@winx.ai
  • Informe: Caso de uso específico e volume esperado
  • Justifique: Por que precisa de limite maior
  • Aguarde: Análise e possível ajuste personalizado

📈 Headers de Controle

Cada resposta inclui headers informativos:

X-RateLimit-Limit: 500          # Limite máximo
X-RateLimit-Remaining: 999       # Requisições restantes
X-RateLimit-Reset: 1640995200     # Timestamp de reset

⚠️ Quando o Limite é Atingido

Status: 429 Too Many Requests

{
  "id": "rate-limit-error-uuid",
  "status": 429,
  "title": "Too Many Requests",
  "detail": "Limite de requisições excedido. Tente novamente em 60 segundos.",
  "meta": {
    "retry_after": 60,
    "limit": 500,
    "window": "1 minute"
  }
}

💡 Boas Práticas

  • Monitore headers: Acompanhe X-RateLimit-Remaining
  • Implemente retry: Aguarde o tempo em retry_after
  • Distribua requisições: Evite picos de uso
  • Cache respostas: Reduza chamadas desnecessárias

Formato de Resposta

✅ Estrutura de Sucesso

Recurso Único (GET /v1/employees/{id})

{
  "data": {
    "id": "uuid-funcionario",
    "name": "João Silva",
    "email": "joao@empresa.com",
    "created_at": "2024-01-01T10:00:00+00:00"
  }
}

Lista com Paginação (GET /v1/employees)

{
  "data": [
    {
      "id": "uuid-funcionario-1",
      "name": "João Silva"
    },
    {
      "id": "uuid-funcionario-2",
      "name": "Maria Santos"
    }
  ],
  "links": {
    "first": "https://api.winx.ai/v1/employees?page=1",
    "last": "https://api.winx.ai/v1/employees?page=10",
    "prev": null,
    "next": "https://api.winx.ai/v1/employees?page=2"
  },
  "meta": {
    "current_page": 1,
    "per_page": 10,
    "total": 100,
    "last_page": 10
  }
}

❌ Formato de Erro Padrão

{
  "id": "error-unique-uuid",
  "status": 422,
  "title": "Validation Error",
  "detail": "Os dados fornecidos contêm erros de validação",
  "meta": {
    "errors": {
      "document": ["The document field is required."],
      "email": ["The email has already been taken."]
    }
  }
}

🔢 Códigos de Status HTTP

CódigoSignificadoQuando Ocorre
200OKGET, PUT bem-sucedidos
201CreatedPOST bem-sucedido
204No ContentDELETE bem-sucedido
401UnauthorizedToken inválido/ausente
403ForbiddenSem permissão
404Not FoundRecurso não encontrado
422Validation ErrorDados inválidos
429Too Many RequestsRate limit excedido
500Internal ErrorErro interno do servidor

🌍 Headers Padrão

Resposta:

Content-Type: application/json; charset=UTF-8
X-RateLimit-Limit:500
X-RateLimit-Remaining: 499

Requisição:

Authorization: Bearer {sua-chave}
Content-Type: application/json
Accept: application/json
Resource-Id: {uuid-empresa}  # Opcional

Paginação

  • Registros por página: 10 (padrão)
  • Formato: Laravel padrão com links e meta

Sistema de Fields

📋 Formato Flexível

O campo fields dos funcionários aceita dois formatos:

Formato 1: ID e Value (Recomendado)

{
  "fields": [
    {
      "id": "uuid-filter-departamento",
      "value": "Tecnologia"
    },
    {
      "id": "uuid-filter-cargo",
      "value": "Desenvolvedor"
    }
  ]
}

Formato 2: Key e Value (Alternativo)

{
  "fields": [
    {
      "key": "departamento",
      "value": "Tecnologia"
    },
    {
      "key": "cargo",
      "value": "Desenvolvedor"
    }
  ]
}

🎯 Quando Usar Cada Formato

FormatoQuando UsarVantagem
ID + ValueIntegrações modernasUUID garante unicidade, mais seguro
Key + ValueSistemas legadosMais legível, fácil manutenção

🔄 Obtenção de IDs/Keys

# Para obter UUIDs e keys dos filtros
GET /v1/filters

Resposta:

{
  "data": [
    {
      "id": "uuid-filter-departamento",  # Use no formato ID+Value
      "key": "departamento",             # Use no formato Key+Value
      "is_required": true,
      "default_value": "Não informado"
    }
  ]
}

⚠️ Validação de Fields

  • Filtros obrigatórios (is_required: true) devem estar presentes
  • Formato misto não é suportado (escolha um formato por requisição)
  • IDs inválidos resultam em erro 422
  • Keys inexistentes resultam em erro 422

Endpoints

Companies

  • 📋 Listar Empresas

Filters

  • 📋 Listar Filtros
  • ➕ Criar Filtro
  • 🔍 Visualizar Filtro
  • ✏️ Atualizar Filtro
  • 🗑️ Excluir Filtro

Employees

  • 📋 Listar Funcionários
  • ➕ Criar Funcionário
  • 🔍 Visualizar Funcionário
  • ✏️ Atualizar Funcionário
  • 🗑️ Excluir Funcionário

Users

  • 📋 Listar Usuários

  • ➕ Criar Usuário

  • 🔍 Visualizar Usuário

  • ✏️ Atualizar Usuário

  • 🗑️ Excluir Usuário

  • 📋 Listar Permissões

  • ➕ Criar Permissão

  • 🔍 Visualizar Permissão

  • 🗑️ Excluir Permissão

  • 📋 Listar Perfis

  • ➕ Criar Perfil

  • 🔍 Visualizar Perfil

  • ✏️ Atualizar Perfil

  • 🗑️ Excluir Perfil

Regras de Negócio Específicas

Identify Key

Cada empresa tem um identify_key que determina qual campo é obrigatório para funcionários:

  • DOCUMENT: Campo document (CPF) obrigatório
  • EMAIL: Campo email obrigatório
{
  "identify_key": "document", // ou "email"
}

Impacto nas Validações:

  • O campo correspondente ao identify_key torna-se obrigatório
  • Validação de unicidade aplica-se globalmente (exceto soft-deleted)
  • Outros campos permanecem opcionais

Gestão de Fields (Filtros)

Fields são pares chave-valor que vinculam funcionários aos filtros da empresa.

Estrutura:

{
  "fields": [
    {
      "id": "uuid-do-filter",
      "value": "Valor Específico"
    }
  ]
}

Regras:

  • Todos os filtros com is_required = true devem estar presentes
  • Se value estiver vazio, usa default_value do filtro
  • filter_id deve existir nos filtros ativos da empresa
  • Cada filter_id deve aparecer apenas uma vez por funcionário

Gestão de Campanhas

Funcionários podem ser incluídos/removidos de campanhas através dos campos:

include_campaign (POST/PUT):

  • true: Inclui funcionário em todas as campanhas ativas
  • false: Não inclui em campanhas
  • Obrigatório no POST, exceto se firing_date preenchido

remove_campaign (PUT apenas):

  • true: Remove funcionário de todas as campanhas ativas
  • false: Mantém funcionário nas campanhas atuais
  • Obrigatório no PUT
  • Mutuamente excludente com include_campaign

Gestão de Desligamento

📅 Timeline Detalhada: firing_date vs DELETE

Processo firing_date (Recomendado)

1. PUT /v1/employees/{id} com firing_date
   ↓
2. Validações obrigatórias: is_voluntary_firing, data válida
   ↓  
3. Registro atualizado (funcionário ainda visível)
   ↓
4. EmployeeObserver detecta firing_date
   ↓
5. Soft delete automático (deleted_at preenchido)
   ↓
6. Funcionário desaparece das consultas GET

Processo DELETE (Direto)

1. DELETE /v1/employees/{id}
   ↓
2. EmployeeRepository::delete() executa:
   - Remove fields fisicamente
   - Remove vínculos de campanhas  
   - Aplica soft delete
   ↓
3. Funcionário desaparece imediatamente das consultas

🏁 Comparação Técnica Completa

Aspectofiring_date (PUT)DELETE (Direto)
Momento do soft deleteApós Observer processarImediato na requisição
Histórico de desligamento✅ Preservado (data, motivo, tipo)❌ Apenas deleted_at
Visibilidade temporária✅ Permanece visível até Observer❌ Invisível imediatamente
CampanhasMantidas (exceto se remove_campaign: true)❌ Removidas automaticamente
Fields✅ Preservados no momento do PUT❌ Removidos imediatamente
Auditoria/Compliance✅ Processo rastreável⚠️ Menos informação
Uso recomendadoDesligamento formal/HRLimpeza/correção de dados

🎯 Quando usar cada abordagem

Use firing_date quando:

  • ✅ Processo formal de desligamento (RH)
  • ✅ Precisa de histórico detalhado (motivo, tipo)
  • ✅ Desligamento com data retroativa
  • ✅ Funcionário ainda precisa responder pesquisas de offboarding
  • ✅ Auditoria/compliance importante
PUT /v1/employees/uuid
{
  "firing_date": "31/12/2024",
  "is_voluntary_firing": true,
  "reason_firing": "Pedido de demissão",
  "remove_campaign": true  // Remove de campanhas se necessário
}

Use DELETE quando:

  • ✅ Limpeza de dados incorretos
  • ✅ Funcionário criado por engano
  • ✅ Necessita remoção imediata
  • ✅ Não precisa de histórico formal
DELETE /v1/employees/uuid
# Resultado: Soft delete + limpeza imediata

⚠️ Estados Intermediários

Durante processo firing_date:

// Estado 1: Após PUT, antes do Observer
{
  "firing_date": "31/12/2024",
  "is_voluntary_firing": true,
  "deleted_at": null  // ← Ainda não processado
}
// Funcionário ainda aparece em GET /v1/employees

// Estado 2: Após Observer (poucos segundos depois)  
{
  "firing_date": "31/12/2024",
  "is_voluntary_firing": true,
  "deleted_at": "2024-01-01T10:00:00+00:00"  // ← Processado
}
// Funcionário desaparece de GET /v1/employees

🔄 Recuperação e Restauração

Ambos os processos:

  • ❌ Não há endpoint REST para restaurar funcionários
  • ✅ Comandos Artisan disponíveis no servidor:
    php artisan employee:restore {uuid}
    
  • ✅ Dados completamente reutilizáveis após soft delete
  • ✅ Nova criação com mesmos dados é permitida

Validações Detalhadas

CPF (document)

  • Formato: Apenas números (11 dígitos)
  • Algoritmo: Validação matemática de CPF brasileiro
  • Unicidade: Global, ignora soft-deleted
  • Exemplos válidos: 12345678901
  • Exemplos inválidos: 123.456.789-01, 123456789, 00000000000

Email

  • Formato: RFC 5322 padrão (validação nativa Laravel)
  • Unicidade: Global, ignora soft-deleted
  • Exemplos válidos: joao@empresa.com, test+tag@domain.co.uk
  • Exemplos inválidos: email-invalido, @domain.com

Telefone (phone)

  • Formato: Celular brasileiro com código do país
  • Validação: Biblioteca propaganistas/laravel-phone
  • País: Apenas Brasil (BR)
  • Tipo: Apenas mobile (celular)
  • Unicidade: Global via regra PhoneExists
  • Exemplos válidos: +5511999999999, 5511999999999
  • Exemplos inválidos: 11999999999, 551133333333 (fixo)

Internal ID

  • Formato: String livre
  • Unicidade: Por empresa (company_id)
  • Opcional: Pode ser nulo
  • Exemplo: EMP001, FUNC-123, João-TI

Datas

  • Formato obrigatório: dd/mm/yyyy
  • Validações específicas:
    • birthdate: < hoje
    • hiring_date: <= hoje, > birthdate (se birthdate existir)
    • firing_date: <= hoje, > hiring_date (se hiring_date existir)

Nome (name/social_name)

  • Regra: FullName() personalizada
  • Formato: Deve ser nome completo válido
  • Exemplos válidos: João Silva, Maria Santos Oliveira
  • Exemplos inválidos: João, 123, joão silva (minúscula)

Comportamento de Soft Delete

🗂️ O que é Preservado vs Removido

✅ DADOS PRESERVADOS (permanecem no banco):

  • Informações pessoais: name, social_name, email, phone, document
  • IDs e chaves: id, internal_id, company_id
  • Datas: birthdate, hiring_date, firing_date, created_at, updated_at
  • Status: is_voluntary_firing, reason_firing, is_on_leave, language
  • Timestamp: deleted_at (preenchido com data/hora da exclusão)

❌ RELACIONAMENTOS REMOVIDOS:

  • Fields: Todos os vínculos em employee_fields são apagados fisicamente
  • Campanhas: Vínculos em campanhas são removidos (employee sai de todas)

🔄 Processo Técnico Detalhado

// O que acontece no EmployeeRepository::delete()

1. DELETE FROM employee_fields WHERE employee_id = ?  // Remove fields
2. DELETE FROM campaign_employees WHERE employee_id = ? // Remove campanhas  
3. UPDATE employees SET deleted_at = NOW() WHERE id = ? // Soft delete

Resultado no Banco:

-- ANTES do soft delete
employees: {id: uuid, name: "João", email: "joao@...", deleted_at: NULL}
employee_fields: [{employee_id: uuid, filter_id: uuid, value: "TI"}]
campaign_employees: [{employee_id: uuid, campaign_id: uuid}]

-- DEPOIS do soft delete  
employees: {id: uuid, name: "João", email: "joao@...", deleted_at: "2024-01-01 10:00:00"}
employee_fields: [] // ← Tabela vazia para este employee
campaign_employees: [] // ← Sem vínculos para este employee

🔍 Estado de Dados Após Soft Delete

Exemplo prático:

// Funcionário ANTES da exclusão
{
  "id": "9c73a4aa-8094-4241-ad05-658436f471fe",
  "name": "João Silva",
  "document": "12345678901",
  "email": "joao@empresa.com",
  "internal_id": "EMP001",
  "fields": [
    {"id": "filter-dept", "value": "TI"},
    {"id": "filter-cargo", "value": "Dev"}
  ],
  "deleted_at": null
}

// Registro no banco DEPOIS da exclusão (invisível via GET)
{
  "id": "9c73a4aa-8094-4241-ad05-658436f471fe", // ✅ Preservado
  "name": "João Silva",                            // ✅ Preservado  
  "document": "12345678901",                       // ✅ Preservado
  "email": "joao@empresa.com",                     // ✅ Preservado
  "internal_id": "EMP001",                         // ✅ Preservado
  "deleted_at": "2024-01-01T10:00:00+00:00"      // ✅ Timestamp da exclusão
}

// Fields foram fisicamente removidos:
employee_fields: [] // ❌ Tabela vazia para este funcionário

🔍 Visibilidade em Consultas GET

❌ Funcionários soft-deleted NÃO aparecem em:

  • GET /v1/employees (listagem)
  • GET /v1/employees?search=termo (busca)
  • GET /v1/employees/{id} (detalhes)

🔧 Implementação Laravel:

// Laravel automaticamente aplica whereNull('deleted_at') em todas as consultas
Employee::where('company_id', $companyId)->get(); 
// Retorna apenas registros com deleted_at = NULL

// Para incluir soft-deleted seria necessário:
Employee::withTrashed()->where('company_id', $companyId)->get();
// Mas este comportamento NÃO está disponível via API REST

🎯 Exemplo Prático:

// ANTES do soft delete - GET /v1/employees retorna:
{
  "data": [
    {
      "id": "uuid-joao",
      "name": "João Silva",
      "email": "joao@empresa.com"
    },
    {
      "id": "uuid-maria",
      "name": "Maria Santos",
      "email": "maria@empresa.com"
    }
  ],
  "meta": {"total": 2}
}

// DEPOIS do soft delete do João - GET /v1/employees retorna:
{
  "data": [
    {
      "id": "uuid-maria",
      "name": "Maria Santos",
      "email": "maria@empresa.com"
    }
  ],
  "meta": {"total": 1}  // ← João desapareceu das consultas
}

⚠️ Importante:

  • Não há endpoint REST para consultar funcionários excluídos
  • Recuperação só via comandos Artisan no servidor
  • Auditoria possível apenas com acesso direto ao banco

💡 Implicações Práticas

  1. Reutilização completa: Dados pessoais ficam disponíveis para nova criação
  2. Auditoria preservada: Histórico completo mantido no banco
  3. Fields perdidos: Filtros devem ser reinseridos em nova criação
  4. Unicidade liberada: CPF/email/phone voltam a estar disponíveis
  5. Invisibilidade total: Funcionário some completamente das consultas API

Busca Inteligente

🔍 Tipo de Busca: LIKE Parcial

A busca no parâmetro search utiliza LIKE parcial, não busca exata:

// Laravel scopeSearch implementa:
$query->where('name', 'LIKE', "%{$search}%")
      ->orWhere('document', 'LIKE', "%{$search}%") 
      ->orWhere('email', 'LIKE', "%{$search}%")
      ->orWhere('phone', 'LIKE', "%{$search}%")
      ->orWhere('internal_id', 'LIKE', "%{$search}%");

📋 Exemplos Práticos de Resultados

Busca por Internal ID:

GET /v1/employees?search=600

# ✅ RETORNA todos que CONTÊM "600":
- internal_id: "6000001" 
- internal_id: "60000011"
- internal_id: "EMP6001" 
- internal_id: "A600B"

Busca por Nome:

GET /v1/employees?search=Silva

# ✅ RETORNA todos que CONTÊM "Silva":
- name: "João Silva"
- name: "Maria Silva Santos" 
- name: "Pedro da Silva"
- social_name: "Ana Silva"

Busca por CPF:

GET /v1/employees?search=123

# ✅ RETORNA todos CPFs que CONTÊM "123":
- document: "12345678901"
- document: "98712345678"  
- document: "11123456789"

⚠️ Comportamento Importante

  • NÃO é match exato: search=600 ≠ internal_id = "600"
  • Case insensitive: Busca ignora maiúsculas/minúsculas
  • Busca múltipla: Procura em todos os campos simultaneamente
  • Resultado paginado: Sempre retorna com paginação (10 por página)

🎯 Casos de Uso por Campo

CampoBuscaExemplos de Match
internal_idContém substring"EMP001" encontra "EMP001", "EMP0011", "TEMP001"
documentContém dígitos"123" encontra "12345678901", "98712345678"
emailContém texto"joao" encontra "joao@empresa.com", "joaosilva@email.com"
phoneContém números"99" encontra "+5511999888777", "+5511988997766"
name/social_nameContém nome"Maria" encontra "Maria Santos", "Ana Maria"

🔍 Único Endpoint de Busca

❌ NÃO existe: GET /v1/employees/{internal_id} (por internal_id)
✅ Use sempre: GET /v1/employees?search={valor} (busca inteligente)

# Para buscar funcionário com internal_id "EMP001":
GET /v1/employees?search=EMP001

# Resposta paginada mesmo que seja 1 resultado:
{
  "data": [
    {
      "id": "uuid-encontrado",
      "internal_id": "EMP001",
      "name": "João Silva"
    }
  ],
  "meta": {
    "total": 1,
    "current_page": 1
  }
}

Limitações e Escopo

🎯 O que ESTÁ na API v1

✅ Funcionalidades Incluídas:

  • Gestão de Funcionários: CRUD completo + busca + soft delete
  • Gestão de Empresas: Listagem e configurações (identify_key, OTP)
  • Sistema de Filtros: CRUD para categorização de funcionários
  • Campanhas: Inclusão/remoção de funcionários (via include_campaign/remove_campaign)
  • Desligamento: Processo completo com firing_date + soft delete automático
  • Autenticação: Sistema de chaves de acesso via Dashboard
  • Multi-empresa: Header Resource-Id para operações entre empresas

❌ O que NÃO ESTÁ na API v1

Gestão de Campanhas:

  • CRUD de campanhas: Não há endpoints para criar/editar/excluir campanhas
  • Configuração avançada: Gerenciamento apenas via Dashboard
  • Relatórios de engajamento: Métricas não disponíveis via API

Autenticação Avançada:

  • Login de usuários: Sistema de login não é escopo da API
  • Gestão de permissões: Roles e acessos gerenciados externamente
  • Autenticação federada: Planejamento futuro

Funcionalidades Administrativas:

  • Configurações de empresa: Alterações via Dashboard, não API
  • Gestão de usuários: Administradores gerenciados externamente
  • Relatórios/Analytics: Dados de engajamento e métricas

Integrações Externas:

  • E-mail/SMS: Envio de mensagens é automático (background)
  • Webhooks: Notificações em tempo real não disponíveis
  • Sincronização: Não há endpoints de importação/exportação em massa

🔄 Por que essas Limitações?

  1. Foco específico: API v1 concentra-se em operações essenciais de funcionários
  2. Separação de responsabilidades: Dashboard gerencia configurações administrativas
  3. Segurança: Funcionalidades sensíveis isoladas do acesso via API
  4. Simplicidade: Escopo reduzido permite melhor manutenção e documentação
  5. Compliance LGPD: Evita exposição desnecessária de dados pessoais

🎯 Casos de Uso Suportados

✅ Cenários Ideais:

  • Sistema de RH: Sincronizar funcionários com plataforma interna
  • Onboarding automatizado: Criar funcionários e incluir em campanhas existentes
  • Offboarding: Processo de desligamento com histórico
  • Operação delegada: Usar Resource-Id para operar em empresas do grupo

❌ Cenários Não Suportados:

  • Gestão completa de campanhas: Criação/edição via Dashboard apenas
  • Automação de e-mails: Use funcionalidades automáticas do sistema

💡 Alternativas para Cenários Não Suportados

NecessidadeAlternativa Recomendada
Autenticação avançadaConfiguração futura via Dashboard
E-mails personalizadosSistema automático + customização via Dashboard
Gestão de campanhasCRUD via Dashboard administrativo
Relatórios de complianceUsar endpoints GET respeitando LGPD
WebhooksImplementação futura da API

Códigos de Erro

Erros de Autenticação

{
  "id": "auth-error-uuid",
  "status": 401,
  "title": "Unauthorized",
  "detail": "Token de acesso inválido ou expirado"
}

Erros de Permissão

{
  "id": "permission-error-uuid",
  "status": 403,
  "title": "Forbidden",
  "detail": "Acesso negado ao recurso solicitado"
}

Erros de Recurso Não Encontrado

{
  "id": "not-found-uuid",
  "status": 404,
  "title": "Not Found",
  "detail": "Funcionário não encontrado"
}

Erros de Validação

{
  "id": "validation-error-uuid",
  "status": 422,
  "title": "Validation Error",
  "detail": "Os dados fornecidos contêm erros",
  "meta": {
    "errors": {
      "document": ["The document field is required."],
      "email": ["The email has already been taken."],
      "phone": ["The phone format is invalid."]
    }
  }
}

Erros de Rate Limiting

{
  "id": "rate-limit-uuid",
  "status": 429,
  "title": "Too Many Requests",
  "detail": "Limite de requisições excedido. Tente novamente em 60 segundos."
}

Erros Internos

{
  "id": "server-error-uuid",
  "status": 500,
  "title": "Internal Server Error",
  "detail": "Erro interno do servidor. Contate o suporte."
}

Exemplos Práticos

Caso de Uso 1: Criando Funcionário Completo

curl -X POST https://api.winx.ai/v1/employees \
  -H "Authorization: Bearer seu-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Maria Santos Silva",
    "social_name": "Maria Santos", 
    "email": "maria@empresa.com",
    "phone": "+5511987654321",
    "document": "12345678901",
    "internal_id": "FUNC001",
    "birthdate": "15/03/1985",
    "hiring_date": "01/06/2020",
    "fields": [
      {
        "id": "uuid-filter-departamento",
        "value": "Recursos Humanos"
      },
      {
        "id": "uuid-filter-cargo", 
        "value": "Analista"
      }
    ],
    "include_campaign": true,
    "is_on_leave": false
  }'

Caso de Uso 2: Buscando Funcionários

# Busca por nome
curl "https://api.winx.ai/v1/employees?search=Maria&page=1" \
  -H "Authorization: Bearer seu-token"

# Busca por CPF  
curl "https://api.winx.ai/v1/employees?search=12345678901" \
  -H "Authorization: Bearer seu-token"

# Busca por ID interno
curl "https://api.winx.ai/v1/employees?search=FUNC001" \
  -H "Authorization: Bearer seu-token"

Caso de Uso 3: Desligamento de Funcionário

curl -X PUT https://api.winx.ai/v1/employees/uuid-funcionario \
  -H "Authorization: Bearer seu-token" \
  -H "Content-Type: application/json" \
  -d '{
    "firing_date": "15/12/2024",
    "is_voluntary_firing": false,
    "reason_firing": "Reestruturação organizacional",
    "remove_campaign": true,
    "fields": [
      {
        "id": "uuid-filter-departamento",
        "value": "Ex-funcionário"
      }
    ],
    "is_on_leave": false
  }'

Caso de Uso 4: Operação Multi-empresa

# Token da matriz operando na filial
curl https://api.winx.ai/v1/employees \
  -H "Authorization: Bearer token-matriz" \
  -H "Resource-Id: uuid-filial"

Troubleshooting Comum

Problema: Erro 422 ao criar funcionário

{
  "meta": {
    "errors": {
      "document": ["The document field is required."]
    }
  }
}

Solução: Verificar o identify_key da empresa. Se for "document", o campo CPF é obrigatório.


Problema: Erro 422 em fields

{
  "meta": {
    "errors": {
      "fields": ["Filtros obrigatórios ausentes: Departamento, Cargo"]
    }
  }
}

Solução: Incluir todos os filtros com is_required = true no array fields.


Problema: Funcionário não aparece após criação
Solução: Verificar se não foi soft-deleted automaticamente devido ao firing_date. Use withTrashed() para confirmar.


Problema: Erro 401 "Unauthorized"
Solução: Verificar se o token está válido e incluído corretamente no header Authorization.

Changelog

v1.0 (Versão Atual)

  • Implementação inicial dos endpoints de Companies, Filters e Employees
  • Sistema de autenticação Sanctum
  • Middleware de multi-tenancy com Resource-Id
  • Validações específicas para CPF, telefone brasileiro e email
  • Sistema de fields/filtros obrigatórios
  • Gestão de campanhas via include_campaign/remove_campaign
  • Soft delete automático para funcionários desligados

Próximas Versões (Planejado)

  • Endpoints de Campaigns
  • Endpoints de Surveys
  • Sistema de webhooks para notificações
  • Versionamento de dados
  • Auditoria de alterações
Modificado em 2025-11-18 20:42:33
Próxima página
📋 Listar Empresas
Built with