104 lines
3.5 KiB
JavaScript
104 lines
3.5 KiB
JavaScript
const dotenv = require("dotenv");
|
|
|
|
dotenv.config();
|
|
|
|
const express = require("express");
|
|
const path = require("path");
|
|
const cors = require("cors");
|
|
const { fetchJson } = require("./services/jsonService");
|
|
const { getMinDistance } = require("./services/distanceService");
|
|
const { geocodeWithGoogle } = require("./services/geocodeService");
|
|
const { insertConsultaData } = require("./models/databaseModel");
|
|
|
|
function createApp() {
|
|
const app = express();
|
|
|
|
app.use(cors());
|
|
app.use(express.static(path.join(__dirname, "public")));
|
|
app.use(express.json());
|
|
|
|
// manual CEP+Numero query: resolves ViaCEP -> Nominatim -> Geogrid
|
|
app.get("/consulta-cep", async (req, res) => {
|
|
const { cep: rawCep, numero: rawNumero } = req.query;
|
|
if (!rawCep) return res.status(400).json({ error: "cep é obrigatório" });
|
|
const cep = String(rawCep).replace(/\D/g, "");
|
|
const numero = rawNumero ? String(rawNumero).trim() : "";
|
|
|
|
try {
|
|
const viaCepData = await fetchJson(
|
|
`https://viacep.com.br/ws/${cep}/json/`
|
|
);
|
|
if (!viaCepData || viaCepData.erro)
|
|
return res.status(404).json({ error: "CEP não encontrado" });
|
|
const logradouro = viaCepData.logradouro || "";
|
|
const bairro = viaCepData.bairro || "";
|
|
const cidade = viaCepData.localidade || "";
|
|
const uf = viaCepData.uf || "";
|
|
const endereco = `${logradouro}, ${numero}, ${bairro}, ${cidade} - ${uf}`
|
|
.replace(/, ,/g, ",")
|
|
.replace(/^,\s*/, "");
|
|
|
|
if (!process.env.GOOGLE_API_KEY)
|
|
return res
|
|
.status(500)
|
|
.json({ error: "GOOGLE_API_KEY não definida no servidor" });
|
|
const geo = await geocodeWithGoogle(endereco || `${cidade} ${uf} ${cep}`);
|
|
if (!geo)
|
|
return res
|
|
.status(404)
|
|
.json({ error: "geocode não encontrado (Google)" });
|
|
const lat = Number(geo.lat);
|
|
const lon = Number(geo.lon);
|
|
const result = await getMinDistance(lat, lon);
|
|
|
|
// determinar valores de retorno padrão
|
|
let distancia = null;
|
|
let dedicado = "Não viável";
|
|
let naoDedicado = "Não viável";
|
|
|
|
if (result && result.dist !== undefined && result.dist !== null) {
|
|
distancia = result.dist;
|
|
// preciso criar 2 campos: Link Dedicado e Link Não Dedicado em que o dedicado é viável até 1000m e o não dedicado até 500m
|
|
if (distancia <= 500) {
|
|
dedicado = "Viável";
|
|
naoDedicado = "Viável";
|
|
} else if (distancia <= 1000) {
|
|
dedicado = "Viável";
|
|
naoDedicado = "Não viável";
|
|
} else {
|
|
dedicado = "Não viável";
|
|
naoDedicado = "Não viável";
|
|
}
|
|
} else {
|
|
dedicado = "Não viável";
|
|
naoDedicado = "Não viável";
|
|
}
|
|
|
|
const response = {
|
|
endereco,
|
|
latitude: lat,
|
|
longitude: lon,
|
|
distancia,
|
|
dedicado,
|
|
naoDedicado,
|
|
};
|
|
|
|
// Inserção no banco: usar fire-and-forget para não atrasar a resposta ao usuário.
|
|
// Se preferir garantir que a gravação ocorreu antes de responder, troque a chamada abaixo por:
|
|
// await insertConsultaData(cep, uf, cidade, bairro, logradouro);
|
|
insertConsultaData(cep, uf, cidade, bairro, logradouro, dedicado, naoDedicado)
|
|
.then(() => console.info(`[INFO] Consulta salva para CEP ${cep}`))
|
|
.catch((err) => console.error(`[ERROR] Falha ao salvar consulta para CEP ${cep}:`, err));
|
|
|
|
return res.json(response);
|
|
} catch (err) {
|
|
console.error(err);
|
|
return res.status(500).json({ error: "erro na consulta" });
|
|
}
|
|
});
|
|
|
|
return app;
|
|
}
|
|
|
|
module.exports = createApp;
|