Case study

MatchMaker FC

PWA que sorteia times equilibrados para a pelada e cria salas com link para os jogadores confirmarem presença sem instalar nada.

Tela do MatchMaker FC com o elenco atual, a escolha entre Futsal 5×5 e Society 7×7 e o botão para criar sala de bate-bola.
FIG. 01 — Tela inicial do MatchMaker FC

Contexto e problema

O MatchMaker nasceu de uma necessidade real de um familiar que organiza partidas de futebol amador: montar times equilibrados e saber quem vai jogar.

Os jogadores não deveriam precisar instalar um app nem criar conta para confirmar presença.

Solução

  • Sorteio em Snake Draft com Power Rating oculto: cada atleta tem uma nota que não aparece na tela de sorteio, e as escolhas se alternam entre os times para equilibrá-los.
  • Match Rooms: o organizador cria uma sala e compartilha um link; os jogadores fazem check-in pelo navegador.
  • Modos Futsal 5×5 e Society 7×7.
  • Funciona sem login, com os dados no próprio aparelho; a conta Google sincroniza o elenco entre dispositivos e libera a criação de salas.
  • PWA instalável, com service worker.

Decisões técnicas

  1. Check-in com runTransaction no Firestore

    Por quê
    Vários jogadores confirmam presença ao mesmo tempo pelo mesmo link. A transação lê e grava a lista de forma atômica, sem que uma confirmação sobrescreva a outra.
    Trade-off
    Transações são repetidas pelo SDK quando há disputa e não funcionam offline.
  2. Listeners onSnapshot com escopo restrito

    Por quê
    Ouvir só os documentos da sala aberta, em vez de coleções inteiras, mantém as leituras dentro da cota do plano gratuito do Firebase.
    Trade-off
    Cada tela que precisa de tempo real exige pensar o escopo do listener; o que fica fora dele não atualiza sozinho.
  3. Dados locais primeiro, conta Google opcional

    Por quê
    O organizador começa a usar na hora, sem cadastro. O login só é pedido para o que depende de servidor: sincronizar e criar salas.
    Trade-off
    Sem login, o elenco fica preso a um aparelho.

Stack

Front-end
  • React
  • TypeScript
  • Vite
  • Tailwind CSS
  • Zustand
  • React Router
  • React Hook Form
  • dnd-kit
Dados e login
  • Firebase Auth (Google)
  • Firestore
Qualidade
  • Vitest
PWA e entrega
  • vite-plugin-pwa (Workbox)
  • Cloudflare Pages

Estado atual

  • Em produção em matchmakerfc.com.br.
  • Código em repositório privado.

Imagens e diagrama

Check-in: link da sala → transação no Firestore → listas atualizadas em tempo realOrganizadorcria a salacompartilha o linkJogadoresabrem o linkno navegadorrunTransactionlê a listagrava o check-inFirestoredocumentoda salacheck-inatômicoonSnapshot só desta sala → lista ao vivo
FIG. 02 — Check-in: link da sala → transação no Firestore → listas atualizadas em tempo real

O organizador cria uma sala e compartilha o link. Cada jogador abre o link no navegador e confirma presença; a confirmação é gravada com runTransaction no documento da sala. O app do organizador ouve só esse documento com onSnapshot e vê a lista atualizar em tempo real.

MatchMaker FC no celular: aviso para conectar a conta Google, elenco atual, botões Futsal 5×5 e Society 7×7, Criar Sala de Bate-Bola e a barra inferior com Home, Elenco, Check-in, Notas e Sortear.
FIG. 03 — App no celular, sem login: dados ficam no aparelho