ADR-0016 — Geocoding (endereço → coordenadas)
- Status: Aceito
- Data: 2026-07-18 · Aceito em: 2026-07-18
Contexto
O mapa (RF-04), a busca por raio/bbox (PostGIS) e o mini-mapa do detalhe (RF-15) exigem localizacao geography(Point) para cada imóvel. O CSV/detalhe traz endereço/bairro/CEP, não coordenadas. É preciso um GeocodingPort com uma implementação concreta, respeitando os Termos de Uso do serviço e a escala de dezenas de milhares de imóveis.
Decisão
- Primário: Nominatim self-hosted (container/Helm no cluster) sobre dados do OpenStreetMap. Evita o limite de 1 req/s do Nominatim público (cujos ToS proíbem uso em massa) e mantém o dado interno.
- Cache persistente: toda resolução é gravada (coordenadas +
qualidade/confianca+ fonte) e reusada; re-geocoding só quando o endereço muda. Nunca geocodar em request de usuário (é batch, no workerGeocodificarImovelUseCase). - Preferência de entrada:
CEPdo detalhe > endereço completo > bairro/cidade (fallback com menor confiança). - Fallback opcional para provedor pago (ex.: LocationIQ/Google) apenas para endereços que o Nominatim não resolve, com flag de custo e limite mensal.
- Rate limit e backoff no worker; paced junto do enriquecimento (ADR-0010).
Arquitetura, robustez e escala
- Porta + cadeia de fallback:
GeocodingPortcom adapters ordenados (nominatim → provedor_pago → indisponível). Cada adapter tem circuit breaker; falha do primário abre o breaker e passa ao próximo sem derrubar o worker. - Cache persistente (
geocode_cache): chave =hash(endereco_normalizado + cep); guardalat/lng,qualidade(exato|aproximado|centroide_bairro|centroide_cidade),provedor,resolvido_em. Hit evita nova chamada; TTL longo (endereço muda pouco). - Normalização antes de consultar (abreviações, acentos, tipo de logradouro) para maximizar hit e qualidade; preferir CEP quando houver.
- Nominatim self-hosted: container com base OSM do Brasil; réplicas stateless de leitura atrás de um Service; atualização do dump mensal via job agendado (blue/green para não derrubar). Dimensionar disco (dezenas de GB) e memória do índice.
- Escala do batch: geocoding roda no worker
GeocodificarImovelUseCase, paced junto do enriquecimento; nunca no request do usuário. Throughput alvo acompanha o backlog da fila. - Qualidade & mapa: armazenar
qualidade/confianca; a UI sinaliza pontos de baixa precisão (ex.: só centroide de bairro) e evita "falsa exatidão". - Observabilidade:
% imóveis geocodados, distribuição dequalidade, latência p95, taxa de fallback e de erro por provedor, custo do provedor pago (ver pilares).
Consequências
- + Sem custo por chamada nem violação de ToS; escala controlada por nós.
- + Cobertura medida por métrica de negócio (
% imóveis geocodados). - − Operar mais um serviço (Nominatim + base OSM ~dezenas de GB); atualização periódica do dump.
- − Qualidade variável em endereços ruins → armazenar
confiancae sinalizar no mapa.
Alternativas consideradas
- Nominatim público: viola ToS para volume; rate limit inviável — rejeitado como primário.
- Só provedor pago: custo por chamada em escala e dependência externa — fica como fallback.
- Geocoding via PostGIS Tiger: dados de qualidade fraca no Brasil — rejeitado.