VO-08 · Une valeur prise dans une liste connue a un type fermé
Signal
- Un statut, une devise ou un moyen de paiement typé
string. - Un value object qui enveloppe une telle valeur, mais ne vérifie que sa forme :
Currency.of('XYZ')passe, parce que le code a trois lettres majuscules.
Pourquoi
VO-01 donne un type au concept. Cette règle ferme ce type. Quand les valeurs possibles forment une liste connue, une valeur hors de la liste ne doit pas pouvoir exister, ni par une faute de frappe, ni par une donnée venue de l’extérieur.
Une instance en vaut une autre : on la remplace et on la compare par valeur.
Exceptions
Une liste tenue par un autre bounded context ou par un référentiel, qui change sans que le code change. Le type ne peut alors pas être fermé à la compilation : un value object fourni par un service de types standard vérifie la valeur à l’exécution. Décider dès le départ si la liste reste synchronisée.
Correction
Un type union, ou une classe à ensemble fixe d’instances, qui refuse toute valeur hors de la liste. Les libellés affichables, souvent traduits, restent dans la couche d’interface : le modèle ne connaît que les valeurs.
Adaptation
Les enum de TypeScript ne peuvent pas avoir de méthodes. Utiliser une union de types littéraux, ou une classe à ensemble fixe d’instances quand le type a besoin d’un comportement propre.
Notre choix : une union de types littéraux, déclarée dans le domaine (type WalletStatus = 'open' | 'closed'). Les règles qui la lisent sont des méthodes de l’aggregate ou d’un value object (SRV-01), jamais des fonctions libres. L’enum Prisma du schéma porte les mêmes valeurs (PER-02).
Voir aussi
VO-01 donne un type à chaque concept du domaine. VO-07 traite des objets venus d’un autre bounded context. La vue d’ensemble ferme la liste des devises : Currency.of() refuse un code hors de SUPPORTED_CURRENCIES.