Files
netslim-core/CONTRIBUTING.md
2026-03-20 22:13:41 +01:00

111 lines
5.1 KiB
Markdown

# Contribuer au projet
Ce dépôt fournit un socle partagé consommé par plusieurs applications. Une contribution doit préserver la stabilité du package, la lisibilité de son organisation et la clarté de son API publique.
## Avant de contribuer
Lire au minimum :
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) avant une évolution structurelle ;
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) pour le workflow quotidien ;
## Prérequis
Les mêmes que pour le développement (voir [README.md](README.md)).
## Vérifications attendues
Lancer au minimum :
```bash
composer test
composer stan
composer cs:check
```
Avec rapport de couverture (nécessite Xdebug ou PCOV) :
```bash
vendor/bin/phpunit --coverage-text
```
## Règles de contribution
### Mocks
Les services applicatifs utilisent les **interfaces** comme type des dépendances. Mocker l'interface plutôt que la classe concrète :
```php
// Correct
$repo = $this->createMock(UserRepositoryInterface::class);
// À éviter
$repo = $this->createMock(UserRepository::class);
```
Les tests de repository (`PdoUserRepository`, etc.) testent volontairement l'implémentation concrète avec un mock PDO. Ils doivent vérifier l'intention générale des requêtes et les valeurs retournées, sans figer inutilement les détails internes.
### Exceptions métier
Les erreurs métier doivent lever l'exception la plus spécifique disponible :
| Situation | Exception | Namespace |
|---|---|---|
| Nom d'utilisateur déjà pris | `DuplicateUsernameException` | `Netig\Netslim\Identity\Domain\Exception` |
| Email déjà utilisé | `DuplicateEmailException` | `Netig\Netslim\Identity\Domain\Exception` |
| Mot de passe trop court | `WeakPasswordException` | `Netig\Netslim\Identity\Domain\Exception` |
| Entité introuvable en base | `NotFoundException` | `Netig\Netslim\Kernel\Support\Exception` |
### Ajouter un test
- **Nommage** : `test` + description camelCase
- **Structure** : Arrange / Act / Assert
- **Isolation** : dépendances mockées via leurs interfaces
- **PHPDoc** : une ligne décrivant le comportement attendu quand cela apporte une vraie valeur
### Frontières à respecter
- **DI stricte dans `Application/` et `UI/`** : ne pas instancier directement de use case, policy, repository concret ou implémentation infrastructure dans un service applicatif ou un controller ;
- **Controllers minces** : un controller traduit HTTP vers l'application, puis convertit le résultat en réponse ou flash ;
- **UI → service uniquement** : un controller, request object ou composant UI ne référence ni `Application/UseCase/`, ni `Application/Command/` ;
- **ApplicationService = façade** : garder les lectures simples et la pagination dans le service applicatif, déléguer les mutations et workflows sensibles à des use cases ;
- **UseCase = action explicite** : un use case doit rester `final readonly`, porter un verbe clair et exposer une seule méthode publique `handle(...)` ;
- **Command = entrée immuable** : une command est un DTO `final readonly` placé dans `Application/Command/` ;
- **Commentaires et PHPDoc** : documenter les shapes, invariants et choix de runtime utiles ; garder les anglicismes techniques déjà utilisés par le projet au lieu de les retraduire ;
- **Modules auto-déclaratifs** : chaque module déclare ses définitions DI, ses routes, ses namespaces Twig et ses extensions Twig via son `<Domaine>Module.php` ;
- **Découplage inter-domaines** : lorsqu'un domaine expose un port à un autre, éviter de faire remonter ses structures internes.
### Checklist de review architecturale
Avant de valider une PR backend, vérifier rapidement :
- la `UI` parle bien au service applicatif, pas à un use case ;
- une mutation nouvelle ou sensible a bien été extraite en `UseCase` ;
- une `Command` a été introduite si elle clarifie l'entrée du workflow ;
- `Kernel/` n'a pas servi de raccourci pour ranger du code mono-domaine.
## Placement du code
Avant d'ajouter une classe dans `src/Kernel`, appliquer cette règle : **domain-first, kernel-last**.
Un élément a sa place dans `Kernel` uniquement s'il est réellement transverse, technique, ou réutilisé par plusieurs domaines. Si son sens reste principalement lié à un domaine métier, il doit rester dans ce domaine.
`Kernel/Support` est gelé par défaut : toute nouvelle entrée doit être justifiée comme réellement transverse, documentée dans `docs/ARCHITECTURE.md` et ajoutée explicitement à l'allow list des tests d'architecture. En cas d'hésitation, garder le code dans le domaine concerné.
Le bootstrap et l'infrastructure runtime doivent aussi rester découpés en étapes simples. Les composants transverses doivent respecter la séparation `Runtime / Http / Persistence|Mail|Html|Pagination|Support` : démarrage et composition dans `Runtime`, web dans `Http`, briques techniques dans les sous-modules transverses dédiés. Si un fichier de démarrage commence à porter plusieurs responsabilités distinctes, préférer extraire un composant ciblé plutôt que d'empiler de la logique.
## Formatage
Appliquer automatiquement :
```bash
composer cs:fix
```
Prévisualiser sans appliquer :
```bash
composer cs:check
```