📚 Pré-requisitos Teóricos: Este projeto prático aplica os conceitos avançados de arquitetura multi-inquilino ensinados na Especialização em Backend com PHP e Laravel. Recomendamos sua consulta para contextualização sobre isolamento de dados e Scopes globais do Eloquent.
A Plataforma SaaS Multi-Tenant com Filament Admin v3 aborda a engenharia de sistemas B2B escaláveis onde múltiplas organizações compartilham a mesma base de código mantendo estrito isolamento lógico e físico de dados. Utilizando o Laravel 11, o painel administrativo Filament v3 e estratégias de Global Scopes e Schemas Dedicados, o projeto entrega uma infraestrutura corporativa robusta e pronta para produção.
O diagrama abaixo detalha a resolução da requisição por subdomínio corporativo e a injeção do escopo de inquilino no Eloquent ORM:
A base de código segue o padrão canônico com nomenclatura anti-colisão:
catalogo_projetos/backend_php_04_saas_multitenancy/
├── api-laravel/ # Backend SaaS corporativo com Laravel 11
│ ├── app/
│ │ ├── Filament/ # Recursos, páginas e painéis do Filament v3
│ │ │ └── Resources/
│ │ ├── Http/
│ │ │ └── Middleware/
│ │ │ └── IdentifyTenantMiddleware.php # Resolução por subdomínio
│ │ ├── Models/
│ │ │ ├── Tenant.php # Entidade central do inquilino
│ │ │ └── Scopes/
│ │ │ └── TenantScope.php # Escopo global do Eloquent
│ ├── config/
│ │ └── tenancy.php # Estratégia de conexão e separação
│ └── composer.json # Dependências: filament/filament, stancl/tenancy
├── assets/ # Galeria de diagramas visuais e arquitetura
│ └── arquitetura_laravel_multitenancy.svg
└── index.md # Especificação executiva e Padrão Ouro
| ID | Persona | História de Usuário | Prioridade |
|---|---|---|---|
| US-01 | Administrador da Empresa (Tenant) | Desejo acessar minha organização através de um subdomínio próprio (empresa.saas.com) com login isolado. |
Alta |
| US-02 | Oficial de Proteção de Dados (DPO) | Desejo garantia absoluta de que usuários de um inquilino jamais tenham acesso a dados de outro (LGPD/GDPR). | Alta |
| US-03 | Desenvolvedor Backend | Desejo que todas as consultas ao banco apliquem automaticamente o filtro do inquilino sem necessidade de WHERE manual em cada query. | Alta |
| US-04 | Gestor de Produto | Desejo um painel administrativo intuitivo e responsivo com Filament v3 para gerenciamento operacional. | Média |
| US-05 | Engenheiro de DevOps | Desejo rodar migrações de banco em lote para todos os clientes corporativos com um único comando Artisan. | Média |
| ID | Nome | Descrição |
|---|---|---|
| RF-01 | Identificação por Subdomínio | Extrair o subdomínio da requisição HTTP via middleware e resolver a instância do Tenant ativo. |
| RF-02 | Escopo Global Eloquent | Injetar automaticamente TenantScope aplicando a cláusula WHERE tenant_id = ? em todos os modelos. |
| RF-03 | Atribuição Automática | Preencher o campo tenant_id no evento creating do ciclo de vida dos modelos Eloquent. |
| RF-04 | Painel Filament Tenancy | Configurar o Filament Admin v3 com suporte a Multi-Tenancy, isolando a navegação entre empresas. |
| RF-05 | Migrações por Inquilino | Comando php artisan tenants:migrate para executar migrations em cada schema/banco de inquilino. |
| ID | Nome | Descrição |
|---|---|---|
| RNF-01 | Blindagem contra Vazamento | Zero possibilidade de acesso cruzado de dados mesmo sob falhas de injeção ou parâmetros forjados. |
| RNF-02 | Overhead Sub-5ms | Identificação e inicialização de contexto de tenancy processada em menos de 5ms por requisição. |
| RNF-03 | Prefixação de Cache | Todas as chaves do Redis de cache de aplicação devem ser prefixadas com o identificador do inquilino. |
| RNF-04 | Escalabilidade de Schema | Suporte a milhares de inquilinos em instâncias PostgreSQL utilizando esquemas dedicados. |
| RNF-05 | Conformidade com PSR-12 | Padrões estritos de código e tipagem forte em PHP 8.3. |
flowchart TD
subgraph Atores
TEN["Usuário da Empresa (Tenant)"]
SYS["Kernel HTTP Laravel"]
ADM["Super Admin da Plataforma"]
end
subgraph "Plataforma SaaS (api-laravel)"
UC1["Acessar Aplicação via Subdomínio"]
UC2["Identificar Tenant no Middleware"]
UC3["Aplicar Global Scope Eloquent nas Consultas"]
UC4["Navegar no Painel Filament Admin v3"]
UC5["Executar Migrações em Lote (tenants:migrate)"]
end
TEN --> UC1
UC1 --> UC2
UC2 --> UC3
TEN --> UC4
ADM --> UC5
| Requisito Funcional | Histórias Atendidas | Requisitos Não-Funcionais | Status de Cobertura |
|---|---|---|---|
| RF-01 (Identificação Subdomínio) | US-01 | RNF-01, RNF-02 | Implementado ✅ |
| RF-02 (Escopo Global Eloquent) | US-02, US-03 | RNF-01, RNF-04 | Implementado ✅ |
| RF-03 (Atribuição Automática) | US-02, US-03 | RNF-01, RNF-05 | Implementado ✅ |
| RF-04 (Painel Filament Tenancy) | US-01, US-04 | RNF-03, RNF-05 | Implementado ✅ |
| RF-05 (Migrações por Inquilino) | US-05 | RNF-01, RNF-04 | Implementado ✅ |
api-laravel/app/Models/Tenant.php)<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;
class Tenant extends Model
{
protected $fillable = [
'id',
'nome',
'subdominio',
'plano',
'ativo',
'database_schema',
];
protected $casts = [
'ativo' => 'boolean',
];
public $incrementing = false;
protected $keyType = 'string';
protected static function booted(): void
{
static::creating(function (Tenant $tenant) {
if (empty($tenant->id)) {
$tenant->id = (string) Str::uuid();
}
if (empty($tenant->database_schema)) {
$tenant->database_schema = 'tenant_' . Str::slug($tenant->subdominio, '_');
}
});
}
public function usuarios(): HasMany
{
return $this->hasMany(User::class);
}
}
cd catalogo_projetos/backend_php_04_saas_multitenancy/api-laravel
composer install
php artisan migrate
php artisan tinker --execute="App\Models\Tenant::create(['nome'=>'Empresa Alpha','subdominio'=>'alpha','plano'=>'pro','ativo'=>true]);"
php artisan serve --port=8000
Teste o acesso via requisição com cabeçalho ou subdomínio configurado no /etc/hosts (alpha.localhost:8000).
| Checkpoint | Critério de Aceite | Validação | Status |
|---|---|---|---|
| CP-01 | Inicialização do runtime Laravel 11 com arquitetura Multi-Tenant | Resposta HTTP do kernel operacional | PASS ✅ |
| CP-02 | Resolução do Tenant por subdomínio no middleware | Extração correta do identificador corporativo | PASS ✅ |
| CP-03 | Aplicação automática do TenantScope bloqueando dados cruzados |
Consultas blindadas por organização | PASS ✅ |
| CP-04 | Painel Filament Admin v3 integrado com isolamento por inquilino | Interface visual restrita ao tenant logado | PASS ✅ |
| CP-05 | Migrations executando isoladamente por esquema/inquilino | Schemas criados sem colisão de tabelas | PASS ✅ |