Présentation
Des règles courtes et vérifiables pour un backend TypeScript / NestJS, appliquées en revue de code et en CI. Elles couvrent deux choses : comment modéliser le métier avec le Domain-Driven Design, et où placer chaque morceau de code.
- Une règle = un signal à chercher dans le code, pourquoi c’est un problème, ses exceptions et la correction attendue.
- Chaque règle a un code stable (
AGG-06) à citer dans une revue, un commit ou un waiver. - Les règles sont regroupées par thème, chacun avec son préfixe, et les thèmes par partie.
Quatre parties
| Partie | Ce qu’elle protège |
|---|---|
| Conception stratégique | Les frontières : un langage par contexte, des relations déclarées entre contextes. |
| Logique du domaine | Les règles métier à l’intérieur d’un contexte : un modèle tactique pour le core, des transaction scripts pour les contextes supporting et generic. |
| Architecture et placement | L’organisation du code : couches, dépendances, rôles de fichiers, wiring, et ce qui va où. |
| Intégration | Les échanges entre contextes : des appels, des messages et des contrats qui résistent au changement. |
Les parties s’appuient les unes sur les autres : un modèle vit dans un contexte, l’architecture découpe le code de chaque contexte, et l’intégration relie des contextes dont les frontières sont déjà claires.
Lire une règle
Toutes les règles suivent le même format.
Sections
| Section | Contenu |
|---|---|
| Signal | Ce qu’il faut chercher dans le code. |
| Pourquoi | Ce que cela coûte si cela passe. |
| Exceptions | Les cas où le signal n’est pas un défaut. |
| Correction | La correction attendue. |
| Adaptation | Facultative. Ce qui est propre à TypeScript et à NestJS. Un paragraphe Notre choix donne le choix par défaut d’Alveolus (voir les choix par défaut). |
| Voir aussi | Facultative. Le lien avec une règle voisine, et comment éviter de signaler deux fois la même chose. |
| Exemple | Facultative. Le code à éviter et le code attendu. |
Chaque règle déclare aussi son périmètre : les parties du code qu’elle vise (domain, application, driving, driven, public, schéma, tests, structure). Les noms de dossiers renvoient à l’architecture de référence.
Une règle peut aussi porter un contexte : elle ne s’applique alors que si le bounded context a adopté le style correspondant (multi-tenant…), par une décision enregistrée. Sinon, on l’ignore.
En haut de la page, une fiche résume la sévérité, le mode de détection, et le périmètre. Les termes gardés en anglais sont dans le glossaire.
Sévérité
| Sévérité | Sens | Attendu en revue |
|---|---|---|
| bloquante | Le code peut corrompre l’état ou casser un invariant en production. | Corriger avant de merger. |
| majeure | Le modèle ne garantit plus ses règles, ou le couplage coûtera cher. | Corriger avant de merger, sauf waiver documenté. |
| mineure | Un écart de conception, à faible risque immédiat. | Corriger la prochaine fois que le code est touché. |
| question | Pas un défaut en soi : une décision à rendre explicite avec le métier ou l’auteur. | Poser la question et consigner la réponse. |
Certaines règles nuancent leur sévérité selon le contexte (par exemple « bloquante si deux écritures concurrentes peuvent casser un invariant, majeure sinon »). La nuance apparaît sous le badge.
Waivers
Plusieurs règles admettent une exception « à documenter ». Un waiver se signale par un commentaire sur la ligne concernée, qui cite le code de la règle et la raison. Comme tout le code, ce commentaire est en anglais : le mot-clé est waiver.
// waiver AGG-03: <reason>, see ADR-NNNNQuand le waiver touche l’architecture ou plusieurs fichiers, il s’appuie aussi sur une ADR, citée dans le commentaire. Une recherche de waiver [A-Z]+-[0-9]+ trouve ainsi tous les waivers, en revue comme en CI.
Exemples
La présentation de chaque thème le montre sur un court exemple, avec des notions bancaires courantes : de l’argent, un wallet, un solde, un dépôt, un retrait. La partie conception stratégique s’appuie sur une petite context map des services d’un établissement de paiement.
Par où commencer
- Découvrir le code : l’architecture de référence, puis la logique du domaine.
- Relire un changement : l’index de toutes les règles, filtrable par partie, thème, périmètre, sévérité et détection.
- Mettre en place un projet : mettre en place un projet (context map, glossaire, ADR, CODEOWNERS, outillage), l’architecture de référence et les choix par défaut, puis architecture et placement.
Thèmes
Conception stratégique
CTX16 règlesBounded contextsUn langage par bounded context, un sens par terme, une frontière par langage.Voir les règles →MAP4 règlesContext mapsDes relations déclarées entre bounded contexts, et un code qui les respecte.Voir les règles →Logique du domaine
TXS8 règlesTransaction scriptsUne procédure par use case, dans une transaction, pour les bounded contexts supporting et generic.Voir les règles →AGG16 règlesAggregatesDe petites frontières de cohérence autour de vrais invariants.Voir les règles →ENT17 règlesEntitiesUne identité stable et des méthodes métier nommées.Voir les règles →VO11 règlesValue objectsDes valeurs immuables qui portent leur propre logique.Voir les règles →EVT7 règlesDomain eventsDes faits métier, nés dans le modèle et nommés dans le langage.Voir les règles →REP16 règlesRepositoriesDes aggregates entiers, écrits dans la transaction du use case.Voir les règles →FAC4 règlesFactoriesUne création maîtrisée, nommée dans le langage métier.Voir les règles →SRV8 règlesDomain servicesCe qui n’appartient à aucun objet : sans état, nommé dans le langage métier.Voir les règles →Architecture et placement
LAY4 règlesCouches et dépendancesUn domaine isolé, des dépendances tournées vers l’intérieur, sans cycle, et le contrat public pour seule porte.Voir les règles →PLC12 règlesCe qui va oùUne place évidente pour chaque morceau de code, un module par concept.Voir les règles →NAM8 règlesNommage et rôles de fichiersUn fichier dit son rôle dans son nom, un dossier son concept.Voir les règles →WIR11 règlesWiringL’assemblage en périphérie, sans framework dans le modèle.Voir les règles →UC10 règlesUse casesUne opération par use case, mince, sécurisée, une command ou une query.Voir les règles →API2 règlesAPI HTTPDes routes et des représentations qui n’exposent pas le modèle.Voir les règles →PER12 règlesPersistanceSchémas, mappers et transactions tenus hors du modèle.Voir les règles →TST6 règlesTestsDes tests placés selon ce qu’ils prouvent, sur une infrastructure réelle.Voir les règles →Intégration
PUB7 règlesContrats et published languageUn contrat documenté, séparé du modèle, lu avec tolérance.Voir les règles →ACL4 règlesTraduction et données étrangèresUne seule anticorruption layer, le minimum traduit, des copies dont on assume la synchronisation.Voir les règles →MSG7 règlesMessagerieDes events enregistrés avec l’état, transmis dans l’ordre, consommés une seule fois.Voir les règles →PRC6 règlesAppels distants et processusDes appels prudents, des processus explicites, pas de modèle caché entre bounded contexts.Voir les règles →