Files
ext.jeremy.guillot@maxicoffee.domains dae215dd3d
All checks were successful
Build and Deploy / deploy (push) Successful in 9m36s
feat: ajout de claude + correction des tests
2026-03-09 17:09:31 +01:00

5.5 KiB

name, description, allowed-tools
name description allowed-tools
hexagonal-arch Architecture hexagonale du projet Mangarr — structure exacte des dossiers, règles d'import strictes par couche, nommage ports (interfaces) vs adapters (implémentations). Utiliser quand on crée un nouveau domaine, un nouveau fichier, ou qu'on vérifie les dépendances entre couches. Read, Grep, Glob, Bash

Architecture Hexagonale — Mangarr

Structure canonique d'un domaine

src/Domain/{DomainName}/
  Domain/                          ← NOYAU pur, 0 dépendance framework
    Model/
      {Aggregate}.php
      ValueObject/
        {VoName}.php
    Event/
      {SomethingHappened}.php
    Exception/
      {Something}Exception.php
    Contract/                      ← PORTS (interfaces only)
      Repository/
        {Name}RepositoryInterface.php
      Service/
        {Name}Interface.php
      Client/
        {Name}ClientInterface.php

  Application/                     ← Use cases, orchestre le Domain
    Command/
      {DoSomething}.php
    CommandHandler/
      {DoSomething}Handler.php
    Query/
      {GetSomething}.php
    QueryHandler/
      {GetSomething}Handler.php
    Response/
      {Something}Response.php
    EventListener/
      {SomethingHappened}EventListener.php

  Infrastructure/                  ← ADAPTERS (implémentations concrètes)
    Persistence/
      Repository/
        {Name}Repository.php       ← implémente Domain/Contract/Repository/
    ApiPlatform/
      Resource/
        {FeatureName}Resource.php
      State/
        Processor/
          {DoSomething}Processor.php
        Provider/
          {GetSomething}StateProvider.php
      Dto/
        {Name}.php
    Service/
      {ServiceName}.php            ← implémente Domain/Contract/Service/
    Client/
      {ClientName}.php             ← implémente Domain/Contract/Client/
    CommandHandler/                ← handlers Symfony Messenger (wrappent l'Application)
      Symfony{DoSomething}Handler.php

Domaines du projet

Domaine Responsabilité
Manga Catalogue mangas, chapitres, métadonnées
Scraping Téléchargement de chapitres depuis les sources
Conversion Conversion de formats (CBR→CBZ, génération CBZ)
Reader Lecture de chapitres
Setting Configuration applicative
Shared Contrats transverses (EventDispatcherInterface, MangaPathManagerInterface, etc.)

Règles d'import strictes

Domain (noyau)

✅ Peut importer :  son propre namespace uniquement
                   + exceptions PHP standard
❌ Interdit :       Symfony\*, Doctrine\*, Ramsey\Uuid, tout autre domaine

Application

✅ Peut importer :  son propre Domain (App\Domain\{X}\Domain\*)
                   App\Domain\Shared\Domain\Contract\*
                   Symfony\Component\Messenger\*
                   Ramsey\Uuid\*
❌ Interdit :       son propre Infrastructure (App\Domain\{X}\Infrastructure\*)
                   Doctrine\*, tout autre domaine

Infrastructure

✅ Peut importer :  tout (Symfony, Doctrine, API Platform, etc.)
                   son Application et son Domain
❌ Convention :     ne pas contenir de logique métier (déléguer à Application)

Ports vs Adapters — nommage

Concept Localisation Suffixe Exemple
Port Domain/Contract/Repository/ Interface MangaRepositoryInterface
Port Domain/Contract/Service/ Interface ImageProcessorInterface
Port Domain/Contract/Client/ Interface MangadexClientInterface
Adapter Infrastructure/Persistence/ Repository LegacyChapterRepository
Adapter Infrastructure/Service/ (nom libre) ImageProcessor
Adapter Infrastructure/Client/ Client MangadexClient

Le binding port → adapter se déclare dans config/services.yaml :

App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface:
    alias: App\Domain\Manga\Infrastructure\Persistence\Repository\LegacyMangaRepository

Shared Domain

Les contrats transverses vivent dans src/Domain/Shared/Domain/Contract/ :

  • CommandInterface, QueryInterface, ResponseInterface — marqueurs
  • CommandHandlerInterface, QueryHandlerInterface — handlers génériques
  • EventDispatcherInterface — dispatch d'événements domain
  • MangaPathManagerInterface — gestion des chemins de fichiers
  • FileUploadInterface, NotificationInterface — services transverses

App\Domain\Shared ne dépend de personne (règle PHPArkitect).

Checklist avant de créer un fichier

  1. Dans quelle couche va ce fichier ? (Domain / Application / Infrastructure)
  2. Ce fichier va-t-il importer quelque chose d'interdit pour cette couche ?
  3. Si c'est une implémentation concrète → existe-t-il déjà une interface (port) dans Domain/Contract/ ?
  4. Si c'est une nouvelle interface → est-elle dans Domain/Contract/ et non dans Infrastructure ?
  5. Le binding alias est-il déclaré dans config/services.yaml ?

Vérification automatique : make phparkitect