111 lines
5.1 KiB
Markdown
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
|
|
```
|