Documentação/APIs e integrações
Desenvolvimento e integrações
10 min de leitura

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

AmbienteBase URL
Homologaçãohttps://api.technos.projeto.dbai.com.br/api/v1
Localhttp://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

SiglaPapel na APIPerfil
ADMADMIN, SUPER_ADMINAdministrador
SUPREGIONAL_MANAGERSupervisor
LIDSTORE_MANAGERLíder de loja
VENSELLERVendedor
DEVDEVICETablet

Quando a tabela informa autenticado, o serviço aplica o escopo do papel recebido no token.

Respostas e erros

CódigoSignificado
200Consulta ou alteração concluída
201Registro criado
400Dados ausentes, inválidos ou regra de negócio não atendida
401Token ausente, inválido ou sessão expirada
403Perfil sem permissão ou recurso fora do escopo
404Recurso não encontrado
409Conflito, duplicidade ou estado incompatível
500Falha 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étodoRotaAcessoFinalidade
GET/healthPúblicoVerificar se a API está respondendo
POST/auth/loginPúblicoLogin do backoffice
POST/auth/device-loginPúblicoLogin do tablet por loja e dispositivo
POST/auth/seller-pin-loginPúblicoValidar PIN do vendedor na loja
GET/auth/meAutenticadoRetornar 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étodoRotaAcessoFinalidade
GET/app-dataAutenticadoCarga consolidada e limitada ao escopo do usuário
GET/app-data/publicPúblicoDados 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étodoRotaAcessoFinalidade
GET/storesAutenticadoListar lojas visíveis
GET/stores/:idAutenticadoConsultar loja dentro do escopo
POST/storesADMCadastrar loja
PATCH/stores/:idADMEditar 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étodoRotaAcessoFinalidade
GET/users?role=&storeId=ADM, SUPListar usuários no escopo
POST/usersADM, SUPCriar usuário
PATCH/users/:idADM, SUPAlterar cadastro sem criar duplicidade
POST/users/:id/inactivateADM, SUPInativar usuário
POST/users/:id/convert-to-sellerADM, SUPConverter 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étodoRotaAcessoFinalidade
POST/uploads/photosADM, SUP, REGEnviar 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étodoRotaAcessoFinalidade
GET/sellers?storeId=AutenticadoListar vendedores visíveis
POST/sellersADM, SUPCadastrar vendedor no escopo
PATCH/sellers/:idADM, SUPEditar vendedor
POST/sellers/:id/inactivateADM, SUPInativar vendedor
POST/sellers/:id/convert-to-userADM, SUPConverter em usuário do backoffice
POST/sellers/:id/vacationADM, SUPRegistrar estado de férias simples
GET/sellers/:id/store-assignmentsADM, SUP, LIDConsultar histórico de lotação
POST/sellers/:id/store-assignmentsADM, SUPCriar cobertura ou lotação temporária
POST/sellers/:id/transferADM, SUPTransferir loja padrão
DELETE/sellers/:id/store-assignments/:assignmentIdADM, SUPRemover uma lotação
GET/sellers/:id/absencesADM, SUP, LIDListar ausências
POST/sellers/:id/absencesADM, SUPCadastrar ausência ou férias por período
DELETE/sellers/:id/absences/:absenceIdADM, SUPRemover 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étodoRotaAcessoFinalidade
GET/goals/cycles?storeId=AutenticadoListar ciclos de meta
POST/goals/cyclesADM, SUPCriar ciclo para loja e período
PATCH/goals/cycles/:idADM, SUPEditar ciclo e valores
DELETE/goals/cycles/:idADM, SUPExcluir ciclo
POST/goals/store-goalsADM, SUPGravar metas da loja
POST/goals/seller-goalsADM, SUPGravar metas do vendedor
POST/goals/cycles/:id/publishADM, SUPPublicar ciclo
POST/goals/import-dailyADM, SUPImportar metas diárias em lote
GET/goals/cycles/:id/distributionADM, SUPObter distribuição diária
PATCH/goals/cycles/:id/distributionADM, SUPAjustar distribuição diária
POST/goals/cycles/:id/recalculate-availabilityADM, SUPRefazer rateio pela disponibilidade atual
GET/goals/current?storeId=&sellerId=AutenticadoConsultar 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étodoRotaAcessoFinalidade
GET/campaignsADM, SUP, LIDListar campanhas visíveis
POST/campaignsADM, SUPCriar campanha
PATCH/campaigns/:idADM, SUPEditar campanha
DELETE/campaigns/:idADM, SUPExcluir campanha
GET/loss-reasonsADM, SUP, LIDListar motivos de perda
POST/loss-reasonsADMCriar motivo com nome e ícone
PATCH/loss-reasons/:idADMEditar nome e ícone
POST/loss-reasons/:id/inactivateADMInativar motivo
GET/holidays?dateFrom=&dateTo=ADM, SUPListar calendário visível
POST/holidaysADMCadastrar feriado ou ponto facultativo
PATCH/holidays/:idADMEditar calendário e lojas
POST/holidays/:id/inactivateADMInativar 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étodoRotaAcessoFinalidade
GET/tablet/bootstrap?storeId=&deviceId=AutenticadoInicializar dados do tablet
POST/tablet/eventsAutenticadoReceber um evento idempotente
POST/tablet/events/batchAutenticadoSincronizar fila de eventos offline
GET/tablet/sync-status?deviceId=AutenticadoVerificar sincronização do dispositivo
GET/attendances?storeId=&date=AutenticadoListar atendimentos
POST/attendances/:id/finishAutenticadoFinalizar 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étodoRotaAcessoFinalidade
GET/sales?storeId=&dateFrom=&dateTo=AutenticadoConsultar vendas do escopo
POST/sales/importADM, SUPImportar 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étodoRotaAcessoFinalidade
GET/validations?storeId=&dateFrom=&dateTo=ADM, SUP, LIDListar dias e totais
POST/validations/:id/adjustADM, SUP, LIDAjustar uma linha com justificativa
POST/validations/day/validateADM, SUP, LIDValidar loja e dia
POST/validations/:id/block-auto-updateADM, SUP, LIDBloquear atualização automática
POST/validations/:id/unblock-auto-updateADM, SUP, LIDLiberar 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étodoRotaAcessoFinalidade
GET/invoice-validationsADM, SUP, LIDListar divergências
GET/invoice-validations/missing-seller-summaryADM, SUP, LIDTotalizar NFs sem vendedor
GET/invoice-validations/:idADM, SUP, LIDAbrir detalhe
POST/invoice-validations/sync-sellersADM, SUP, LIDVincular NFs a vendedores novos
POST/invoice-validations/:id/validateADM, SUP, LIDCorrigir, 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étodoRotaAcessoFinalidade
GET/reports/dashboard?storeId=&dateFrom=&dateTo=AutenticadoConsolidado do dashboard
GET/reports/sales-analyticAutenticadoAnalítico de vendas
GET/feedbacks?storeId=&sellerId=&managerId=AutenticadoListar feedbacks
POST/feedbacksADM, SUP, LIDRegistrar 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étodoRotaAcessoFinalidade
POST/integrations/protheus/syncADMSincronizar CNPJs e período
POST/integrations/protheus/test-connectionADMTestar credencial sem salvar
GET/integrations/protheus/logsADMConsultar até 100 execuções
GET/integrations/protheus/statusADMConsultar agendador
POST/integrations/protheus/logs/:id/reprocessADMRepetir uma execução
POST/integrations/protheus/logs/reprocess-failedADMRecuperar períodos com falha
GET/integrations/data-source/logsADMLogs de API e planilha
POST/integrations/data-source/manual-uploadADMImportar XLSX, XLS ou CSV
GET/settings/parametersADMConsultar parâmetros
PATCH/settings/parametersADMAlterar parâmetros permitidos
GET/settings/protheus-credentialsADMConsultar estado mascarado
PATCH/settings/protheus-credentialsADMSalvar credencial criptografada
GET/audit-logsADM, SUP, LIDConsultar 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, currency e dateFormat;
  • sellerPinDigits e tabletIdleMinutes;
  • validationTolerance e goalRounding;
  • dataSource, com protheus ou manual;
  • dailySyncTime e protheusReviewDays;
  • protheusClosingDay e protheusClosingTime.

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.