- A classificação de pastas agora é por prefixo (s-/p-/sub); a lista de siglas autorizadas no .env não é mais usada. - Remove a variável do apiConfig e as referências (env + seção "Siglas de Pastas") do README, documentando a nova convenção de prefixo. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18 KiB
Sothis Contratação API
Visão Geral
A Sothis Contratação API é uma solução robusta para automatizar e facilitar o processo de novas contratações. A aplicação gerencia consultas de viabilidade técnica e a criação de prospectos de clientes no sistema integrado Hubsoft.
Funcionalidades Principais
- Consulta de Viabilidade por CEP e Número: Verifica a viabilidade técnica de um endereço e retorna informações sobre disponibilidade de serviços (dedicado e não-dedicado) com base na proximidade de pontos de presença.
- Consulta de Viabilidade por Coordenadas: Consulta viabilidade usando latitude e longitude com reverse geocoding.
- Criação de Prospectos: Registra novos clientes (Pessoa Física ou Jurídica) no sistema de gestão Hubsoft com suporte a diferentes planos de banda larga.
Features Técnicas
- Express.js 5.1: Framework web moderno para construção de APIs RESTful.
- Arquitetura Modular: Estrutura baseada em MVC com separação clara entre Controller, Service, Repository e Model.
- Integração com Múltiplas APIs:
- Google Maps Geocoding: Para geocodificação e reverse geocoding de endereços.
- GeoGrid API: Consulta de pontos de presença e viabilidade técnica.
- Hubsoft API: Gestão de prospectos e clientes.
- CEP Validation: Integração com
cep-promisepara validação e busca de endereços brasileiros. - Logging Avançado: Sistema de logging estruturado com
winstone arquivo rotativo diário. - Configuração por Ambiente: Suporte a múltiplos ambientes (desenvolvimento/produção) via
dotenv. - CORS Configurado: Habilitado para domínios específicos (
sothis.com.brebandalarga.srv.br). - PostgreSQL Ready: Preparado para persistência de dados com
pg. - Desenvolvimento Otimizado: Hot-reload automático com
nodemon.
Pré-requisitos
- Node.js (versão 18.x ou superior recomendada)
- npm (geralmente instalado junto com o Node.js)
- PostgreSQL (opcional, para persistência de dados)
- Chaves de API: Google Maps, GeoGrid, Hubsoft
1. Instalação
Clone o repositório e instale as dependências:
npm install
2. Configuração
A aplicação utiliza arquivos .env para carregar suas configurações. Você precisará criar dois arquivos na raiz do projeto:
.env.development(para ambiente de desenvolvimento).env.production(para ambiente de produção)
Variáveis de Ambiente Obrigatórias
# Servidor
PORT=3000
NODE_ENV=development
# Google Maps Geocoding API (para geocodificação e reverse geocoding)
GOOGLE_API_KEY=sua_chave_google_maps_aqui
# GeoGrid API (para consulta de viabilidade técnica)
GEOGRID_API_URL=https://.../viabilidade/raio # URL COMPLETA da consulta por raio
GEOGRID_API_KEY=sua_chave_geogrid_aqui
GEOGRID_API_COOKIE=seu_cookie_geogrid_aqui
# Distância REAL de trajeto (opcionais — têm defaults seguros)
GEOGRID_API_BASE_URL=https://.../vale/api/v3 # base p/ o endpoint de trajeto; se ausente, derivada da URL de consulta
GEOGRID_TRAJETO_MODO=walking # modo do trajeto
GEOGRID_TRAJETO_TOP_N=3 # nº de caixas roteadas na consulta individual (precisão)
GEOGRID_TRAJETO_TOP_N_LOTE=2 # nº de caixas roteadas por item no lote (a planilha mostra 2 caixas)
GEOGRID_CONCURRENCY=5 # chamadas externas simultâneas no lote
# Hubsoft API (para gestão de prospectos)
HUBSOFT_URL=https://seu-dominio.hubsoft.com.br
HUBSOFT_CLIENT_ID=seu_client_id_hubsoft
HUBSOFT_CLIENT_SECRET=seu_client_secret_hubsoft
HUBSOFT_USERNAME=seu_usuario_hubsoft
HUBSOFT_PASSWORD=sua_senha_hubsoft
HUBSOFT_GRANT_TYPE=password
# Database PostgreSQL (opcional, para persistência de viabilidades)
DB_HOST=localhost
DB_PORT=5432
DB_USER=seu_usuario_postgres
DB_PASSWORD=sua_senha_postgres
DB_NAME=contratacao_db
Classificação de Pastas (provedor)
O provedor é resolvido pelo prefixo da sigla da pasta no GeoGrid (não há configuração no .env):
s-...→ Sothis (rede própria).p-<nome>...→ parceiro; o provedor é o nome que vem depois do-(ex.:p-Vivo→Vivo).- Um segmento
subapós o-marca rede subterrânea e prefixa(Subterrâneo)no provedor (ex.:s-sub-Barueri→(Subterrâneo) Sothis). - Qualquer sigla fora dessa convenção é considerada não elegível (ignorada).
3. Rodando a Aplicação
Modo de Desenvolvimento
Este comando inicia a API com nodemon, que reinicia o servidor automaticamente a cada alteração nos arquivos. As configurações serão carregadas do .env.development.
npm run dev:api
A API será iniciada na porta configurada (padrão 3000) e exibirá:
🚀 Servidor API rodando na porta 3000 em modo development
Modo de Produção
Este comando inicia a API de forma otimizada para produção usando node. As configurações serão carregadas do .env.production.
npm run start:api
Logging e Monitoramento
A aplicação utiliza Winston para logging estruturado com as seguintes características:
- Arquivos de Log: Criados automaticamente no diretório
logs/ - Rotação Diária: Novos arquivos criados a cada dia com formato
application-YYYY-MM-DD.log - Níveis de Log:
info: Requisições recebidas, operações bem-sucedidaswarn: Advertências e situações inesperadaserror: Erros e exceções
Exemplo de Logs
2026-05-20T10:30:45.123Z [info]: 🚀 Servidor API rodando na porta 3000 em modo development
2026-05-20T10:31:20.456Z [info]: Requisição recebida: POST /api/viabilidade - IP: 127.0.0.1
2026-05-20T10:31:21.789Z [info]: Endereço obtido com sucesso via cep-promise
2026-05-20T10:31:23.234Z [info]: Coordenadas obtidas com sucesso - lat: -23.5070, lon: -46.4036
2026-05-20T10:31:25.567Z [info]: Viabilidade salva com sucesso
Tratamento de Erros
A API implementa tratamento robusto de erros:
- Validação de Entrada: CEP e número são obrigatórios na consulta de viabilidade
- Erros de Integração: Erros de terceiros são tratados e retornam respostas HTTP apropriadas
- Logging de Erros: Todos os erros são registrados com stack trace completo
- Respostas Consistentes: Erros retornam status HTTP apropriado e mensagem descritiva
Integração com Serviços Externos
Google Maps Geocoding
- Uso: Converter endereço em coordenadas e vice-versa (reverse geocoding)
- Rate Limit: Respeitar limites da Google API
GeoGrid API
- Uso: Consultar pontos de presença e viabilidade de instalação
- Autenticação: Via API Key e Cookie
Hubsoft API
- Uso: Criação e gestão de prospectos
- Autenticação: OAuth 2.0 com grant_type=password
Configuração de CORS
A API está configurada para aceitar requisições apenas de domínios específicos:
✅ https://sothis.com.br
✅ https://bandalarga.srv.br
Métodos HTTP Permitidos:
- GET, POST, PUT, DELETE, OPTIONS
Headers Permitidos:
- Content-Type
- Authorization
Para adicionar novos domínios, edite o arquivo app.js:18.
Documentação da API
O prefixo para todos os endpoints é /api.
1. Consulta de Viabilidade por CEP
Verifica a viabilidade técnica de um endereço usando CEP e número.
-
Endpoint:
POST /viabilidade -
Descrição: Realiza geocodificação do endereço e consulta viabilidade na GeoGrid baseado em pontos de presença.
-
Corpo da Requisição (
application/json):{ "nome": "João Silva", "email": "joao@email.com", "telefone": "11987654321", "cep": "06419240", "numero": "303", "source": "" } -
Resposta de Sucesso (
200 OK):{ "nome": "João Silva", "email": "joao@email.com", "telefone": "11987654321", "logradouro": "Rua Imirim", "numero": "303", "bairro": "Chácaras Marco", "cidade": "Barueri", "estado": "SP", "cep": "06419240", "naoDedicado": true, "dedicado": true, "distancia": 250, "provedor": "Sothis" }Campos da Resposta:
naoDedicado: Serviço disponível em banda compartilhada (distância real ≤ 500m)dedicado: Serviço disponível em banda dedicada (distância real ≤ 1000m)distancia: Distância real de trajeto em metros até a caixa mais próxima (ou "5KM+" se não houver caixa no raio). Se o trajeto falhar, cai para a distância em linha reta.distanciaReta: Distância em linha reta em metros (aditivo, para comparação).provedor: Identificação do provedor pela convenção de prefixo da sigla de pasta (ver "Classificação de Pastas")
Nota: a regra de viabilidade e o campo
distanciapassaram a usar a distância real de trajeto (via GeoGrid/integracao/trajeto/cordenada). Como a real é sempre ≥ a linha reta, endereços de borda podem deixar de viabilizar em relação ao comportamento anterior. -
Respostas de Erro:
400 Bad Request: Secepounumeronão forem fornecidos.422 Unprocessable Entity: Se os dados de endereço estiverem incompletos ou inválidos.502 Bad Gateway: Se o CEP for inválido ou não encontrado na bibliotecacep-promise.500 Internal Server Error: Para outros erros no processo.
1.1. Consulta de Viabilidade em Lote
Consulta viabilidade para vários endereços/coordenadas de uma vez (usado pelo viabiliza). Reusa o mesmo core de viabilidade, com top-N de trajeto reduzido e concorrência limitada.
-
Endpoint:
POST /viabilidade/lote -
Corpo da Requisição (
application/json):{ "itens": [ { "cep": "06419240", "numero": "303" }, { "latitude": "-23.5070", "longitude": "-46.4036" } ], "modo": "walking" } -
Resposta de Sucesso (
200 OK): array alinhado por índice aoitensenviado.{ "resultados": [ { "index": 0, "provedor": "Sothis", "distancia": 630, "distanciaReta": 300, "distanciaReal": 630, "dedicado": true, "naoDedicado": false, "caixas": [ { "provedor": "Sothis", "sigla": "A", "distancia": 420, "distanciaReta": 300, "distanciaReal": 420, "dedicado": true, "naoDedicado": true }, { "provedor": "Parceiro - X", "sigla": "B", "distancia": 900, "distanciaReta": 700, "distanciaReal": 900, "dedicado": true, "naoDedicado": false } ] }, { "index": 1, "erro": "Item inválido: informe cep+numero ou latitude+longitude." } ] }caixas: detalhe por caixa (as mais próximas em linha reta primeiro), cada uma com seu próprio provedor, distância de trajeto e classificação. No lote a seleção é mista (as N mais próximas de qualquer provedor — rede própria e parceiros), então caixas na mesma linha podem ter provedores diferentes. O viabiliza usa as 2 primeiras para montar as colunas da planilha (Provedor/Não Dedicado/Dedicado/Distância por caixa). A consulta individual (/viabilidade) continua priorizando Sothis.- Cada item é resolvido de forma independente: um erro em um item não derruba os demais (vem no campo
erro). - Coordenadas/CEPs repetidos são deduplicados (uma chamada externa por chave única).
2. Consulta de Viabilidade por Coordenadas
Verifica a viabilidade técnica usando latitude e longitude com reverse geocoding.
-
Endpoint:
POST /viabilidade/lat-long -
Descrição: Consulta viabilidade baseado em coordenadas geográficas e realiza reverse geocoding.
-
Corpo da Requisição (
application/json):{ "latitude": "-23.5070", "longitude": "-46.4036" } -
Resposta de Sucesso (
200 OK):{ "endereco": "Avenida Paulista, 1000 - Bela Vista - São Paulo, SP", "naoDedicado": false, "dedicado": true, "distancia": 750, "provedor": "Sothis" } -
Respostas de Erro:
500 Internal Server Error: Se ocorrer erro na consulta ou reverse geocoding.
3. Criação de Prospecto
Cria um novo cliente (Pessoa Física ou Jurídica) no Hubsoft.
-
Endpoint:
POST /prospecto -
Descrição: Registra um novo prospecto no sistema Hubsoft com dados de contato e plano selecionado.
-
Corpo da Requisição (
application/json):Para Pessoa Física (CPF não vazio):
{ "prospectData": { "Nome completo": "João Silva Santos", "CPF": "123.456.789-00", "Nome da mãe": "Maria Silva", "Data de nascimento": "15/05/1985", "E-mail": "joao@email.com", "Celular": "(11) 98765-4321", "CEP": "06419240", "Logradouro": "Rua Imirim", "Número": "303", "Complemento": "Apto 42", "Bairro": "Chácaras Marco", "Descrição": "100 Mega + Super WiFi", "Valor (mensal)": "R$ 119,90" } }Para Pessoa Jurídica (CPF vazio, CNPJ preenchido):
{ "prospectData": { "Razão Social": "Empresa LTDA", "CNPJ": "12.345.678/0001-90", "E-mail": "contato@empresa.com", "Celular": "(11) 98765-4321", "CEP": "06419240", "Logradouro": "Rua Imirim", "Número": "303", "Complemento": "", "Bairro": "Chácaras Marco", "Descrição": "500 Mega + Super WiFi + IP Fixo", "Valor (mensal)": "R$ 249,90", "CPF:": "" } }Planos Disponíveis:
100 Mega + Super WiFi(ID: 22)200 Mega + Super WiFi(ID: 94)500 Mega + Super WiFi(ID: 96)700 Mega + Super WiFi(ID: 97)1 Gb + Super WiFi(ID: 32)- Variações com
+ IP Fixo
-
Resposta de Sucesso (
200 OK):{ "message": "Prospecto criado com sucesso", "data": { "tipo_pessoa": "pf", "nome_razao_social": "João Silva Santos", "cpf_cnpj": "123.456.789-00", "email": "joao@email.com", "telefone": "11987654321", "endereco": "Rua Imirim", "numero": "303", "bairro": "Chácaras Marco", "cep": "06419240", "servico": { "id_servico": 22, "valor": 119.90 } } } -
Respostas de Erro:
400 Bad Request: Se o plano informado for inválido ou não encontrado.500 Internal Server Error: Se ocorrer erro na comunicação com Hubsoft.
Estrutura do Projeto
src/
├── app.js # Ponto de entrada da aplicação
├── routes/
│ └── routes.js # Definição de rotas
├── modules/
│ └── contratacao/
│ ├── contratacao.controller.js # Controladoras HTTP
│ ├── contratacao.service.js # Lógica de negócio
│ ├── contratacao.repository.js # Acesso a dados
│ └── contratacao.model.js # Modelos de dados
└── shared/
├── apis/
│ ├── googleService.js # Integração Google Maps
│ ├── geogridService.js # Integração GeoGrid
│ └── hubsoftService.js # Integração Hubsoft
├── config/
│ ├── environment.js # Carregamento de variáveis
│ ├── apiConfig.js # Configurações de API
│ └── dbConfig.js # Configurações de banco
└── utils/
└── logger.js # Sistema de logging
Boas Práticas e Considerações
Validação de CEP
- A biblioteca
cep-promiserealiza consulta em múltiplas bases de dados brasileiras - Retorna erro 502 se o CEP for inválido ou não encontrado
Distância de Viabilidade
- ≤ 500m: Ambos serviços disponíveis (dedicado e não-dedicado)
- 500m - 1000m: Apenas serviço dedicado disponível
- > 1000m: Nenhum serviço disponível (retorna "5KM+")
Criação de Prospectos
- O tipo de pessoa é detectado automaticamente: CPF não vazio = Pessoa Física, CNPJ com CPF vazio = Pessoa Jurídica
- Números de telefone são sanitizados automaticamente (removem caracteres não-numéricos)
- Valores monetários aceitam diversos formatos (R$ 119,90 ou 119.90)
Segurança
- CORS restrito a domínios específicos
- Todas as requisições são logadas com IP e método
- Erros não expõem informações sensíveis ao cliente
Troubleshooting
Erro: "CEP não encontrado"
- Verifique se o CEP está correto e tem 8 dígitos
- Alguns CEPs novos podem não estar na base de dados
Erro: "Sem caixas dentro de 5km"
- Significa que não há ponto de presença próximo ao endereço
- O serviço não é viável para esta localização
Erro: "Plano inválido"
- Verifique se a descrição do plano corresponde exatamente a um dos planos mapeados
- Referência: contratacao.service.js:159-170
Logs não aparecem
- Verifique se a pasta
logs/foi criada (criada automaticamente) - Verifique permissões de escrita no diretório do projeto
Histórico de Mudanças
Recent Updates
- ✅ Adicionado tratamento de erro para casos sem caixa em 5km
- ✅ Implementada variável de sigla de pasta no .env com mapeamento de provedor
- ✅ Refatorada busca de CEP usando
cep-promise - ✅ Adicionada URL de banda larga na configuração de CORS
- ✅ Atualizado suporte de CORS para Express 5.x
Suporte e Contribuições
Para reportar bugs ou sugerir melhorias, entre em contato com a equipe de desenvolvimento Sothis.
Contato: gabriel.amancio@sothis.com.br
Licença
ISC