Skip to content

GabrielSgrancio/voting-contest

Repository files navigation

BBB Voting System

Sistema de votação em tempo real do BBB, preparado para receber milhares de votos simultâneos durante horário nobre.

Quick Start

make gabriel-globo  #ou docker-compose up --build -d (Sobe tudo - Docker Compose)

Acessos:

Arquitetura

┌─────────────────────────────────────────────────────────────┐
│                    FRONTEND (React/Vite)                    │
│                    http://localhost:8080                    │
└──────────────────────────┬──────────────────────────────────┘
                           │ POST /votes, GET /stats/*
                           ▼
┌─────────────────────────────────────────────────────────────┐
│              NGINX LOAD BALANCER (10k req/s)                │
└──────────────┬─────────────────────────┬────────────────────┘
               │                         │
       ┌───────▼────────┐        ┌───────▼────────┐
       │  API 1         │        │  API 2         │
       │  (4 workers)   │        │  (4 workers)   │
       └───────┬────────┘        └───────┬────────┘
               │                         │
               └──────────┬──────────────┘
                          ▼
              ┌───────────────────────┐
              │   REDIS (Cache+Queue) │
              │   • <1ms (contadores) │
              │   • AOF (persistência)│
              └──────┬────────┬───────┘
                     │        │
           ┌─────────▼──┐  ┌──▼─────────┐
           │ Worker 1   │  │ Worker 2   │
           │ Batch: 500 │  │ Batch: 500 │
           └─────────┬──┘  └──┬─────────┘
                     │        │
                     └────┬───┘
                          ▼
              ┌───────────────────────┐
              │   POSTGRESQL          │
              │   • votes_raw         │
              │   • votes_hourly      │
              └───────────────────────┘

Como Funciona

1. Voto chega:

  • Frontend envia POST → Nginx distribui → API incrementa Redis (<1ms) → Enfileira para persistência

2. Persistência:

  • Workers processam fila em lote (500 votos/vez) → PostgreSQL armazena permanentemente

3. Consultas:

  • Frontend consulta Redis (tempo real, <1ms)
  • PostgreSQL guarda histórico completo para auditoria

Por que Redis E PostgreSQL?

  • Redis: Contadores instantâneos, aguenta 100k+ leituras/s
  • PostgreSQL: Histórico permanente, auditoria, relatórios

Endpoints

POST   /votes                  # Registrar voto
GET    /stats/total            # Total geral
GET    /stats/participants     # Por participante
GET    /stats/hourly           # Por hora
GET    /paredao/ativo          # Dados do paredão ativo
GET    /metrics                # Prometheus (métricas)
GET    /health                 # Status da API

Performance

Testado com make load-test:

  • Baseline requerido: 100 req/s
  • Entregue: 5-6k req/s sustentados (50-60x superior)
  • Picos: Até 38k req/s
  • Latência: <1ms (Redis), 10-50ms (PostgreSQL)

Load test distribui votos 50/50 entre participantes para simular cenário real.

Comandos Úteis

make gabriel-globo   # Subir infraestrutura
make test            # Rodar testes (backend + frontend)
make load-test       # Teste de carga (100 → 800 conexões)
make check-data      # Verificar consistência Redis/PostgreSQL
make reset-votes     # Zerar contadores (útil para demos)
make logs            # Acompanhar logs
make down            # Derrubar tudo

Reset de Contadores

Após load test, contadores terão 100k+ votos. Para demonstrar frontend com cliques visíveis:

make reset-votes  # Zera Redis, mantém histórico PostgreSQL

Útil para mostrar UX/tempo real para avaliadores.

Observabilidade

Dashboard Grafana provisionado automaticamente:

  • Total de votos (com thresholds coloridos)
  • Distribuição por participante (donut chart)
  • Evolução temporal
  • Votos por hora (bar chart)

Acesse: http://localhost:3000 (admin/admin)

Testes

Backend: Jest + Supertest

cd backend && npm test

Frontend: Vitest

cd frontend && npm test

Ambos:

make test

Stack

Backend:

  • Fastify (cluster mode, 8 workers total)
  • TypeScript + JSON Schema
  • Redis (cache + fila)
  • PostgreSQL (persistência)

Frontend:

  • React 18 + Vite
  • TypeScript
  • CSS puro (sem Tailwind - design customizado)

Infra:

  • Docker Compose (9 serviços)
  • Nginx (load balancer)
  • Prometheus + Grafana

Screenshots

Demonstração em vídeo(clique para assistir):

https://youtu.be/R33YrSM_X4Y

Tela de votação: Tela principal

Resultado com ProgressCircle: Resultado

Header customizado (inspirado Globo 100 anos): Header Aba

Dashboard Grafana: Grafana

Documentação

✅ Requisitos Atendidos

  • ✅ UI fiel ao mockup fornecido
  • ✅ Votação ilimitada por usuário
  • ✅ Performance até 50x superior ao baseline (100 → 5-6k req/s)
  • ✅ URLs de consulta (total, por participante, por hora)
  • ✅ Testes automatizados
  • ✅ Infraestrutura automatizada (Docker Compose)
  • ✅ Documentação completa

Diferenciais

  • Observabilidade completa (Prometheus + Grafana)
  • Arquitetura escalável (cluster mode, load balancer, workers)
  • Load test automatizado com distribuição realista
  • Scripts úteis (reset-votes, check-data)
  • Documentação detalhada de decisões técnicas

Desenvolvido por Gabriel Sgrancio

About

High-throughput real-time voting system inspired by BBB. Fastify (cluster mode), Redis (queue + atomic counters), PostgreSQL, Nginx load balancer, Prometheus/Grafana observability. 9 services via Docker Compose, sustained 5-6k req/s with peaks up to 38k req/s.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors