refactor(core) : RBAC Task 1 - polish apres revue qualite

- Permission : guards constructeur (code/label/module non vides, code avec point)
- Permission::revive() reutilise updateMetadata() pour eviter la duplication
- Suppression de SystemRolesTest (tautologique, ne capture aucun comportement)
- Role::permissions : commentaire explicite sur la raison du fetch EAGER
- Alignement des types de retour sur static (style User.php)
- Nouveau test Role::addPermission avec permissions distinctes

Ticket #343 - Task 1 polish (revue qualite).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-04-14 16:37:53 +02:00
parent f0ea9201f5
commit 0fc0b57e37
5 changed files with 84 additions and 35 deletions

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Module\Core\Domain\Entity;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
// TODO: brancher repositoryClass au ticket 343 partie 2 (Task 2).
#[ORM\Entity]
@@ -31,8 +32,29 @@ class Permission
#[ORM\Column(options: ['default' => false])]
private bool $orphan = false;
/**
* Invariants : une permission doit avoir un code non vide respectant la
* convention "module.resource[.sub].action" (donc contenir au moins un
* point), un libelle non vide et un module proprietaire non vide. Ces
* garde-fous evitent la persistence de lignes incoherentes si un appelant
* (fixture, commande de synchro, import) oublie un champ ou passe une
* chaine vide.
*/
public function __construct(string $code, string $label, string $module)
{
if ('' === $code) {
throw new InvalidArgumentException('Le code de permission ne peut pas etre vide.');
}
if (!str_contains($code, '.')) {
throw new InvalidArgumentException(sprintf('Le code de permission "%s" ne respecte pas la convention "module.resource[.sub].action".', $code));
}
if ('' === $label) {
throw new InvalidArgumentException('Le libelle de permission ne peut pas etre vide.');
}
if ('' === $module) {
throw new InvalidArgumentException('Le module proprietaire de la permission ne peut pas etre vide.');
}
$this->code = $code;
$this->label = $label;
$this->module = $module;
@@ -69,7 +91,7 @@ class Permission
* permettre une reactivation ulterieure, mais doit etre ignoree par les
* verifications d'autorisation.
*/
public function markOrphan(): self
public function markOrphan(): static
{
$this->orphan = true;
@@ -78,14 +100,14 @@ class Permission
/**
* Reactive une permission precedemment orpheline : son code reapparait
* dans le code source d'un module. On en profite pour rafraichir les
* metadonnees (libelle et module d'appartenance).
* dans le code source d'un module. Equivaut a updateMetadata() suivi d'un
* clearing du flag orphan ; on delegue a updateMetadata() pour ne pas
* dupliquer la logique d'affectation des metadonnees.
*/
public function revive(string $label, string $module): self
public function revive(string $label, string $module): static
{
$this->updateMetadata($label, $module);
$this->orphan = false;
$this->label = $label;
$this->module = $module;
return $this;
}
@@ -95,7 +117,7 @@ class Permission
* statut d'orphelin. Utilise par la commande de synchronisation lorsque
* seul le libelle ou le module proprietaire a change cote code.
*/
public function updateMetadata(string $label, string $module): self
public function updateMetadata(string $label, string $module): static
{
$this->label = $label;
$this->module = $module;