SmartITBI — ambientes¶
O SmartITBI é a aplicação de análise de imóveis para ITBI: coleta anúncios de imóveis em várias plataformas, geocodifica, analisa com LLM e devolve um parecer com relatório em PDF. Desde agosto de 2026 ele tem três ambientes padronizados — dev, homolog e prod —, gerenciados por uma instalação própria do Coolify, em br-sao (São Paulo).
Esta página descreve esses ambientes: o que cada um serve, como o código chega neles e o que muda de um para o outro.
Os três ambientes¶
| Ambiente | Aplicação | API | Serve para |
|---|---|---|---|
| Dev | dev.smartitbi.bravonix.ia.br | api.dev.smartitbi.bravonix.ia.br |
Integração contínua do time; base vazia |
| Homologação | homolog.smartitbi.bravonix.ia.br | api.homolog.smartitbi.bravonix.ia.br |
Validação antes de produção; base vazia |
| Produção (nova) | prod.smartitbi.bravonix.ia.br | api.prod.smartitbi.bravonix.ia.br |
Ambiente-alvo, montado em paralelo e ainda sem dados |
O ambiente prod desta página ainda não atende cliente
Ele está no ar, responde normalmente e a base está vazia — existe para validação enquanto a virada não acontece. O endereço que atende cliente hoje é outro, e é informado pela equipe responsável. Não mande cliente para prod.smartitbi.bravonix.ia.br.
Por que os internos usam bravonix.ia.br
Ambientes internos ficam todos na zona bravonix.ia.br, no mesmo padrão dos demais serviços.
O que compõe um ambiente¶
Os três têm o mesmo desenho: cinco aplicações (build por Dockerfile) e dois bancos (recursos do Coolify, sem porta publicada na internet).
flowchart TB
U["Usuário"]
subgraph AMB["Um ambiente (dev / homolog / prod)"]
GW["Gateway<br>Express — encaminha e serve a interface"]
API["API<br>Django + gunicorn"]
WS["worker scraping<br>Celery"]
WD["worker default<br>Celery"]
BT["beat<br>agendador"]
DB[("PostgreSQL")]
R[("Redis<br>fila, cache e resultados")]
end
EXT["Serviços externos<br>coleta de anúncios · geocoding · LLM"]
U --> GW
GW --> API
API --> DB
API --> R
R --> WS
R --> WD
BT --> R
WS --> DB
WD --> DB
WS --> EXT
API --> EXT
| Peça | Papel |
|---|---|
| Gateway | Serve a interface e encaminha /api, /admin, /static e /health para a API — o navegador fala só com ele |
| API (Django + gunicorn) | Regras do produto, autenticação e enfileiramento das análises |
worker scraping |
Faz a análise que o cliente pediu: coleta, geocoding e LLM. Fila dedicada, com toda a concorrência |
worker default |
Webhook, e-mail transacional e manutenção — separado para que um consumidor lento não ocupe capacidade de análise |
beat |
Tarefas periódicas, incluindo a varredura de análises órfãs |
| PostgreSQL | Dados da aplicação e resultado das análises |
| Redis | Fila do Celery (/0), cache (/1) e resultados (/2) |
O frontend é um gateway, não uma SPA que chama a API direto
Diferente do Adapter, aqui o navegador conversa com um endereço só. O endereço api.<ambiente>.smartitbi... existe para acesso direto à API e ao admin, não para o uso normal da interface.
Os três ambientes dividem a mesma máquina
Também diferente do Adapter, onde cada ambiente tem servidor próprio. Aqui a separação é lógica: aplicações, bancos e endereços são independentes, mas o hardware é o mesmo. Consequência prática: uma carga pesada em um ambiente pode ser sentida nos outros.
Branches — uma por ambiente¶
O produto é um repositório só, então a regra é direta:
| Branch | Ambiente |
|---|---|
dev |
Dev |
homolog |
Homologação |
main |
Produção (nova) |
Um merge na branch dispara o deploy das cinco aplicações daquele ambiente.
Como o código chega no ambiente¶
flowchart LR
A["Merge na branch<br>do ambiente"] --> B["Webhook<br>para o Coolify"]
B --> C["Build na máquina<br>dedicada de build"]
C --> D["Imagem publicada<br>no registry privado"]
D --> E["Servidor do ambiente<br>baixa e sobe o container"]
- O build não roda no servidor do ambiente: existe uma máquina só para isso — a mesma que atende o Adapter — e a imagem pronta vai para o registry privado da Bravonix.
- Nome da imagem:
<aplicação>-<ambiente>, com a tag sendo o commit. Cada ambiente tem seu próprio repositório de imagem. - As quatro aplicações Python de um ambiente saem da mesma imagem; o que muda entre API, workers e agendador é o comando de inicialização.
- Deploy bem-sucedido troca o container, e a troca tem alguns segundos de 502. Deploy que falha não derruba nada: o container antigo só sai depois que o novo sobe.
- O banco se resolve no boot: o passo de inicialização roda as migrations e coleta os estáticos antes de a aplicação atender.
Dados — o que cada ambiente contém¶
| Ambiente | Origem dos dados | Contém dado pessoal? |
|---|---|---|
| Dev | Nasceu vazio | Não |
| Homologação | Nasceu vazio | Não |
| Produção (nova) | Vazio até a virada | Não, por enquanto |
Cada ambiente tem segredos próprios
A chave que assina as sessões é diferente em cada ambiente — token emitido em um não vale no outro, e isso é deliberado. Senhas de banco e de Redis também são próprias.
Quando a virada acontecer, o ambiente de produção receberá uma restauração do ambiente atual, e a partir daí passa a conter dado real.
Backup¶
| O que é salvo | Frequência | Onde |
|---|---|---|
| O banco de cada ambiente | Diário, horários escalonados | Bucket de backup por ambiente |
| Configuração do Coolify (variáveis e acessos dos três) | Diário | Bucket próprio |
- Um bucket por ambiente, com credencial restrita a ele — backup de produção não é alcançável por credencial de dev; o isolamento foi testado nos dois sentidos.
- Alerta por e-mail quando um backup falha, quando o arquivo não chega ao destino e também quando o backup deixa de rodar — a falha silenciosa é a que mais engana.
- A restauração foi testada de ponta a ponta em destino descartável, comparando a contagem de tabelas com o original.
O backup mais importante não é o dos ambientes
É o da configuração do Coolify: ele guarda as variáveis e os acessos dos três ambientes de uma vez. A cópia só é útil junto com a chave que decifra essas variáveis — por isso as duas viajam juntas.
Convenção de nomes¶
Servidores seguem sitbi-<papel>-<YYMM>: o papel no meio (controle, ambientes) e a data de criação no fim — nessa ordem porque só assim a listagem alfabética fica em ordem cronológica. É a mesma regra dos servidores do Adapter, sem o número de ambiente, porque aqui os três dividem uma máquina.
O nome do servidor não diz quem está servindo o endereço
Quem responde por um domínio é o DNS, não o nome da máquina.
Troubleshooting¶
| Sintoma | Causa provável | O que fazer |
|---|---|---|
| Endereço devolve 502 e a aplicação parece sadia por dentro | Rota do proxy apontando para a porta antiga — ela é gravada quando a aplicação é criada e não se refaz sozinha | Limpar a configuração de rota da aplicação e refazer o deploy |
| Um worker ou o agendador some logo depois do deploy | Variável obrigatória ausente: a configuração de produção recusa subir sem os segredos, e vale para worker e agendador, não só para a API | Conferir as variáveis daquela aplicação — o container morre antes de deixar log |
| Merge não dispara deploy nenhum | Branch sem ambiente correspondente | Usar dev, homolog ou main |
| Análise fica parada em processamento | Fila de scraping ocupada, ou serviço externo de coleta lento | Acompanhar o status da análise; a varredura de órfãs roda periodicamente |
| Erro 502 por alguns segundos | Troca de container em deploy bem-sucedido | Comportamento esperado; escolher a janela de deploy |
| Interface abre mas a API responde 404 em um caminho | Caminho não encaminhado pelo gateway | Conferir a lista de caminhos encaminhados (/api, /admin, /static, /health) |
Onde estão as credenciais
Acessos ao painel, aos bancos e às contas de serviço ficam com a equipe de desenvolvimento — nunca nesta wiki. Solicite ao responsável pelo ambiente.