NN.← Voltar ao portfólio

Estudo de caso · P02

Sessão

Porque memórias se perdem.

Casais que assistem muitos filmes e séries juntos não têm como registrar essa jornada de forma organizada — e emocional. Os apps existentes são para listas individuais. Sessão é para dois.

Status

Em desenvolvimento

Stack

ReactViteFirebaseFirestorePWA
01

O Problema

Minha namorada e eu assistimos muitos filmes juntos. Com o tempo, começamos a perder o controle: o que já assistimos? O que queríamos assistir? Qual era a nota dela para aquele filme que eu achei incrível?

Tentamos alternativas. O Letterboxd é individual — não tem watchlist compartilhada para dois usuários. Planilhas são funcionais mas emocionalmente mortas. Listas no Notes não têm busca, avaliações, histórico.

O insight

O problema não é tecnológico — é emocional. Casais que assistem juntos estão construindo uma memória compartilhada. O produto precisa respeitar isso: não apenas registrar, mas preservar a perspectiva de cada um.

02

Arquitetura e Decisões

O maior desafio de design: como estruturar dados compartilhados entre dois usuários distintos, sem violar a privacidade de cada um, sem conflitos de escrita, com sincronização em tempo real.

Espaço compartilhado no Firestore

Criei o conceito de 'casal' como entidade própria no banco. Cada casal tem um ID único. Os dois usuários referenciam esse ID — os dados vivem no espaço do casal, não de nenhum deles individualmente.

Permissões por casal

As regras de segurança do Firestore verificam se o usuário autenticado pertence ao casal que está tentando acessar. Nenhum usuário acessa dados de outro casal — mesmo que saiba o ID.

Avaliações independentes

Cada usuário tem sua própria subcoleção de avaliações dentro do espaço compartilhado. Os dois podem ver as notas um do outro, mas só podem editar as próprias.

TMDB como fonte de verdade

Metadados de filmes (poster, sinopse, elenco, gênero) não são armazenados — são buscados via API no momento do uso. Evita dados desatualizados e reduz tamanho do banco.

03

Desafio Técnico Principal

Sincronização sem colisão

Quando dois usuários estão usando o app ao mesmo tempo e um deles adiciona um filme à watchlist, o outro precisa ver essa atualização imediatamente — sem recarregar a página, sem conflitos.

O risco: se os dois adicionam um filme ao mesmo tempo, a última escrita sobrescreve a anterior — e um registro se perde.

Solução implementada

Operações de escrita na watchlist usam transações do Firestore em vez de escritas diretas. A transação lê o estado atual, verifica se o filme já existe e só então adiciona — tudo em uma operação atômica. Colisões são impossíveis.

await runTransaction(db, async (transaction) => {
  const watchlistRef = doc(db, 'casais', casalId, 'watchlist', movieId);
  const snap = await transaction.get(watchlistRef);

  if (snap.exists()) return; // já existe, ignora

  transaction.set(watchlistRef, {
    addedBy: currentUser.uid,
    addedAt: serverTimestamp(),
    ...movieData,
  });
});
04

O que foi construído

Busca via TMDB

Busca em tempo real na base do The Movie Database. Poster, sinopse e metadados automaticamente preenchidos.

Watchlist compartilhada

Os dois adicionam filmes à mesma lista. Sincronização em tempo real — sem precisar atualizar a página.

Registro de sessões

Assistiram juntos? Um clique registra a sessão com data e hora.

Avaliações individuais

Cada um dá a sua nota. Notas diferentes, perspectivas diferentes. O sistema preserva ambas.

Séries em andamento

Controle de qual temporada e episódio estão assistindo. Não mais 'qual era o episódio mesmo?'

Estatísticas do casal

Quantos filmes assistiram juntos. Gêneros favoritos. Avaliação média. Uma história em dados.

05

O que aprendi

Dados compartilhados exigem modelo de propriedade explícito

Quem é dono do quê? No Sessão, o casal é dono da watchlist. Cada usuário é dono das próprias avaliações. Essa distinção tem que estar na estrutura de dados — não só na UI.

Transações são a única forma confiável de evitar colisões

Verificar antes de escrever sem transações é uma race condition esperando para acontecer. Se dois requests chegam ao mesmo tempo, a verificação passa nos dois — e ambos escrevem.

Produto para dois usuários tem UX diferente de produto individual

Cada ação tem um autor. 'Você adicionou' vs 'Ela adicionou' muda completamente a percepção. Atribuição de ações é um requisito de produto, não um detalhe de implementação.

Produto ao vivo

Sessão está rodando.
Pode explorar agora.