Files
Mangarr/phparkitect.php
2025-03-22 17:48:19 +01:00

80 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
use Arkitect\ClassSet;
use Arkitect\CLI\Config;
use Arkitect\Expression\ForClasses\HaveNameMatching;
use Arkitect\Expression\ForClasses\NotDependsOnTheseNamespaces;
use Arkitect\Expression\ForClasses\NotHaveDependencyOutsideNamespace;
use Arkitect\Expression\ForClasses\ResideInOneOfTheseNamespaces;
use Arkitect\Rules\Rule;
return static function (Config $config): void {
$domainClassSet = ClassSet::fromDir(__DIR__ . '/src/Domain');
$businessDomains = ['Manga', 'Reader', 'Scraping'];
// Classes PHP standards et utilitaires
$standardExceptions = [
'DateTimeImmutable',
'RuntimeException',
'Exception',
'DomainException',
'Symfony\Component\HttpKernel\Exception',
'Throwable',
'InvalidArgumentException',
];
// Dépendances externes autorisées
$externalDependencies = [
'Symfony\Component\Messenger',
'Ramsey\Uuid'
];
// Règle pour le namespace cohérent
$namespaceRule = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces('App\Domain'))
->should(new HaveNameMatching('*'))
->because('nous voulons un namespace cohérent pour notre domaine');
$rules = [$namespaceRule];
// Règles spécifiques pour le domaine Shared
$rules[] = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces('App\Domain\Shared'))
->should(new NotHaveDependencyOutsideNamespace(
'App\Domain\Shared',
$standardExceptions
))
->because('le domaine Shared ne doit dépendre de personne');
// Génération des règles pour chaque domaine métier
foreach ($businessDomains as $domain) {
// Règle pour la couche Domain
$rules[] = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces("App\Domain\\$domain\Domain"))
->should(new NotHaveDependencyOutsideNamespace(
"App\Domain\\$domain\Domain",
$standardExceptions
))
->because("la couche Domain de $domain ne doit dépendre que de ses propres classes, des contrats partagés et des exceptions autorisées");
// Règle pour la couche Application
$rules[] = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces("App\Domain\\$domain\Application"))
->should(new NotHaveDependencyOutsideNamespace(
"App\Domain\\$domain",
array_merge($standardExceptions, $externalDependencies, ['App\Domain\Shared\Contract'])
))
->because("la couche Application de $domain ne peut dépendre que de son propre domaine, des contrats partagés et des dépendances autorisées");
// Interdiction explicite pour l'Application d'accéder à l'Infrastructure
$rules[] = Rule::allClasses()
->that(new ResideInOneOfTheseNamespaces("App\Domain\\$domain\Application"))
->should(new NotDependsOnTheseNamespaces("App\Domain\\$domain\Infrastructure"))
->because("la couche Application de $domain ne doit jamais dépendre de l'Infrastructure, même au sein de son propre domaine");
}
$config->add($domainClassSet, ...$rules);
};