O problema

Muita operação depende de decisões em cima de dados que mudam a cada minuto — estoque, sensores, preços, filas — mas boa parte dos dashboards ainda são "snapshots" que só atualizam quando alguém aperta F5. Construir ingestão contínua, detecção de padrões e um canal ao vivo até o usuário é um problema de arquitetura, não só de front-end.

Este projeto é um protótipo funcional rodando em produção (não uma maquete): ele consome uma API pública de clima em tempo real, roda cada leitura por um detector de anomalias e uma busca de padrões similares, e transmite tudo via WebSocket assim que acontece.

// ARCHITECTURE

Arquitetura

Um loop de coleta busca dados reais a cada 60 segundos, cada leitura passa por dois detectores independentes de IA, e o resultado combinado é transmitido para todos os clientes conectados — sem polling do lado do navegador.

Open-Meteo API Poll loop (60s) pipeline de IA Detector de anomalias (z-score) Busca vetorial de padrões WebSocket broadcast Dashboard (ao vivo)

Ingestão contínua

Loop assíncrono coleta dados reais de múltiplas cidades a cada 60s, via um cliente isolado e substituível (mesmo padrão de adapter plugável do projeto de extração de documentos).

Detecção de anomalias

Z-score sobre uma janela móvel, por cidade e por métrica — totalmente explicável, sem caixa-preta.

Busca de padrões similares

Cada leitura vira um vetor numérico; uma busca por similaridade encontra o registro histórico mais parecido, de qualquer cidade.

Streaming via WebSocket

O dashboard não faz polling: o servidor empurra cada atualização assim que ela é processada.

// EM PRODUÇÃO

Rodando de verdade, não é mock

Hospedado no Railway, consumindo a API pública Open-Meteo sem chave, sem dados sintéticos:

6 cidades monitoradas em paralelo
60s intervalo de coleta em tempo real
5 métricas por leitura (temp, umidade, vento, pressão, nuvens)
0 chaves de API pagas necessárias

Duas decisões de engenharia que valeram a pena documentar:

A primeira versão usava ChromaDB para a busca de padrões. Em produção, o container era derrubado e reiniciado a cada ~60-70s — consistente com falta de memória — o que derrubava toda conexão WebSocket aberta. Para o volume de dados real do app (poucos vetores de 5 números por cidade), um banco vetorial completo era peso desnecessário: troquei por uma busca por força bruta em memória, mesma interface, sem a dependência pesada. Resolveu o problema.

A segunda foi mais boba: um erro de maiúscula na URL do CDN do Chart.js quebrava o carregamento do gráfico — e como o script inteiro rodava em um único bloco, esse erro impedia até o WebSocket de conectar. Corrigido, e agora a falha de qualquer biblioteca de gráfico é isolada: o dashboard continua funcionando (cards + insights) mesmo que o gráfico não carregue.

Tecnologias

PythonFastAPIWebSocketsDocker RailwayChart.jsOpen-Meteo API

Precisa de um pipeline de dados em tempo real de verdade?