feat(squads): fundar Squad com ciclo de vida#382
Conversation
There was a problem hiding this comment.
Pull request overview
Funda o primeiro slice runtime do módulo squads, introduzindo o agregado Squad com persistência (migration), SquadStatus como enum/cast no model, actions para criação e transições de status, e testes de criação/autorização/ciclo de vida.
Changes:
- Move/ajusta o
SquadsServiceProviderparasrc/e atualiza referências do provider no módulo e no lockfile. - Adiciona migration/model/factory/enum para o agregado
Squadcomstatustipado e unicidade deslugportenant. - Implementa actions (
CreateSquad,ActivateSquad,DeactivateSquad,ArchiveSquad) e testes de criação e transições.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| composer.lock | Atualiza o provider auto-discovered para o novo namespace/classe. |
| app-modules/squads/composer.json | Atualiza o provider do módulo para He4rt\\Squads\\SquadsServiceProvider. |
| app-modules/squads/src/SquadsServiceProvider.php | Ajusta namespace do provider para He4rt\\Squads. |
| app-modules/squads/database/migrations/2026_07_01_015630_create_squads_table.php | Cria tabela squads com constraints/índices e timestamps Tz. |
| app-modules/squads/src/Models/Squad.php | Define model Squad com casts e relação com Tenant. |
| app-modules/squads/src/Enums/SquadStatus.php | Introduz enum backed string para status do squad. |
| app-modules/squads/database/factories/SquadFactory.php | Cria factory para gerar squads válidos em testes. |
| app-modules/squads/src/Actions/CreateSquad.php | Action de criação com autorização de super-admin e slug único por tenant. |
| app-modules/squads/src/Actions/ActivateSquad.php | Action para transicionar status para active. |
| app-modules/squads/src/Actions/DeactivateSquad.php | Action para transicionar status para inactive. |
| app-modules/squads/src/Actions/ArchiveSquad.php | Action para transicionar status para archived. |
| app-modules/squads/tests/Feature/CreateSquadTest.php | Testa criação, autorização e unicidade de slug. |
| app-modules/squads/tests/Feature/SquadLifecycleTest.php | Testa transições e bloqueio por autorização. |
Comments suppressed due to low confidence (1)
app-modules/squads/src/SquadsServiceProvider.php:7
- O provider do módulo não carrega as migrations. Sem
loadMigrationsFrom(__DIR__.'/../database/migrations'), a migrationcreate_squads_tablepode não ser descoberta quando o pacote é carregado, impedindo a criação da tabelasquadsem ambientes que dependem do ServiceProvider.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| namespace He4rt\Squads\Actions; | ||
|
|
||
| use He4rt\Identity\User\Models\User; | ||
| use He4rt\Squads\Enums\SquadStatus; | ||
| use He4rt\Squads\Models\Squad; | ||
| use Illuminate\Auth\Access\AuthorizationException; | ||
|
|
||
| final class ActivateSquad | ||
| { | ||
| public function handle(User $actor, Squad $squad): Squad | ||
| { | ||
| if (!$actor->isAdmin()) { | ||
| throw new AuthorizationException(); | ||
| } | ||
|
|
||
| $squad->update([ | ||
| 'status' => SquadStatus::Active, | ||
| ]); |
| namespace He4rt\Squads\Actions; | ||
|
|
||
| use He4rt\Identity\User\Models\User; | ||
| use He4rt\Squads\Enums\SquadStatus; | ||
| use He4rt\Squads\Models\Squad; | ||
| use Illuminate\Auth\Access\AuthorizationException; | ||
|
|
||
| final class DeactivateSquad | ||
| { | ||
| public function handle(User $actor, Squad $squad): Squad | ||
| { | ||
| if (!$actor->isAdmin()) { | ||
| throw new AuthorizationException(); | ||
| } | ||
|
|
||
| $squad->update([ | ||
| 'status' => SquadStatus::Inactive, | ||
| ]); |
| namespace He4rt\Squads\Actions; | ||
|
|
||
| use He4rt\Identity\User\Models\User; | ||
| use He4rt\Squads\Enums\SquadStatus; | ||
| use He4rt\Squads\Models\Squad; | ||
| use Illuminate\Auth\Access\AuthorizationException; | ||
|
|
||
| final class ArchiveSquad | ||
| { | ||
| public function handle(User $actor, Squad $squad): Squad | ||
| { | ||
| if (!$actor->isAdmin()) { | ||
| throw new AuthorizationException(); | ||
| } | ||
|
|
||
| $squad->update([ | ||
| 'status' => SquadStatus::Archived, | ||
| ]); |
| actor: $actor, | ||
| squad: $squad, | ||
| ); | ||
| })->throws(AuthorizationException::class); |
|
Meninos se puderem dar prioridade, essa task é necessária para poder liberar as outras |
| $table->string('name'); | ||
| $table->string('slug'); | ||
| $table->text('objective')->nullable(); | ||
| $table->string('status', 30)->default(SquadStatus::Draft->value); |
There was a problem hiding this comment.
not a good code practice to reference enum class with a value in a table column even when it will store enum values
| use Illuminate\Auth\Access\AuthorizationException; | ||
|
|
||
| test('super-admin creates a squad as draft', function (): void { | ||
| config(['he4rt.admins' => 'guisaliba']); |
There was a problem hiding this comment.
its weird to see this, but while this project doesnt have a rbac module then it is what it is
Closes #354
O que foi feito
Funda o primeiro slice runtime do módulo
squads, criando o agregadoSquadcom persistência, status tipado, criação autorizada por super-admin e transições básicas de ciclo de vida.src/SquadsServiceProvider.phpe referência atualizada nocomposer.jsonsquadsvia módulo, com datasTz:tenant_idnameslugobjectivenullablestatusdefaultdraftUNIQUE (tenant_id, slug)INDEX (tenant_id, status)Squadcom@propertyPHPDoc,#[Table],#[UseFactory],HasUuidse cast destatusSquadFactorySquadStatus:draft,active,inactive,archivedCreateSquad— cria squad comodraft, apenas por super-admin, com slug único por tenantActivateSquad— muda status paraactiveDeactivateSquad— muda status parainactiveArchiveSquad— muda status paraarchivedCritérios de aceite
Tz,UNIQUE (tenant_id, slug)eINDEX (tenant_id, status)Squadcom PHPDoc sincronizadoSquadStatuscast no modelCreateSquadsó por super-admindraftdraft → active → inactive → archivedCenários BDD → testes
CreateSquadTestCreateSquadTestCreateSquadTestSquadLifecycleTestSquadLifecycleTestValidação local
Rodado contra Postgres real via Docker Compose:
app-modules/squads/tests/Feature— 10 testes / 21 assertionsObservação: o Pest completo da aplicação executou 845 testes, com 837 passando e 8 falhando por ausência de
public/build/manifest.jsonem testes de UI/Filament. As falhas não passam pelo módulosquads.