Use ao implementar backend em PHP com Laravel, quando project.config.md indicar esta stack. Cobre estrutura hexagonal em PHP, injeção de dependência via Service Container do Laravel, Eloquent somente para mapeamento (SQL customizado para queries complexas), Value Objects com readonly classes, CQRS, OpenAPI via l5-swagger, Prometheus via spatie/laravel-prometheus, e idiomas específicos da linguagem.
Use ao implementar backend em PHP com Laravel, quando project.config.md indicar esta stack. Cobre estrutura hexagonal em PHP, injeção de dependência via Service Container do Laravel, Eloquent somente para mapeamento (SQL customizado para queries complexas), Value Objects com readonly classes, CQRS, OpenAPI via l5-swagger, Prometheus via spatie/laravel-prometheus, e idiomas específicos da linguagem.
Backend: PHP + Laravel + Hexagonal
Padrões universais (hexagonal, SOLID, CQRS, UUID, stateless, Value Objects,
ABAC, auditoria, observabilidade, OpenAPI) estão em CLAUDE.md — não são
repetidos aqui. Esta skill documenta apenas o que é específico do PHP/Laravel.
Estrutura de pastas
app/
├── Domain/
│ ├── Entity/ # entidades com identidade e comportamento
│ ├── ValueObject/ # readonly classes — imutáveis por definição
│ ├── Port/ # interfaces (Contracts) de repositório, cache, evento
│ └── Exception/ # exceções de domínio tipadas
├── Application/
│ ├── Command/
│ │ └── <Entidade>/ # ex: Processo/, Usuario/, Conta/
│ │ ├── CriarProcessoUseCase.php
│ │ └── AtualizarProcessoUseCase.php
│ └── Query/
│ └── <Entidade>/ # ex: Processo/, Usuario/
│ ├── ListarProcessosUseCase.php
│ └── BuscarProcessoUseCase.php
├── Adapter/
│ ├── Http/ # Controllers Laravel — finos, sem lógica de negócio
│ ├── Persistence/ # implementações dos ports usando Query Builder
│ │ └── Migrations/ # migrations Laravel com up() e down() obrigatórios
│ ├── Cache/ # Redis via Laravel Cache
│ └── Messaging/ # publishers de fila (Laravel Queues / RabbitMQ)
├── Infrastructure/
│ └── Providers/
│ └── AppServiceProvider.php # binding dos ports no Service Container
└── Http/
└── Requests/ # Form Requests para validação
Regra inegociável: Domain/ e Application/ nunca importam de Adapter/.
Acesso a dados: Query Builder (não Eloquent ORM para queries complexas)
Queries simples (CRUD):DB::table('processos')->insert(...) ou
Eloquent Model como mapeador de resultado — não como entidade de domínio.
Queries complexas (relatórios, agregações, joins pesados): SQL puro via
DB::select(DB::raw(...)) com parâmetros bindados — nunca concatenação.
Regra da allowlist de ordenação (igual às outras stacks):
privateconstCOLUNAS_ORDENAVEIS = ['criado_em', 'descricao', 'status'];
publicfunctionlistar(ListarProcessosQuery $query): ProcessoPage{
if (!in_array($query->sort, self::COLUNAS_ORDENAVEIS, true)) {
thrownew\InvalidArgumentException("Coluna de ordenação inválida");
}
// $query->sort é seguro aqui — está na allowlist$resultados = DB::table('processos')
->whereNull('excluido_em')
->orderBy($query->sort, $query->order)
->paginate($query->pageSize);
}
Migrations com up() e down() obrigatórios
// Migrations incluem sempre o down() funcionalpublicfunctionup(): void{
Schema::create('processo', function (Blueprint $table) {
$table->uuid('id')->primary(); // UUIDv7 gerado na aplicação$table->text('descricao');
$table->string('status', 50);
$table->uuid('responsavel_id')->index();
$table->foreign('responsavel_id')->references('id')->on('usuario');
$table->timestampsTz(); // criado_em + atualizado_em$table->softDeletes('excluido_em'); // deleção lógica
});
}
publicfunctiondown(): void{
Schema::dropIfExists('processo');
}
Importante:softDeletes('excluido_em') implementa a deleção lógica do
projeto automaticamente — Model::query() já filtra excluido_em IS NULL.
Verificar que isso está ativo em todo Model usado para leitura.
Observabilidade e documentação de API (ver CLAUDE.md para as regras)