Uma solução Full Stack distribuída para monitoramento climático em tempo real, utilizando arquitetura de microsserviços orientada a eventos.
Este projeto foi desenvolvido como solução para um desafio técnico de engenharia de software. O objetivo principal é criar uma arquitetura robusta e poliglota, onde diferentes serviços (cada um em sua linguagem nativa) cooperam através de um message broker para processar dados de alta volumetria.
A aplicação coleta dados meteorológicos, processa em filas de alta performance, armazena em banco orientado a documentos e exibe em um dashboard reativo.
- Coleta (Python): um script agendado busca dados da Open-Meteo API
- Mensageria (RabbitMQ): garante desacoplamento e resiliência dos dados
- Processamento (Go): um worker consume a fila e comunica com a API
- Backend (NestJS): gerencia regras de negócio e persistência no MongoDB
- Frontend (React): interface moderna com Tailwind e shadcn/ui
- Infraestrutura: Docker & Docker Compose
- Coletor: Python 3.10 +
requests+schedule - Fila/Broker: RabbitMQ (Management Plugin)
- Worker: Golang (AMQP Protocol)
- API: NestJS (TypeScript) + Mongoose
- Banco de Dados: MongoDB
- Frontend: React + Vite + TailwindCSS + Recharts
Graças ao Docker, não é necessário instalar Python, Go ou Node.js na sua máquina. Apenas o Docker é obrigatório.
- Docker Desktop instalado e rodando
- Clone o repositório:
git clone https://github.com/SEU-USUARIO/gdash-weather-station.git
cd gdash-weather-station- Suba a aplicação com um único comando:
docker compose up --buildNa primeira execução, aguarde o download das imagens e a compilação dos serviços.
- Acesse as interfaces:
- Dashboard (Frontend):
http://localhost:5173 - API (Backend):
http://localhost:3000/api - RabbitMQ Manager:
http://localhost:15672(User:admin/ Pass:password123)
Use o arquivo .env.example como base para criar seu .env:
MONGO_URL=mongodb://admin:password123@mongo:27017/weatherdb?authSource=admin
RABBITMQ_URL=amqp://admin:password123@rabbitmq:5672
RABBITMQ_QUEUE=weather_data
JWT_SECRET=changeme
DEFAULT_USER_EMAIL=admin@example.com
DEFAULT_USER_PASSWORD=123456
OPEN_METEO_URL=https://api.open-meteo.com/v1/forecast
LOCATION_LAT=-23.5505
LOCATION_LON=-46.6333
COLLECTION_INTERVAL=3600
VITE_API_URL=/api
gdash-weather-station/
├── backend-nest/ # API Principal (Node.js/NestJS)
├── frontend-react/ # Dashboard (React/Vite)
├── weather-collector-python/ # Serviço de Coleta (Python)
├── worker-go/ # Consumidor da Fila (Golang)
└── docker-compose.yml # Orquestração dos Containers
- Resiliência: o Worker em Go possui lógica de retry e ack/nack manual; se a API estiver fora do ar, a mensagem volta para a fila
- Tradução WMO: o Frontend implementa a tabela da Organização Meteorológica Mundial para traduzir códigos numéricos (ex.:
2) para descrições humanas ("Parcialmente Nublado ⛅") - Networking Docker: os serviços se comunicam via rede interna do Docker (
http://backend-nest:3000,amqp://rabbitmq), isolados do host
- Backend (NestJS)
backend-nest/- Porta:
3000 - Principais rotas:
POST /auth/login(gera token JWT)GET /weather(lista dados)POST /weather(insere dado)GET /weather/export(CSV)
- Porta:
- Frontend (React/Vite)
frontend-react/- Porta:
5173 - Páginas: Login (
/login) e Dashboard (/)
- Porta:
- Coletor (Python)
weather-collector-python/- Publica JSON na fila
weather_data
- Publica JSON na fila
- Worker (Go)
worker-go/- Consome a fila e envia
POSTpara a API
- Consome a fila e envia
- Frontend:
docker compose up -d frontend - API:
docker compose up -d backend - Coletor:
docker compose up -d collector - Worker:
docker compose up -d worker
- Frontend:
http://localhost:5173 - API:
http://localhost:3000 - RabbitMQ UI:
http://localhost:15672(admin/password123)
- Email:
admin@example.com - Senha:
123456
Autenticação e listagem via PowerShell:
$body = @{ email = 'admin@example.com'; password = '123456' } | ConvertTo-Json
$login = Invoke-RestMethod -Method Post -Uri http://localhost:3000/auth/login -ContentType 'application/json' -Body $body
$token = $login.access_token
Invoke-RestMethod -Method Get -Uri http://localhost:3000/weather -Headers @{ Authorization = "Bearer $token" }- Se o login não avançar, limpe o token do navegador:
localStorage.removeItem('gdash_token')e recarregue
- Se o worker receber
401, ele reautentica automaticamente e reenvia - Ajuste
COLLECTION_INTERVAL=60no.envpara acelerar dados em desenvolvimento
Desenvolvido por Fernando Henrique Silva
