2025-11-12 11:13:39 -03:00
|
|
|
const axios = require("axios");
|
2025-11-24 16:13:35 -03:00
|
|
|
const logger = require('../utils/logger.js');
|
2025-11-12 11:13:39 -03:00
|
|
|
|
2025-11-18 08:26:50 -03:00
|
|
|
// Consulta o endereço completo usando a API externa de CEP
|
|
|
|
|
|
2025-12-08 15:43:20 -03:00
|
|
|
const getConsultaCep = async (rawCep) => {
|
|
|
|
|
logger.info('Iniciando consulta de CEP');
|
2025-11-24 16:13:35 -03:00
|
|
|
|
2025-11-14 08:16:04 -03:00
|
|
|
if (!rawCep) {
|
2025-11-24 16:13:35 -03:00
|
|
|
logger.warn('CEP não fornecido para getConsultaCep');
|
2025-11-14 08:16:04 -03:00
|
|
|
throw new Error("cep é obrigatório");
|
|
|
|
|
}
|
2025-11-12 11:13:39 -03:00
|
|
|
const cep = String(rawCep).trim().replace(/\D/g, "");
|
2025-11-14 08:16:04 -03:00
|
|
|
if (cep.length !== 8) {
|
2025-11-24 16:13:35 -03:00
|
|
|
logger.warn('CEP inválido fornecido para getConsultaCep', { cepBruto: rawCep, cepLimpo: cep });
|
2025-11-14 08:16:04 -03:00
|
|
|
throw new Error("cep inválido, verifique se foram digitados apenas números");
|
|
|
|
|
}
|
2025-11-18 08:26:50 -03:00
|
|
|
|
|
|
|
|
|
2025-11-12 11:13:39 -03:00
|
|
|
try {
|
|
|
|
|
const cepRestUrl = 'https://api.cep.rest/';
|
|
|
|
|
const address = await axios.post(cepRestUrl, { cep });
|
2025-11-14 08:16:04 -03:00
|
|
|
|
2025-11-12 11:13:39 -03:00
|
|
|
if (address.data && address.data.code === 404) {
|
2025-11-24 16:13:35 -03:00
|
|
|
logger.warn('CEP não encontrado na API externa', { cep, response: address.data });
|
2025-11-14 08:16:04 -03:00
|
|
|
return null; // Controller tratará como 'Endereço não encontrado'
|
2025-11-12 11:13:39 -03:00
|
|
|
} else if (address.data && address.data.code) {
|
2025-11-24 16:13:35 -03:00
|
|
|
logger.error('API de CEP retornou um código de erro', { cep, response: address.data });
|
2025-11-14 08:16:04 -03:00
|
|
|
throw new Error("Erro ao consultar o CEP na API externa");
|
2025-11-12 11:13:39 -03:00
|
|
|
} else {
|
2025-12-02 17:29:20 -03:00
|
|
|
// Estrutura 1: { "cep:09662000": { bairro, ... } }
|
|
|
|
|
const cepKey = `cep:${cep}`;
|
|
|
|
|
if (address.data.data && address.data.data[cepKey]) {
|
|
|
|
|
logger.info('CEP encontrado com chave aninhada', { cepKey });
|
|
|
|
|
return address.data.data[cepKey];
|
|
|
|
|
}
|
|
|
|
|
// Estrutura 2: { bairro, cep, ... } (direto em data)
|
|
|
|
|
else if (address.data.data && address.data.data.cep) {
|
|
|
|
|
return address.data.data;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
logger.warn('Estrutura de resposta não reconhecida', { response: address.data });
|
|
|
|
|
return address.data.data || address.data;
|
|
|
|
|
}
|
2025-11-12 11:13:39 -03:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2025-11-24 16:13:35 -03:00
|
|
|
logger.error("Erro na chamada da API de CEP", { message: error.message, stack: error.stack, cep });
|
2025-11-14 08:16:04 -03:00
|
|
|
throw new Error("Erro ao consultar o CEP");
|
2025-11-12 11:13:39 -03:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-24 10:59:46 -03:00
|
|
|
module.exports = { getConsultaCep };
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
DESCRIÇÃO:
|
|
|
|
|
Este arquivo define um serviço para consultar endereços a partir de um CEP.
|
|
|
|
|
|
|
|
|
|
FLUXO:
|
|
|
|
|
1. É chamado principalmente pelo `contratacao.service.js`.
|
|
|
|
|
2. Recebe um CEP e um número.
|
|
|
|
|
3. Formata e valida o CEP.
|
|
|
|
|
4. Realiza uma requisição POST para a API externa `https://api.cep.rest/`.
|
|
|
|
|
5. Trata a resposta da API:
|
|
|
|
|
- Se o CEP não for encontrado (código 404), retorna `null`.
|
|
|
|
|
- Se houver outro erro na API, lança uma exceção.
|
2025-12-02 17:29:20 -03:00
|
|
|
- Se for bem-sucedido, verifica qual estrutura a API retornou:
|
|
|
|
|
* Estrutura aninhada: `{ data: { "cep:09662000": { ... } } }` → extrai a chave dinâmica
|
|
|
|
|
* Estrutura direta: `{ data: { bairro, cep, ... } }` → retorna data direto
|
2025-11-24 10:59:46 -03:00
|
|
|
6. Em caso de erro na comunicação, loga o erro e lança uma exceção genérica.
|
|
|
|
|
|
|
|
|
|
Este serviço abstrai a complexidade da comunicação com a API de CEP, fornecendo uma interface simples para outras partes da aplicação obterem dados de endereço.
|
|
|
|
|
*/
|