Skip to content

Visão Geral da Arquitetura

Padrões

DDD (Domain-Driven Design)

O código é organizado por domínios de negócio em app/Domain/:

DomínioResponsabilidade
ChurchIgreja, congregações, oficiais, endereços, referência eclesiástica
MemberMembros, telefones
FinanceTransações, categorias, contas bancárias
UserUsuários do sistema
SharedModels compartilhados (Escolaridade, Profissão, País, UF, TelefoneTipo)

Cada domínio contém: Models/, Actions/, Events/, Policies/, Observers/.

Actions (não Services)

Lógica de negócio fica em Actions — classes final readonly com um único método execute(). Services são usados apenas para integrações com ferramentas externas (APIs de terceiros).

php
final readonly class CreateMemberAction
{
    public function execute(array $data): Member
    {
        $member = Member::create($data);
        MemberCreated::dispatch($member);
        return $member;
    }
}

Models Unguarded

Models são globalmente unguarded (Model::unguard() no AppServiceProvider). Validação acontece via Form Requests.

ULID como Identificador Público

Todos os models de domínio usam ULID (HasUlids trait) como identificador público. O id numérico nunca é exposto na API ou URLs.

php
public function getRouteKeyName(): string { return 'ulid'; }
public function uniqueIds(): array { return ['ulid']; }

Auditoria

Todos os models de domínio implementam OwenIt\Auditing\Contracts\Auditable + OwenIt\Auditing\Auditable trait. Alterações são registradas automaticamente.

Fluxo de Request

Browser → Nginx → PHP-FPM (app container)
    → Tenancy Middleware (identifica tenant por domínio)
    → Web Middleware (session, CSRF)
    → Auth Middleware
    → Controller
        → authorize (Policy)
        → validate (Form Request)
        → execute (Action → Event)
    → Inertia::render (Vue page)

Banco de Dados

Central (laravel)

  • tenants — registro de tenants com plan_id
  • domains — domínios por tenant
  • plans — planos de assinatura
  • sessions — sessions (driver cookie, tabela de fallback)
  • cache, jobs — infra Laravel

Tenant (tenant{id})

Cada tenant tem seu próprio banco com:

  • users, password_reset_tokens, sessions
  • permissions, roles, role_has_permissions, model_has_roles, model_has_permissions
  • members, member_phones
  • church_profiles, congregations, church_officials, addresses
  • igreja_situacoes, igreja_funcoes, igreja_cargos, igreja_modos_admissao
  • transactions, transaction_categories, bank_accounts
  • escolaridades, profissoes, telefone_tipos, paises, ufs
  • media, audits

Testes

  • Framework: Pest PHP
  • Banco: SQLite in-memory (RefreshDatabase)
  • Tenancy: middlewares de tenancy desabilitados globalmente nos Feature tests (via Pest.php)
  • Cobertura: 429+ testes, 982+ assertions