Résultat final

Infrastructure générée,
application fonctionnelle.

  • Plugins JPA et REST configurés avec routage multi-module.
  • ~32 fichiers d'infrastructure générés automatiquement.
  • Score final 67/100, grade D, 0 violation.
Configuration

Configuration HexaGlue

Le fichier hexaglue.yaml à la racine du projet configure les quatre plugins actifs et déclare le rôle architectural de chaque module Maven.
Deux clés structurent la configuration : les exclusions de classification pour les packages hors périmètre DDD, et les rôles de modules qui permettent le routage du code généré.
hexaglue.yaml
classification:
exclude:
- "com.acme.banking.core.exception.*"
plugins:
io.hexaglue.plugin.jpa:
entitySuffix: "JpaEntity"
repositorySuffix: "JpaRepository"
adapterSuffix: "RepositoryAdapter"
generateRepositories: true
generateAdapters: true
generateEmbeddables: true
enableAuditing: false
targetModule: banking-persistence
outputDirectory: "src/main/java"
io.hexaglue.plugin.rest:
targetModule: banking-api
flattenValueObjects: true
generateExceptionHandler: true
generateConfiguration: false
io.hexaglue.plugin.livingdoc:
outputDir: "living-doc"
io.hexaglue.plugin.audit:
generateDocs: false
modules:
banking-core:
role: DOMAIN
banking-persistence:
role: INFRASTRUCTURE
banking-service:
role: APPLICATION
banking-api:
role: API
banking-app:
role: ASSEMBLY
  • targetModule: banking-persistence : tout le code JPA généré (entités, repositories, mappers, adapters) est routé vers le module de persistance dédié, sans polluer le domaine
  • targetModule: banking-api : les contrôleurs REST, DTOs et l'exception handler sont routés vers le module API
  • generateConfiguration: false : nécessaire ici car les ApplicationService sont définis dans banking-service. HexaGlue ne peut pas générer la configuration Spring dans un module qui ne voit pas ces services ; la configuration reste manuelle dans banking-app
  • Rôles de modules : DOMAIN, INFRASTRUCTURE, APPLICATION, API, ASSEMBLY permettent à HexaGlue de valider les règles d'isolation entre couches et de router la génération vers le bon module
Génération

Code généré automatiquement

Les plugins JPA et REST analysent le modèle domaine pur et génèrent toute la couche infrastructure à la compilation.
Aucun de ces fichiers n'est écrit à la main : le code JPA est produit dans banking-persistence, le code REST dans banking-api.

Plugin JPA → banking-persistence

Entités JPA

AccountJpaEntity, BeneficiaryJpaEntity, CardJpaEntity, CustomerJpaEntity, TransactionJpaEntity, TransferJpaEntity

6 fichiers
Embeddables

AddressEmbeddable, MoneyEmbeddable

2 fichiers
Spring Data Repositories

AccountJpaRepository, BeneficiaryJpaRepository, CardJpaRepository, CustomerJpaRepository, TransactionJpaRepository, TransferJpaRepository

6 fichiers
MapStruct Mappers

AccountMapper, BeneficiaryMapper, CardMapper, CustomerMapper, TransactionMapper, TransferMapper

6 fichiers
Repository Adapters

AccountRepositoryAdapter, BeneficiaryRepositoryAdapter, CardRepositoryAdapter, CustomerRepositoryAdapter, TransactionRepositoryAdapter, TransferRepositoryAdapter

6 fichiers

Plugin REST → banking-api

REST Controllers

AccountController, BeneficiaryController, CardController, CustomerController, TransferController

5 fichiers
DTOs (request / response)

Objets de transfert aplatis depuis les value objects domaine (flattenValueObjects: true)

~18 fichiers
Exception Handler

BankingExceptionHandler — gestionnaire global des erreurs domaine

1 fichier
Total généré ~32 fichiers
  • ~32 fichiers générés remplacent le code infrastructure manuel : 26 fichiers JPA (entités, embeddables, repositories, mappers, adapters) et environ 6 fichiers REST de base (controllers, exception handler), auxquels s'ajoutent les ~18 DTOs
  • 38 types domaine manuels restent : les agrégats, value objects, identifiants, ports et services applicatifs constituent l'architecture métier que HexaGlue analyse et ne génère pas
  • Synchronisation garantie : si le domaine évolue, toute la couche infrastructure est régénérée automatiquement à la compilation suivante, sans intervention manuelle

Rapport d'audit

Rapport d'audit final après génération automatique JPA et REST, purification des services et câblage des driven ports.

Verdict

Verdict de l'audit

Le score final est de 67/100, grade D, statut PASSED. L'architecture hexagonale et le DDD atteignent tous deux 100%. Le score est plafonné par les dimensions Dependencies et Coupling, qui mesurent les cycles de dépendances inter-packages.
67
/100
Grade D
PASSED
0
violations
0
critical
0
major
+53 pts
-36 viol.

Le statut PASSED reflète l'absence totale de violations architecturales. Le grade D traduit la qualité globale mesurée sur cinq dimensions.

  • Statut PASSED : aucune violation Blocker, Critical ou Major. Toutes les contraintes DDD et hexagonales sont respectées
  • Grade D (score ≥ 60) : DDD Compliance et Hexagonal Architecture sont au maximum (100%), mais Dependencies (0%) et Coupling (51%) plafonnent le score total. Ces dimensions mesurent les cycles de dépendances et le couplage entre packages, indépendamment de la conformité hexagonale
Score

Décomposition du score

Le score final de 67/100 reflète l'état de chaque dimension architecturale.
DDD Compliance et Hexagonal Architecture sont au maximum. Dependencies et Coupling, qui mesurent les cycles inter-packages, concentrent les points perdus.
DimensionScoreStatusDelta
DDD Compliance100%+91
Hexagonal Architecture100%+100
Dependencies0%=
Coupling51%+11
Cohesion68%+28
TOTAL67.85
  • DDD Compliance à 100% : tous les patterns tactiques DDD sont en place — agrégats avec identifiants typés, value objects, ports de domaine. Le modèle domaine est complet
  • Hexagonal Architecture à 100% : les services applicatifs sont des POJOs purs, chaque port dispose d'un adaptateur généré, les couches sont isolées sans aucune dépendance croisée
  • Dependencies à 0% : cette dimension pénalise les cycles de dépendances entre packages. Des cycles inter-packages subsistent dans la base de code, indépendamment de la qualité de l'architecture hexagonale
  • Coupling à 51% : le couplage inter-packages reste élevé car plusieurs bounded contexts partagent des types. Des identifiants typés réduiraient les références croisées entre agrégats
  • Cohesion à 68% : la concentration fonctionnelle des packages est satisfaisante mais pourrait progresser en regroupant les types par bounded context
Inventaire

Inventaire architectural

L'inventaire recense les composants du modèle domaine classifiés par HexaGlue à l'issue de la migration complète.
Il montre la répartition finale entre agrégats, ports et services applicatifs.
ComposantNombre
Aggregate Roots6
Entities0
Value Objects8
Identifiers6
Domain Events0
Application Services5
Driving Ports5
Driven Ports8
  • 6 Aggregate Roots : Account, Beneficiary, Card, Customer, Transaction, Transfer — chaque entité métier principale est un agrégat avec identifiant typé et frontières respectées
  • 8 Value Objects : les 4 enums (AccountType, CardType, TransactionType, TransferStatus) plus Money, Iban, Email et Address — le domaine exprime ses concepts sans primitives
  • 5 Driving Ports : les 5 use cases exposés par l'hexagone. FraudDetection et NotificationSender sont correctement classifiés comme driven ports (ports sortants)
  • 8 Driven Ports : les 6 repositories de persistence plus FraudDetection et NotificationSender — tous couverts par des adaptateurs générés ou câblés manuellement
Violations

Violations détectées

Aucune violation architecturale n'est détectée dans l'état final.
La génération automatique et la purification des services ont éliminé les 16 violations de l'étape précédente.
0 violation

Aucune violation détectée. Toutes les contraintes DDD et hexagonales sont respectées.

Le zéro violation résulte de la combinaison de trois actions menées lors des étapes précédentes :

  • Génération JPA : les adaptateurs générés couvrent correctement tous les driven ports, éliminant les violations port-coverage et layer-isolation
  • Génération REST : les contrôleurs et DTOs générés remplacent le code REST manuel, éliminant les violations adapter-coupling
  • Purification des services : la suppression des annotations @Service et le reclassement de FraudDetection et NotificationSender en driven ports éliminent les violations application-purity
Qualité

Métriques de qualité

Les métriques de qualité mesurent l'adhérence du code aux principes DDD et hexagonaux.
La pureté du domaine atteint 100%, mais le boilerplate technique reste élevé en raison du code généré.
MétriqueValeurStatus
Domain purity100.00%
Domain coverage52.63%
Aggregate boundary100.00%
Code boilerplate88.41%
Code complexity1.08
Adapter independence100.00%
  • domain.purity à 100% : le domaine ne contient aucune dépendance technique. Les agrégats, value objects et ports sont des POJOs purs Java
  • aggregate.boundary à 100% : tous les agrégats respectent leurs frontières. Aucune entité interne n'est exposée directement depuis l'extérieur
  • code.boilerplate à 88.41% (CRITICAL) : ce ratio inclut le code infrastructure généré par HexaGlue. Les entités JPA, mappers et DTOs sont techniques par nature ; le seuil de 50% est conçu pour le code domaine et ne s'applique pas directement à un projet multi-module avec génération active
  • adapter.independence à 100% : les adaptateurs générés ne dépendent pas les uns des autres et restent isolés dans leur module
  • code.complexity à 1.08 : la complexité cyclomatique moyenne est très faible, confirmant la lisibilité du code domaine pur
Packages

Stabilité des packages

L'analyse de stabilité positionne chaque package sur le graphe Abstractness / Instability.
Elle révèle les packages en Zone of Pain (stables mais concrets) et ceux bien positionnés sur la Main Sequence.
PackageCaCeIADZone
com.acme.banking.api.controller0201.000.000.00Main Sequence
com.acme.banking.core.model4800.000.001.00Zone of Pain
com.acme.banking.core.port.in11130.541.000.54Main Sequence
com.acme.banking.core.port.out14130.481.000.48Main Sequence
com.acme.banking.infrastructure.persistence0261.000.460.46Main Sequence
com.acme.banking.service.application0251.000.000.00Main Sequence
Ca = Afferent Coupling (dépendants)
Ce = Efferent Coupling (dépendances)
I = Instability (0 = stable, 1 = instable)
A = Abstractness (0 = concret, 1 = abstrait)
D = Distance (0 = optimal, > 0.7 = problème)
Zone = Position sur le graphe A/I
  • core.model en Zone of Pain (D=1.00) : ce package est très stable (Ca=49, Ce=0 — 49 packages en dépendent) mais totalement concret (A=0). Il concentre toutes les classes domaine. Cette position est attendue pour un modèle métier dense ; la résoudre impliquerait d'introduire des interfaces ou de découper par bounded context
  • core.port.in et core.port.out sur la Main Sequence : les ports sont abstraits (A=1.00) et correctement positionnés. Ils constituent l'hexagone au sens strict
  • infrastructure.persistence, service.application, api.controller : ces packages sont instables (I=1.00) — aucun package ne dépend d'eux. C'est la position correcte pour les couches externes : elles dépendent du domaine et ne sont pas dépendées
Remédiation

Plan de remédiation

Aucune action de remédiation n'est requise à l'issue de la migration.
Toutes les violations architecturales ont été résolues. Le plan de remédiation est vide.
0 action requise

Aucune violation à corriger. L'architecture hexagonale est conforme aux contraintes DDD et hexagonales définies.

Bilan

Avant vs Après

Comparaison entre l'application legacy (étape 0) et l'architecture hexagonale finale.
Les chiffres montrent ce que la migration apporte concrètement : suppression de la dette technique, ajout des patterns DDD, et génération automatique de l'infrastructure.
CritèreLegacyHexagonal
Classes manuelles~4538
Infrastructure générée0~32
JPA dans le domaineOuiNon
Value Objects08
Identifiants typés06
Driving Ports05
Driven Ports08
Score architecturalN/A67/100
Retours

Enseignements

Les leçons clés tirées de cette migration, issues directement des rapports HexaGlue et des observations à chaque étape.

Le domaine doit être pur

La suppression des annotations JPA du domaine est le point d'inflexion. Tant que le domaine contient du code technique, HexaGlue ne peut pas générer l'infrastructure correctement.

Multi-module et routage par module

targetModule route le code généré vers le bon module. Le mode reactor analyse tous les modules en une seule passe. Les ports définis dans banking-core sont vus par tous les plugins.

Convention reconstitute()

La factory method reconstitute() est indispensable pour que les mappers générés puissent restaurer les agrégats depuis la persistance, sans compromettre l'encapsulation du domaine.

Migration incrémentale

Chaque étape compile. Les rapports d'audit guident l'étape suivante. Pas de Big Bang : le score progresse de 14 à 67/100 de manière incrémentale.

Le score est un indicateur fidèle

67/100 avec 0 violation montre une architecture hexagonale bien structurée. Dependencies (0%) et Coupling (51%) signalent des cycles inter-packages, un axe d'amélioration distinct de la conformité hexagonale.

Infrastructure sans code manuel

~32 fichiers générés remplacent l'infrastructure manuelle. Le coût de l'architecture hexagonale est absorbé par la génération automatique : entités JPA, repositories, mappers, adapters, controllers et DTOs.

Une architecture hexagonale opérationnelle.
Un socle solide pour aller plus loin.

L'application bancaire multi-modules est passée de 14/100 à 67/100, avec 0 violation et DDD + Hexagonal à 100%.