ddd-ts-kit/declarations-role-declared
Identifiant d'architecture : declarations/role-declared. Sévérité par défaut : error dans recommended, error dans strict.
S'applique à : chaque fichier d'un contexte dans un projet de style déclaré (stack.style: "declared" dans ddd-ts-kit.config.json), tests exclus. Rien n'est signalé dans un projet de style explicite, qui est aussi ce qu'est une configuration qui ne dit rien.
Pourquoi
Section intitulée « Pourquoi »Dans le style déclaré, un contexte n'a pas de fichier de module : une classe dit ce qu'elle est par un décorateur de @ddd-ts-kit/kernel/declarations, et la racine de composition est assemblée à partir de ce que disent les classes. Un fichier de rôle dont la classe ne dit rien n'entre dans aucun assemblage : le gestionnaire (handler) n'est jamais enregistré et la première commande échoue à l'exécution. Un nom dérivé au lieu d'être écrit change quand une classe est renommée, et avec lui la portée d'idempotence d'un consommateur. Un décorateur dans le domaine lie le modèle au câblage.
Dans un fichier de rôle (le tableau ci-dessous), hors *.command.ts et *.query.ts, que tient authz-declared :
- aucune classe exportée ne porte le décorateur du rôle
- une classe du fichier porte un autre décorateur de déclaration que celui du rôle
Sur toute classe de application/, infrastructure/, presentation/ ou de la racine du contexte :
@IntegrationEventHandler(definition, { consumer })ou@Policy(permission, { name })dont le nom n'est pas un littéral de chaîne non vide : absent, vide, une variable, un gabarit avec une substitution, des options contenues dans une variable ou seulement étalées.@DomainEventHandler(Event)n'écrit aucun nom : il est rattaché à celui que sa classe d'événement déclare une fois,static readonly eventName, que le compilateur exige
Sous domain/ :
- une classe qui porte un décorateur de déclaration quel qu'il soit :
Requires,Public,CommandHandler,QueryHandler,IntegrationEventHandler,DomainEventHandler,Scheduled,Projection,Repository,Gateway,Adapter,Policy
| Fichier, relatif au contexte | La classe exportée porte |
|---|---|
application/commands/**/*.handler.ts |
@CommandHandler |
application/queries/**/*.handler.ts |
@QueryHandler |
application/integration/handlers/**/*.integration-handler.ts |
@IntegrationEventHandler |
application/event-handlers/**/*.event-handler.ts |
@DomainEventHandler |
application/integration/publishers/**/*.publisher.ts |
@DomainEventHandler |
application/authorization/**/*.policy.ts |
@Policy |
application/scheduling/**/*.job.ts |
@Scheduled |
application/projections/**/*.projection.ts |
@Projection |
infrastructure/persistence/**/*.repository.ts |
@Repository |
infrastructure/**/*.gateway.ts |
@Gateway |
infrastructure/**/*.adapter.ts |
@Adapter |
Incorrect :
export class IssueInvoiceHandler {}
// application/queries/search-invoices/search-invoices.handler.ts@CommandHandler(SearchInvoicesQuery)export class SearchInvoicesHandler {}
// application/authorization/only-issuer-voids.policy.ts@Policy(billingPermissions['invoice.void'], { name: policyName })export class OnlyIssuerVoidsPolicy {}
// domain/aggregates/invoice.aggregate.ts@Repository(InvoiceRepository)export class Invoice {}Correct :
import type { Clock } from '@ddd-ts-kit/kernel';import { CommandHandler } from '@ddd-ts-kit/kernel/declarations';import type { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository';
@CommandHandler(IssueInvoiceCommand)export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> { constructor( private readonly invoices: InvoiceRepository, private readonly clock: Clock, ) {}}
// application/authorization/only-issuer-voids.policy.ts@Policy(billingPermissions['invoice.void'], { name: 'billing.only-issuer-voids' })export class OnlyIssuerVoidsPolicy {}
// application/event-handlers/invoice-issued.event-handler.ts@DomainEventHandler(InvoiceIssued)export class InvoiceIssuedEventHandler {}Un décorateur compte quand son nom est l'un des douze décorateurs de déclaration et que ce nom est importé de @ddd-ts-kit/kernel/declarations dans le fichier : { Repository }, un alias { Repository as Repo }, ou un espace de noms declarations.Repository. Un décorateur maison du même nom, ou celui d'un autre package (@Retry de @ddd-ts-kit/aspects/decorators), est ignoré.
Le rôle d'un fichier se lit à son suffixe et à son dossier, tels que le générateur les écrit. Une classe est exportée en ligne, par export { A } ou par export default A. Quand une classe porte un autre décorateur de déclaration, seul celui-ci est signalé : le corriger répond aussi au décorateur manquant.
Aucune.
rules."declarations/role-declared" à off dans ddd-ts-kit.config.json désactive la règle, et // ddd-ts-kit-disable-next-line declarations/role-declared -- <reason> désactive une ligne, exactement comme pour ddd-ts-kit check.
- Un décorateur appliqué par une variable (
const declare = Repository(InvoiceRepository); @declare class ...) n'est pas reconnu. - Ce qu'une classe reçoit relève de
declarations/constructor-injection; qu'une liste corresponde au constructeur et qu'un gestionnaire traite son message est vérifié par le compilateur, pas ici ; qu'un adaptateur implémente son port relève deports/implements-never-extends, et l'endroit où vit un job et son nom relèvent descheduling/job-triggers-use-caseet descheduling/job-name. - Que chaque fichier de rôle contienne une seule classe déclarée relève de
naming/one-concept-per-filededdd-ts-kit check. - Que le barrel généré
<context>.declarations.tsliste chaque fichier de rôle relève dedeclarations/barrel-currentdeddd-ts-kit check: c'est un fait du projet, pas d'un fichier. - Un fichier de rôle écrit hors des dossiers du tableau n'est pas reconnu comme tel :
naming/suffixettree/closeddeddd-ts-kit checktiennent l'arborescence. - Le
consumernon écrit de@IntegrationEventHandlerest aussi signalé parevents-consumer-idempotent, pour ce qu'il coûte à l'exécution.
Avec le checker de la CLI
Section intitulée « Avec le checker de la CLI »ddd-ts-kit check signale le même identifiant à partir du texte des fichiers et reste le garde-fou rapide pendant l'écriture. Cette règle fait autorité.