Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature de novo Endpoint para verificação de área de risco dos Correios por CEP #557

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

SenaJesus
Copy link

Descrição da Nova Feature "Verificar Área de Risco dos Correios por CEP"

Implementamos uma nova funcionalidade no BrasilAPI que permite verificar se um CEP está localizado em uma área de risco, conforme classificado pelos Correios do Brasil. Esta feature é essencial para informar consumidores e empresas sobre restrições de entrega em determinados CEPs, reduzindo a incidência de surpresas desagradáveis e contribuindo para um planejamento mais eficaz de envios e recebimentos de encomendas.

Motivação

A motivação para o desenvolvimento desta funcionalidade surgiu da necessidade de mitigar os impactos da segregação social exacerbada pela falta de informação sobre áreas com restrição de entrega. Consumidores, especialmente em regiões periféricas, frequentemente enfrentam desafios ao receber encomendas devido a essas restrições, um problema pouco divulgado pelas empresas de distribuição. A transparência na verificação de CEPs em áreas de risco é também uma exigência do Código de Defesa do Consumidor brasileiro, reforçando a relevância desta funcionalidade.

Detalhes Técnicos

  • Análise de Arquitetura: A funcionalidade foi integrada respeitando a arquitetura existente dos endpoints do BrasilAPI, mantendo a coesão e a qualidade do código-fonte.
  • Engenharia Reversa e Parsing de Dados: Realizamos engenharia reversa nas requisições HTTP do site dos Correios, extraindo informações de HTML com técnicas de parsing usando JSDOM.
  • Tratamento de Erros e Exceções: Implementamos um sistema robusto para o manejo de erros, utilizando expressões regulares e constantes para mensagens de erro.
  • Requisições HTTP com Axios: Asseguramos requisições HTTP eficientes e corretas para a coleta dos dados necessários.
  • Otimizações de Código: Fizemos uma análise de complexidade do código, buscando otimizações por meio de modularização e reutilização de funções eficientes do JavaScript.
  • Documentação: A documentação segue as diretrizes do OpenAPI 3.0, detalhando esquemas de requisição, status de resposta, e parâmetros.
  • Testes Unitários: Foram realizados testes unitários abrangentes para garantir a confiabilidade e integridade da funcionalidade.

Benefícios para Empresas e Consumidores

Empresas de e-commerce, serviços de entrega, e consumidores se beneficiam diretamente desta funcionalidade. E-commerce, como a Magazine Luiza, poderá informar seus clientes antecipadamente sobre possíveis restrições de entrega em seus CEPs, aumentando a transparência e a satisfação do cliente. Serviços de entrega poderão planejar rotas mais eficientes, considerando as restrições existentes. Consumidores, por sua vez, estarão mais informados e poderão se planejar melhor para o recebimento de seus produtos.

Solicitação de Integração

Solicitamos a revisão desta implementação pela comunidade e a subsequente integração ao projeto principal do BrasilAPI, acreditando que esta funcionalidade agregará grande valor ao projeto e à sociedade brasileira.

Copy link

vercel bot commented Nov 30, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
brasilapi ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 1, 2023 3:55pm

Copy link

sonarcloud bot commented Dec 1, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

Copy link
Member

@LorhanSohaky LorhanSohaky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muito obrigado pela contribuição! Deixei alguns pedidos de melhoras

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

É uma prática deste repositório deixar as versões pinadas

"dayjs": "1.11.7",
"dom-parser": "^1.1.5",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pelo que vi essa dependência não é utilizada. Se for o caso, poderia remover?

// Padrões de alertas dos Correios definidos por expressões regulares.
const padroesAlertasCorreios = [
{
regex: /alert\(\'CEP de origem n.*o encontrado na base de dados dos Correios \(-1\).\'\)/,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se com a expressão regular de baixo der certo, acho interessante adotar a estratégia não gulosa

Suggested change
regex: /alert\(\'CEP de origem n.*o encontrado na base de dados dos Correios \(-1\).\'\)/,
regex: /alert\(\'CEP de origem n.*?o encontrado na base de dados dos Correios \(-1\).\'\)/,

https://pt.stackoverflow.com/a/94104

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Por qual motivo estamos lidando com matchers na acentuação? A ideia é garantir que mesmo sem saber o encoding a gnt lidar corretamente?

Comment on lines +38 to +48
regex: /alert\(\'CEP de destino n.*o encontrado na base de dados dos Correios \(-2\).\'\)/,
mensagem: ERROR_MESSAGES['CEP_DESTINO_NOT_FOUND']
},
{
regex: /alert\(\'CEP de destino inv.*lido.\'\)/,
mensagem: ERROR_MESSAGES['CEP_DESTINO_INVALIDO']
},
{
regex: /alert\(\'CEP inv.*lido.\'\)/,
mensagem: ERROR_MESSAGES['CEP_ORIGEM_INVALIDO']
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
regex: /alert\(\'CEP de destino n.*o encontrado na base de dados dos Correios \(-2\).\'\)/,
mensagem: ERROR_MESSAGES['CEP_DESTINO_NOT_FOUND']
},
{
regex: /alert\(\'CEP de destino inv.*lido.\'\)/,
mensagem: ERROR_MESSAGES['CEP_DESTINO_INVALIDO']
},
{
regex: /alert\(\'CEP inv.*lido.\'\)/,
mensagem: ERROR_MESSAGES['CEP_ORIGEM_INVALIDO']
}
regex: /alert\(\'CEP de destino n.*?o encontrado na base de dados dos Correios \(-2\).\'\)/,
mensagem: ERROR_MESSAGES['CEP_DESTINO_NOT_FOUND']
},
{
regex: /alert\(\'CEP de destino inv.*?lido.\'\)/,
mensagem: ERROR_MESSAGES['CEP_DESTINO_INVALIDO']
},
{
regex: /alert\(\'CEP inv.*?lido.\'\)/,
mensagem: ERROR_MESSAGES['CEP_ORIGEM_INVALIDO']
}

// Função para validar a presença dos CEPs de origem e destino.
function validarCEP(cepOrigem, cepDestino) {
if (!cepOrigem || !cepDestino) {
throw new NotFoundError({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creio que aqui faça mais sentido um bad request

Suggested change
throw new NotFoundError({
throw new BadRequestError({

},
"example": {
"response": "CEP em zona restrita",
"isDeliverable": false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"isDeliverable": false
"is_deliverable": false

"schemas": {
"cepInfo": {
"title": "Informação do CEP",
"required": ["response", "isDeliverable"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"required": ["response", "isDeliverable"],
"required": ["response", "is_deliverable"],

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sugeriria de deixar aqui o mais simples possível e deixar a maioria das funções e constantes dentro do service

Copy link
Member

@lucianopf lucianopf Dec 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Será que vale criar uma rota mãe chamada /correios e colocar dentro dela /correios/cep e /correios/restricao?

Obviamente ainda mantendo um symlink do cep atual pra não deixar de funionar 🤔

// Função principal que verifica restrições de entrega para um CEP.
const verifyRestriction = async (request, response) => {
try {
const {cepOrigem, cepDestino, servico} = request.query;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho interessante adotar o padrão snake_case para as variáveis que vêm do cliente e vão para o cliente

Suggested change
const {cepOrigem, cepDestino, servico} = request.query;
const {cep_origem: cepOrigem, cep_destino: cepDestino, servico} = request.query;

Comment on lines +112 to +117
response.status(200).json('{"response": "CEP em zona restrita", "isDeliverable": false}');
return;
}

if (positiveDiv) {
response.status(200).json('{"response": "CEP sem restricao de entrega", "isDeliverable": true}');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
response.status(200).json('{"response": "CEP em zona restrita", "isDeliverable": false}');
return;
}
if (positiveDiv) {
response.status(200).json('{"response": "CEP sem restricao de entrega", "isDeliverable": true}');
response.status(200).json({message: "CEP em zona restrita", is_deliverable: false});
return;
}
if (positiveDiv) {
response.status(200).json({message:"CEP sem restricao de entrega", is_deliverable": true});

Comment on lines +52 to +55
function verificarAlertasCorreios(correiosData) {
const padrao = padroesAlertasCorreios.find(p => p.regex.test(correiosData));
return padrao ? { alerta: true, mensagem: padrao.mensagem } : { alerta: false, mensagem: '' };
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dado que o esperado é que na maioria das vezes não hajam alertas será que não é melhor primeiro validar se existe um alerta e caso exista a gnt iterar sobre os possíveis alertas pra mapear corretamente o erro? (pensando especialmente que fazer validações com Regex pode ser bem exaustivo)

}

// Função para validar a presença dos CEPs de origem e destino.
function validarCEP(cepOrigem, cepDestino) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seria interessante manter o nome das funções em inglês como o restante da codebase 🙏

const {cepOrigem, cepDestino, servico} = request.query;

// Verifica se o serviço solicitado é válido.
if (!(servico in SERVICOS)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pq fazer dessa forma e não da seguinte forma?

Suggested change
if (!(servico in SERVICOS)) {
if (!SERVICOS[servico]) {

}

// Valida os CEPs fornecidos na requisição.
validarCEP(cepOrigem, cepDestino);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Será que aqui um nome melhor pra função não seria validateParams e nessa função validar os 3 parametros? 👀

];

// Função para verificar se existe algum alerta na resposta dos Correios.
function verificarAlertasCorreios(correiosData) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Será que não seria mais interessante essa função se chamar getAlerts e caso não hajam alertas o retorno é null?

Comment on lines +96 to +105
const verificarAlerta = verificarAlertasCorreios(correiosData);

// Se um alerta for encontrado, lança um erro.
if (verificarAlerta['alerta']) {
throw new NotFoundError({
message: verificarAlerta['mensagem'],
type: 'cep_error',
name: 'CEP_NOT_FOUND',
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partindo do comentário https://github.com/BrasilAPI/BrasilAPI/pull/557/files#r1412902104

A gnt poderia reescrever esse trecho pra algo tipo

Suggested change
const verificarAlerta = verificarAlertasCorreios(correiosData);
// Se um alerta for encontrado, lança um erro.
if (verificarAlerta['alerta']) {
throw new NotFoundError({
message: verificarAlerta['mensagem'],
type: 'cep_error',
name: 'CEP_NOT_FOUND',
});
}
const foundAlert = getAlert(correiosData);
if (foundAlert) {
throw new NotFoundError({
message: foundAlert,
type: 'cep_error',
name: 'CEP_NOT_FOUND',
});
}

}

// Processa o HTML para determinar restrições de entrega.
const { errorDiv, positiveDiv } = parseCorreiosHtml(correiosData);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Na prática mesmo o que a gnt ta querendo aqui é baseado no html definir se a entrega é possível ou não, correto?

Será que não seria melhor essa função na vdd retornar um boolean e baseado nisso a gnt define a resposta?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants