Catálogo da API REST
Versão: v1
Última atualização: 23/07/2026
Prefixo: /api/v1
Este catálogo descreve os endpoints implementados no backend NestJS. Os contratos devem ser atualizados junto com o código sempre que houver mudança.
Endereços
| Ambiente | Base URL |
|---|---|
| Homologação | https://api.technos.projeto.dbai.com.br/api/v1 |
| Local | http://127.0.0.1:3000/api/v1 |
Convenções
- Conteúdo JSON usa
Content-Type: application/json. - Upload manual usa
multipart/form-data. - Datas de entrada usam preferencialmente
YYYY-MM-DD. - Data e hora usam ISO 8601.
- Valores monetários são números decimais.
- Endpoints protegidos recebem
Authorization: Bearer <accessToken>. - Listagens respeitam empresa, lojas e vendedor do usuário autenticado.
Perfis abreviados
| Sigla | Papel na API | Perfil |
|---|---|---|
ADM | ADMIN, SUPER_ADMIN | Administrador |
SUP | REGIONAL_MANAGER | Supervisor |
LID | STORE_MANAGER | Líder de loja |
VEN | SELLER | Vendedor |
DEV | DEVICE | Tablet |
Quando a tabela informa autenticado, o serviço aplica o escopo do papel recebido no token.
Respostas e erros
| Código | Significado |
|---|---|
200 | Consulta ou alteração concluída |
201 | Registro criado |
400 | Dados ausentes, inválidos ou regra de negócio não atendida |
401 | Token ausente, inválido ou sessão expirada |
403 | Perfil sem permissão ou recurso fora do escopo |
404 | Recurso não encontrado |
409 | Conflito, duplicidade ou estado incompatível |
500 | Falha interna ou indisponibilidade de dependência |
Ao receber 401, o frontend encerra a sessão local e redireciona para o login.
Saúde e autenticação
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /health | Público | Verificar se a API está respondendo |
POST | /auth/login | Público | Login do backoffice |
POST | /auth/device-login | Público | Login do tablet por loja e dispositivo |
POST | /auth/seller-pin-login | Público | Validar PIN do vendedor na loja |
GET | /auth/me | Autenticado | Retornar o principal do token |
Exemplo de login:
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "usuario@empresa.com",
"password": "senha-fornecida-em-canal-seguro"
}
A resposta contém accessToken, refreshToken e os dados do usuário. Tokens e
credenciais não devem ser gravados em logs de aplicação.
Resposta do health check:
{
"status": "ok",
"service": "gv-api",
"version": "0.1.0"
}
Dados iniciais
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /app-data | Autenticado | Carga consolidada e limitada ao escopo do usuário |
GET | /app-data/public | Público | Dados mínimos para telas públicas de login |
/app-data abastece seletores e experiências do frontend. Não substitui os
endpoints transacionais.
Lojas
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /stores | Autenticado | Listar lojas visíveis |
GET | /stores/:id | Autenticado | Consultar loja dentro do escopo |
POST | /stores | ADM | Cadastrar loja |
PATCH | /stores/:id | ADM | Editar ou ativar/inativar loja |
Campos principais: code, name, format (Loja, Quiosque ou Outlet),
operation, city, state, brandId, regionId, supervisorId, cnpj,
protheusCode, operatingDays, openTime e closeTime.
operatingDays usa os números de dia da semana do JavaScript: domingo 0,
segunda 1 até sábado 6.
Usuários do backoffice
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /users?role=&storeId= | ADM, SUP | Listar usuários no escopo |
POST | /users | ADM, SUP | Criar usuário |
PATCH | /users/:id | ADM, SUP | Alterar cadastro sem criar duplicidade |
POST | /users/:id/inactivate | ADM, SUP | Inativar usuário |
POST | /users/:id/convert-to-seller | ADM, SUP | Converter o mesmo cadastro em vendedor |
Campos principais: nome, e-mail, senha, papel, foto, loja, vigência profissional, férias e situação. A troca de cargo usa atualização ou conversão e deve preservar a identidade, o histórico e a auditoria da pessoa.
Upload de fotos
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
POST | /uploads/photos | ADM, SUP, REG | Enviar a miniatura de uma pessoa |
O corpo usa multipart/form-data, com o arquivo no campo file. São aceitos JPG,
PNG e WebP com até 2 MB. A API valida e recodifica a imagem como WebP 512x512,
remove os metadados do arquivo original e responde com photoUrl, path,
filename e mimeType. O cadastro de usuário ou vendedor persiste somente a URL;
o arquivo fica no diretório definido por UPLOAD_DIR.
Vendedores, lotação e ausências
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /sellers?storeId= | Autenticado | Listar vendedores visíveis |
POST | /sellers | ADM, SUP | Cadastrar vendedor no escopo |
PATCH | /sellers/:id | ADM, SUP | Editar vendedor |
POST | /sellers/:id/inactivate | ADM, SUP | Inativar vendedor |
POST | /sellers/:id/convert-to-user | ADM, SUP | Converter em usuário do backoffice |
POST | /sellers/:id/vacation | ADM, SUP | Registrar estado de férias simples |
GET | /sellers/:id/store-assignments | ADM, SUP, LID | Consultar histórico de lotação |
POST | /sellers/:id/store-assignments | ADM, SUP | Criar cobertura ou lotação temporária |
POST | /sellers/:id/transfer | ADM, SUP | Transferir loja padrão |
DELETE | /sellers/:id/store-assignments/:assignmentId | ADM, SUP | Remover uma lotação |
GET | /sellers/:id/absences | ADM, SUP, LID | Listar ausências |
POST | /sellers/:id/absences | ADM, SUP | Cadastrar ausência ou férias por período |
DELETE | /sellers/:id/absences/:absenceId | ADM, SUP | Remover ausência |
Uma lotação recebe storeId, type, startsAt, endsAt e notes. A transferência
recebe a nova loja, a data de início e a observação. Uma ausência recebe início, fim,
motivo e observação. As mutações de ausência retornam affectedGoalCycles com as
metas que cruzam o período alterado para o frontend solicitar o recálculo.
No cadastro de vendedor, pdvCode é obrigatório. Para vendas Protheus, o vínculo
usa document/CPF como chave principal e storeId + pdvCode como alternativa.
Metas
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /goals/cycles?storeId= | Autenticado | Listar ciclos de meta |
POST | /goals/cycles | ADM, SUP | Criar ciclo para loja e período |
PATCH | /goals/cycles/:id | ADM, SUP | Editar ciclo e valores |
DELETE | /goals/cycles/:id | ADM, SUP | Excluir ciclo |
POST | /goals/store-goals | ADM, SUP | Gravar metas da loja |
POST | /goals/seller-goals | ADM, SUP | Gravar metas do vendedor |
POST | /goals/cycles/:id/publish | ADM, SUP | Publicar ciclo |
POST | /goals/import-daily | ADM, SUP | Importar metas diárias em lote |
GET | /goals/cycles/:id/distribution | ADM, SUP | Obter distribuição diária |
PATCH | /goals/cycles/:id/distribution | ADM, SUP | Ajustar distribuição diária |
POST | /goals/cycles/:id/recalculate-availability | ADM, SUP | Refazer rateio pela disponibilidade atual |
GET | /goals/current?storeId=&sellerId= | Autenticado | Consultar meta vigente |
Criação do ciclo:
{
"storeId": "uuid-da-loja",
"name": "Meta 07/2026",
"startsAt": "2026-07-01",
"endsAt": "2026-07-31"
}
A edição estrutural da distribuição usa allocations. Esse formato permite
incluir ou remover linhas quando férias, ausências ou lotações alteram os dias
disponíveis:
{
"allocations": [
{
"sellerId": "uuid-do-vendedor",
"date": "2026-08-21",
"amount1": 5000,
"amount2": 5750,
"amount3": 6500
}
]
}
A API valida escopo, vendedor, período, loja, disponibilidade e duplicidade de vendedor/data. Em seguida recria as metas diárias e consolida os totais de cada vendedor e da loja em uma transação auditada.
O recálculo por disponibilidade soma primeiro a distribuição já existente para preservar a meta de cada data. Depois reparte cada dia somente entre os vendedores do ciclo que estejam disponíveis conforme férias, ausências, vigência e lotação.
A importação diária recebe todos os dias do mês para cada loja. amount2 e
amount3 são opcionais; quando ausentes, a API calcula 115% e 130% da meta
principal. Com dryRun=true, todas as validações e o rateio são simulados sem
gravação.
{
"dryRun": false,
"rows": [
{
"storeId": "uuid-da-loja",
"date": "2026-08-01",
"amount1": 22000
},
{
"storeId": "uuid-da-loja",
"date": "2026-08-02",
"amount1": 0
}
]
}
O lote é transacional: conflito de loja/mês, data ausente, duplicidade, valor inválido ou dia positivo sem vendedor impede a gravação de todos os ciclos. A meta de cada dia é dividida em centavos entre os vendedores disponíveis, com diferença máxima de um centavo entre as parcelas.
A distribuição recebe uma lista de metas diárias:
{
"dailyGoals": [
{
"id": "uuid-meta-diaria",
"amount1": 1200,
"amount2": 1320,
"amount3": 1440
}
]
}
Campanhas, motivos e feriados
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /campaigns | ADM, SUP, LID | Listar campanhas visíveis |
POST | /campaigns | ADM, SUP | Criar campanha |
PATCH | /campaigns/:id | ADM, SUP | Editar campanha |
DELETE | /campaigns/:id | ADM, SUP | Excluir campanha |
GET | /loss-reasons | ADM, SUP, LID | Listar motivos de perda |
POST | /loss-reasons | ADM | Criar motivo com nome e ícone |
PATCH | /loss-reasons/:id | ADM | Editar nome e ícone |
POST | /loss-reasons/:id/inactivate | ADM | Inativar motivo |
GET | /holidays?dateFrom=&dateTo= | ADM, SUP | Listar calendário visível |
POST | /holidays | ADM | Cadastrar feriado ou ponto facultativo |
PATCH | /holidays/:id | ADM | Editar calendário e lojas |
POST | /holidays/:id/inactivate | ADM | Inativar ocorrência |
O feriado informa nome, data, tipo (HOLIDAY ou OPTIONAL_DAY), abrangência, estado,
cidade, lojas, e se deve ser excluído dos dias da meta.
Tablet e atendimentos
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /tablet/bootstrap?storeId=&deviceId= | Autenticado | Inicializar dados do tablet |
POST | /tablet/events | Autenticado | Receber um evento idempotente |
POST | /tablet/events/batch | Autenticado | Sincronizar fila de eventos offline |
GET | /tablet/sync-status?deviceId= | Autenticado | Verificar sincronização do dispositivo |
GET | /attendances?storeId=&date= | Autenticado | Listar atendimentos |
POST | /attendances/:id/finish | Autenticado | Finalizar atendimento |
Eventos implementados para atendimento:
ATTENDANCE_STARTED;ATTENDANCE_FINISHED;STORE_DAY_ENDED, registrado no encerramento do dia.
Exemplo de evento:
{
"clientEventId": "uuid-gerado-no-tablet",
"deviceId": "uuid-dispositivo",
"storeId": "uuid-loja",
"eventType": "ATTENDANCE_FINISHED",
"createdAtLocal": "2026-07-23T18:30:00-03:00",
"payload": {
"attendanceId": "uuid-atendimento",
"result": "NOT_CONVERTED",
"lossReasonId": "uuid-motivo"
}
}
O backend usa clientEventId para impedir duplicidade na sincronização offline.
Vendas
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /sales?storeId=&dateFrom=&dateTo= | Autenticado | Consultar vendas do escopo |
POST | /sales/import | ADM, SUP | Importar lote JSON de vendas |
Cada venda importada informa loja, vendedor opcional, identificador externo, data, valor e quantidade de peças.
Validação diária
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /validations?storeId=&dateFrom=&dateTo= | ADM, SUP, LID | Listar dias e totais |
POST | /validations/:id/adjust | ADM, SUP, LID | Ajustar uma linha com justificativa |
POST | /validations/day/validate | ADM, SUP, LID | Validar loja e dia |
POST | /validations/:id/block-auto-update | ADM, SUP, LID | Bloquear atualização automática |
POST | /validations/:id/unblock-auto-update | ADM, SUP, LID | Liberar atualização automática |
Validação de um dia:
{
"storeId": "uuid-loja",
"date": "2026-07-22",
"notes": "Conferido com o fechamento da loja",
"autoUpdateBlocked": true,
"rows": [
{
"validationId": "uuid-validacao",
"adjustedSalesAmount": 12540.9,
"adjustedPiecesQuantity": 32,
"adjustedSalesQuantity": 18
}
]
}
Sem mudança de valor, o status é validado. Havendo alteração, fica validado com edição manual. O usuário, a data e a justificativa são auditados.
Validação de NF
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /invoice-validations | ADM, SUP, LID | Listar divergências |
GET | /invoice-validations/missing-seller-summary | ADM, SUP, LID | Totalizar NFs sem vendedor |
GET | /invoice-validations/:id | ADM, SUP, LID | Abrir detalhe |
POST | /invoice-validations/sync-sellers | ADM, SUP, LID | Vincular NFs a vendedores novos |
POST | /invoice-validations/:id/validate | ADM, SUP, LID | Corrigir, incluir/excluir e validar |
Filtros da lista: storeId, status, dateFrom, dateTo, issueType e search.
Tipos atuais: vendedor ausente, valor, quantidade, vendedor, data ou loja alterados.
O resumo aceita storeId, operation, dateFrom e dateTo. O reprocessamento
de vendedores respeita o mesmo escopo de loja/operação e usa CPF ou a combinação
loja + código PDV, sem criar ou alterar cadastros de funcionários.
{
"sellerId": "uuid-vendedor-ou-null",
"soldAt": "2026-07-22",
"amount": 899.9,
"piecesQty": 2,
"includedInMetrics": true,
"notes": "Conferido com a loja"
}
includedInMetrics=false mantém a NF no histórico, mas a retira dos dashboards,
metas e agregações comerciais.
Relatórios e feedbacks
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
GET | /reports/dashboard?storeId=&dateFrom=&dateTo= | Autenticado | Consolidado do dashboard |
GET | /reports/sales-analytic | Autenticado | Analítico de vendas |
GET | /feedbacks?storeId=&sellerId=&managerId= | Autenticado | Listar feedbacks |
POST | /feedbacks | ADM, SUP, LID | Registrar feedback e plano de ação |
O analítico aceita storeId, sellerId, dateFrom, dateTo, status, origin,
search e take.
No consolidado do Dashboard, salesAmount, salesQuantity e piecesQuantity
consideram somente vendas com vendedor vinculado. O campo
unidentifiedSalesAmount retorna separadamente o valor pendente das NFs sem
vendedor.
Integrações e configurações
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
POST | /integrations/protheus/sync | ADM | Sincronizar CNPJs e período |
POST | /integrations/protheus/test-connection | ADM | Testar credencial sem salvar |
GET | /integrations/protheus/logs | ADM | Consultar até 100 execuções |
GET | /integrations/protheus/status | ADM | Consultar agendador |
POST | /integrations/protheus/logs/:id/reprocess | ADM | Repetir uma execução |
POST | /integrations/protheus/logs/reprocess-failed | ADM | Recuperar períodos com falha |
GET | /integrations/data-source/logs | ADM | Logs de API e planilha |
POST | /integrations/data-source/manual-upload | ADM | Importar XLSX, XLS ou CSV |
GET | /settings/parameters | ADM | Consultar parâmetros |
PATCH | /settings/parameters | ADM | Alterar parâmetros permitidos |
GET | /settings/protheus-credentials | ADM | Consultar estado mascarado |
PATCH | /settings/protheus-credentials | ADM | Salvar credencial criptografada |
GET | /audit-logs | ADM, SUP, LID | Consultar trilha de auditoria |
O upload usa o campo multipart file, aceita até 10 MB e os formatos .xlsx, .xls
e .csv.
A sincronização Protheus trata o cadastro de vendedores como somente leitura: não
cria nem atualiza pessoas. O resultado informa sellerMatches e sellerNotFound;
movimentos sem correspondência geram MISSING_SELLER no Validador NF.
Parâmetros disponíveis:
timezone,currencyedateFormat;sellerPinDigitsetabletIdleMinutes;validationToleranceegoalRounding;dataSource, comprotheusoumanual;dailySyncTimeeprotheusReviewDays;protheusClosingDayeprotheusClosingTime.
Filtros de auditoria: limit, personId, entityId e actorUserId.
Teste rápido
curl https://api.technos.projeto.dbai.com.br/api/v1/health
Para uma chamada protegida:
curl \
-H "Authorization: Bearer $GV_ACCESS_TOKEN" \
"https://api.technos.projeto.dbai.com.br/api/v1/stores"
Limitações documentais atuais
O projeto ainda não publica uma especificação OpenAPI/Swagger gerada automaticamente. Este catálogo e os controllers NestJS são a referência vigente. Adicionar geração OpenAPI é recomendado antes da abertura da API a terceiros.
