Pular para conteúdo
Logo
Overview
Versus: plataforma de torneios 1v1 com Nuxt 4 e SQLite

Versus: plataforma de torneios 1v1 com Nuxt 4 e SQLite

September 14, 2026
3 min read

A disputa 1v1 em chave eliminatória (bracket) é um dos formatos mais diretos e divertidos de engajamento na web: colocar duas opções frente a frente, pedir um clique e avançar a vencedora para a fase seguinte até sobrar apenas uma campeã.

O Versus nasceu para transformar esse chaveamento em uma plataforma leve, visual e sem atrito. A experiência do usuário começa no primeiro clique, sem formulários de cadastro ou barreiras de entrada.

Múltiplos temas no ar com a mesma base

Em vez de criar projetos isolados para cada ideia de votação, organizei o Versus como um monorepo orquestrado com Turborepo e pnpm workspaces. O motor de jogo, a árvore de confrontos e o esquema de banco de dados são compartilhados entre todas as instâncias. Cada aplicação independente define apenas seu catálogo de concorrentes e sua identidade visual.

Hoje a plataforma mantém frentes temáticas como:

  • brversus.com: duelo gastronômico que coloca 32 pratos da culinária brasileira contra 32 receitas consagradas do resto do mundo (também acessível pelo espelho brversus.com.br).
  • richarlison.com.br: chaveamento de futebol confrontando 32 ídolos do futebol nacional contra 32 craques do futebol internacional.

Dinâmica do torneio e privacidade por design

Uma chave com 64 participantes é resolvida em seis rodadas consecutivas: 32 duelos no round inicial, 16 no segundo, 8 nas oitavas, 4 nas quartas, semifinal e a grande final.

Para que essa jornada funcione no navegador de forma fluida e respeitosa, adotei duas premissas centrais:

  1. Votação anônima com sessão em cookie: o progresso do usuário dentro do chaveamento fica registrado por meio de um cookie de sessão assinado. Isso permite pausar a votação e retomar a qualquer momento, além de evitar votos duplicados na mesma rodada sem obrigar a pessoa a preencher e-mail ou senha.
  2. Conformidade nativa com a LGPD: o produto não solicita nem armazena nomes, endereços IP para rastreamento de perfil ou identificadores comportamentais invasivos. O modelo aplica o princípio da minimização de dados na prática: guardamos apenas o estado da chave e o placar agregado dos confrontos.

Arquitetura e stack

A separação de responsabilidades no monorepo garante que correções no cálculo da chave ou melhorias de interface beneficiem todos os temas instantaneamente:

  • packages/core: reúne os serviços de jogo, algoritmos de embaralhamento dos pares, schemas do Drizzle ORM e composables de estado (useGameState, useDashboard).
  • packages/ui: componentes Vue compartilhados para a árvore de chaveamento, cards de batalha 1v1, placares e animações de vitória.
  • apps/*: cada aplicação Nuxt 4 consome os pacotes compartilhados e injeta seu seed.ts de candidatos, suas cores e seus componentes de logo.

Na escolha das tecnologias, busquei o equilíbrio entre velocidade de renderização e simplicidade de manutenção:

  • Nuxt 4 e Tailwind CSS 4: SSR rápido com @nuxt/ui v4, garantindo uma interface responsiva pensada prioritariamente para uso no celular.
  • Drizzle ORM e SQLite (better-sqlite3): persistência relacional direta em arquivo local. Para o volume e a natureza das votações anônimas, o SQLite oferece latência de milissegundos sem a complexidade operacional de manter um cluster externo de banco.
  • motion-v: animações leves para transições entre rodadas e celebração do item campeão.
  • nuxt-security: cabeçalhos HTTP endurecidos (CSP, CORS, nonces) para proteção das rotas públicas.
  • Vitest: suíte de testes automatizados cobrindo a integridade dos avanços de chave e integridade dos votos.

Operação no homelab

As aplicações rodam em containers Docker orquestrados pelo Coolify nos servidores do meu homelab (PLATON e OCI).

A escolha do SQLite simplifica a rotina de resiliência: cada aplicação mantém seu arquivo isolado (brversus-comidas.db e richarlison.db). Uma rotina automatizada via cron executa backups diários com rclone, enviando cópias criptografadas para um bucket Cloudflare R2. O tráfego de entrada passa pela Cloudflare com cache em borda para assets estáticos e políticas de SSL estrito.

A plataforma mostra na prática como um mesmo motor de software pode dar vida a diferentes formatos de entretenimento rápido sem gerar dívida técnica desnecessária.

Leitura Relacionada