O contexto
Produto próprio, não projeto de cliente. Um criador que já tem audiência e quer cobrar assinatura hoje tem duas opções ruins: entrar numa plataforma que fica com uma fatia da receita e coloca a marca dela na frente da dele, ou mandar construir do zero um site com login, cobrança recorrente e área de membros.
O PeekingMe é a terceira opção: a estrutura pronta, mas com a marca do criador na frente.
O problema
"White-label multi-tenant" é fácil de falar e caro de errar. São dois requisitos que puxam para lados opostos.
O primeiro é isolamento. Conteúdo, assinantes e dados de cobrança de um criador não podem vazar para outro — e não vazar de verdade, não por descuido de uma query sem filtro. Uma listagem esquecida já é incidente.
O segundo é operabilidade. Se cada criador virar uma instalação separada, cada correção de bug vira N deploys e a manutenção morre no terceiro cliente.
O terceiro é identidade: domínio, nome, cores, tom. Da perspectiva do assinante, aquilo é o site do criador, não uma página de perfil dentro de um produto genérico.
Decisões técnicas
Tenant como dimensão de primeira classe no domínio, não isolamento só na infraestrutura. A alternativa clássica é um banco por tenant, ou um schema por tenant. Isso resolve o vazamento com força bruta e cobra o preço em migração: toda alteração de schema precisa rodar em N bancos, e uma delas vai falhar no meio. Optei por tenant explícito nas entidades relevantes, com o escopo aplicado no nível do modelo em vez de depender de cada query lembrar do where. O risco que assumo é conhecido — um caminho que escape do escopo é bug de vazamento — e é por isso que o escopo mora no modelo, não na chamada.
Um build de frontend, configuração por tenant vinda da API. Build por criador seria mais simples de raciocinar e um pesadelo de operar: cada mudança de UI exigiria reconstruir e republicar N frontends. O React é um só; ele lê a configuração do tenant ativo (domínio, marca, cores, planos) da API Laravel e se adapta em runtime. O custo é que nada de identidade pode estar hardcoded — tudo é dado.
Asaas em vez de gateway internacional. Para assinatura recorrente no Brasil, PIX e boleto não são detalhe: são o que decide se o assinante conclui o pagamento. Stripe teria melhor DX e documentação, mas o meio de pagamento local pesa mais na conversão do que a qualidade do SDK. Asaas tem recorrência, PIX e boleto nativos e compliance nacional resolvido.
IA orquestrada no backend, não no cliente. Os recursos de IA que o criador usa são chamados a partir do Laravel. Chamar o provedor direto do React seria mais rápido de escrever e exporia credencial, tiraria o controle de custo e impediria limitar uso por plano. No backend, a chamada é contabilizada, limitada por tenant e trocável de provedor sem tocar no frontend.
AWS em vez de servidor fixo. Multi-tenant em lançamento tem crescimento imprevisível: pode ser um criador por semana ou dez em um dia depois de um vídeo viral. AWS permite acompanhar isso sem provisionar servidor por criador nem replanejar infra a cada degrau.
O que ficou pronto
Plataforma em lançamento (peekingme.com.br): cadastro de criador, site de assinatura com marca própria, gestão de assinantes, cobrança recorrente integrada e recursos de IA. Como é produto próprio e não escopo fechado de cliente, segue em iteração — o que muda a natureza do trabalho: aqui eu decido também prioridade, precificação e nível de customização, não só implementação.
O que eu faria diferente hoje
Teria escrito, desde o primeiro dia, uma suíte de testes dedicada só a vazamento entre tenants — um teste por entidade, tentando ler dado de outro tenant e esperando falha. Adicionei isso depois. É o tipo de rede de segurança que só é barata enquanto o modelo de dados é pequeno.
Site: peekingme.com.br