O que construí

Date Checklist, um SaaS pra casais montarem a lista de dates juntos: checklist em tempo real, sortear o próximo date, e uma linha do tempo com as fotos dos que já rolaram. A feature de fotos é paga: R$ 9,90 vitalício por sala. Multi-tenant de verdade: cada casal tem uma sala isolada, com pagamento processado pelo Mercado Pago.

O nicho é o de menos. O ponto deste post é que isso é um produto pago, completo e no ar, não um protótipo. E a parte difícil de um SaaS não é a tela bonita: é cobrar de um estranho na internet sem furar segurança nem lei.

As decisões que couberam nos dois dias

Velocidade não veio de digitar rápido. Veio de cortar o caminho certo nas decisões de arquitetura, e de recusar as que dariam retrabalho depois.

Padrão: cada "atalho" foi na verdade uma decisão pra não pagar dívida técnica depois. Rápido e descartável são coisas diferentes.

O que quebrou e o que cada bug ensinou

Lançar de verdade é onde os detalhes aparecem. Quatro que custaram tempo e viraram regra reutilizável:

"Uma das partes é de teste"

O pagamento recusava mesmo com a credencial de produção (APP_USR-). O detalhe: o token existe, mas as credenciais de produção do Mercado Pago só passam a valer depois de ativadas (preencher ramo + site). Antes disso, ele opera como teste.

A sessão sumia ao voltar do pagamento

Pagava, voltava pro site e estava deslogado. Causa: localStorage é por origem, e o retorno do gateway apontava pra um domínio diferente do que o usuário tinha acessado. Regra: as URLs de retorno (e o redirect do login) têm que voltar pro mesmo host de onde veio a pessoa.

O convite caía na sala errada

Dois bugs juntos: o modelo N:N permitia múltiplas salas e o app pegava a "mais antiga"; e uma corrida de tempo no carregamento fazia a tela de onboarding montar e consumir o convite antes da sala real carregar. Solução: uma sala por pessoa (limpa vínculos antigos ao entrar) + segurar o "carregando" até o fetch real terminar.

Texto fantasma no iOS

Um botão trocava de texto e o WebKit não repintava: ficava o texto antigo "queimado" por baixo do novo. Só no iOS. Fix: forçar o React a recriar o elemento com uma key por estado, em vez de reaproveitar o nó.

Conformidade não foi opcional

Cobrar de estranho na internet sobe o modelo de ameaça, e é aqui que a maioria dos "fiz em um fim de semana" para. Eu não pulei:

O que dá pra levar disso

  1. A velocidade está nas decisões, não na digitação. As horas que eu não gastei foram as que recusei: migração, host errado, e-mail caro, RLS recursiva.
  2. Cortar caminho ≠ pular o que importa. Segurança, pagamento e legal foram feitos direito. É justamente o que separa um SaaS de um protótipo.
  3. Bug em produção é dado. Cada um dos quatro virou uma regra que eu carrego pro próximo projeto.
  4. "Completo" inclui a parte chata. Legal, conformidade e exclusão de conta não são polimento, são o produto sendo vendável.

Dois dias, do zero ao cobrando. O produto está no ar em datechecklist.com.br. Se você precisa de um MVP ou SaaS feito assim, rápido mas sem pular a parte que importa, é o tipo de coisa que eu faço.