Workshop ao vivo, tom de aula prática mesmo com bastante teoria antes de abrir o código. Danilo e Virgão dividiram a noite entre fundamentos de arquitetura (por que multi-database, quando NÃO usar) e a implementação real dentro de uma aplicação Laravel + Sail, com o chat participando o tempo todo trazendo casos reais (RDS por tenant, imagens por tenant, relatórios cross-tenant, webhooks de gateway de pagamento).
Destaques
- Comparação direta single database vs. multi-database: prós (simplicidade, queries agregadas fáceis) e contras (risco de vazamento entre tenants, dificuldade de escalar, chargeback complicado) de cada abordagem, sem vender nenhuma das duas como "a certa".
- Estratégia de banco compartilhado (landlord) com tabela
tenants(nome, domínio, nome do banco) + um banco por tenant, usando o pacotespatie/laravel-multitenancyv4. - Configuração passo a passo:
composer require spatie/laravel-multitenancy, publicação do config e das migrations do landlord, criação das conexõeslandlordetenantnoconfig/database.php(comdatabasenulo na conexão tenant — quem escolhe é o pacote em runtime). DomainTenantFinderresolvendo o tenant pelo host da requisição, troca automática de conexão viaSwitchTenantDatabaseTask, e o comandotenants:artisan "migrate"/"db:seed"rodando migrations e seeds em todos os bancos de tenant de uma vez.- Demonstração de que filas, eventos e observers já nascem "tenant aware" — o job/evento/listener sabe automaticamente qual tenant disparou, sem código extra, porque a conexão já foi resolvida no início do ciclo de vida da requisição.
- Ponto de atenção explícito para
schedule(comandos Artisan via cron não têm request/domínio) — solução mostrada comTenant::all()->each->makeCurrent()para rodar uma rotina em todos os tenants, com opção de passar o tenant específico por parâmetro. - Discussão aprofundada sobre webhooks multi-tenant (ex.: Mercado Pago): 3 cenários — aplicação separada por tenant (ideal), header/campo de identificação do tenant na requisição, ou pior caso, varrer todos os bancos por um ID de venda (evitar, ruim para performance e arriscado por colisão de IDs).
- Recomendações de arquitetura complementares: cache/Redis com prefixo por tenant (mas separado por questão de precificação), relatórios cross-tenant via data warehouse/ETL ou job simples alimentando outro banco à noite, e cuidado com o custo operacional de escalar bancos por tenant antes de precisar.
Profundidade técnica
O workshop foi além do "copiar comando" — os instrutores abriram o código-fonte do pacote Spatie (SwitchTenantDatabaseTask, DomainTenantFinder) para mostrar exatamente onde a troca de conexão acontece no service container do Laravel, e insistiram em entender o ciclo de vida da requisição para saber em quais contextos existe (ou não) um tenant "ativo" — request HTTP sim, comando artisan via schedule não. Trataram também de decisões de negócio com peso técnico real: quando migrar de single para multi-database (baixa complexidade se o projeto já usa Laravel/migrations direito), estratégia de domínio próprio vs. subdomínio (SSL wildcard, DNS, White Label), e armadilhas como abrir uma "brecha comercial" fácil demais para customização por cliente que vira dívida técnica.
Faça parte do Clã
Esse tipo de profundidade — decisão de arquitetura discutida ao vivo, com código real rodando e o porquê de cada escolha — é exatamente o que rola toda semana dentro do Clã Beer and Code. Se você quer transformar workshops como esse em rotina, ter mentoria técnica direta e trocar ideia com quem constrói SaaS de verdade no dia a dia, é hora de entrar para o Clã.
Engenharia de IA virou profissão, e se aprende construindo, não assistindo. O Clã Beer and Code é o ambiente onde isso acontece ao vivo, toda semana: RAG, agentes, observabilidade e LLMOps em projetos reais, ao lado de quem já está em produção. É pago, é assinatura, e é exatamente o ambiente que estes encontros dão uma amostra.
Entrar no Clã