Skip to content

Multi-Tenancy

Abordagem

O sistema usa stancl/tenancy com banco de dados isolado por tenant. Cada igreja (tenant) tem seu próprio banco MariaDB, identificado pelo subdomínio.

AspectoImplementação
IdentificaçãoPor domínio completo (InitializeTenancyByDomain)
IsolamentoMulti-database (um banco por tenant)
Namingtenant{id} (ex: tenantalfa, tenantbeta)
Migrationsdatabase/migrations/tenant/
SeedersTenantDatabaseSeeder (produção + desenvolvimento)

Fluxo de Criação de Tenant

Quando um Tenant é criado (Tenant::create()), o pipeline em TenancyServiceProvider executa:

  1. Jobs\CreateDatabase — cria o banco tenant{id}
  2. Jobs\MigrateDatabase — roda migrations de database/migrations/tenant/
  3. Jobs\SeedDatabase — roda TenantDatabaseSeeder (roles, permissions, referência, dados dev)

Tenant Model

php
final class Tenant extends BaseTenant implements TenantWithDatabase
{
    use HasDatabase, HasDomains;

    // Colunas reais (não JSON)
    public static function getCustomColumns(): array
    {
        return ['id', 'plan_id', 'extra_features', 'trial_ends_at'];
    }
}

Domínios Centrais

Configurados em config/tenancy.php:

php
'central_domains' => [
    str(env('APP_URL'))->after('://')->before('/')->before(':')->toString(),
],

Rotas centrais ficam em routes/web.php com Route::domain($domain). Rotas de tenant ficam em routes/tenant.php.

Session

SESSION_DRIVER=cookie — evita problemas de cross-database session. Cookies são isolados por domínio naturalmente.

Cuidados

  • Models centrais (Plan, Tenant) devem usar getConnectionName() para sempre acessar o banco central
  • Testes rodam sem tenancy real (middlewares desabilitados no Pest.php) — tudo no SQLite in-memory
  • Migrations centrais vão em database/migrations/ (sem tenant/)
  • Migrations de tenant vão em database/migrations/tenant/