feat: add architecture tests for enforcing module boundaries
Integrated a new `:platform:architecture-tests` module using ArchUnit to enforce backend and frontend architecture rules. Configured explicit dependencies to all relevant modules and implemented rules to prevent cross-dependencies between backend services and frontend features. Replaced legacy Gradle-based architecture guards with this robust solution. Updated CI pipeline to include these tests.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
---
|
||||
type: Journal
|
||||
status: COMPLETED
|
||||
owner: Curator
|
||||
date: 2026-01-29
|
||||
participants:
|
||||
- Lead Architect
|
||||
- DevOps Engineer
|
||||
- Curator
|
||||
---
|
||||
|
||||
# Session Log: 29. Jänner 2026 - Etablierung robuster Architektur-Guards mit ArchUnit
|
||||
|
||||
## Zielsetzung
|
||||
Etablierung eines robusten, wartbaren und zentralisierten Systems zur Überprüfung und Erzwingung der Projekt-Architekturregeln, insbesondere der Trennung zwischen Modulen (Features, Services).
|
||||
|
||||
## Durchgeführte Arbeiten
|
||||
|
||||
### 1. Strategische Entscheidung
|
||||
* **Problem:** Die Notwendigkeit, die modulare Trennung (z.B. zwischen Frontend-Features und Backend-Services) technisch zu erzwingen, wurde als kritisch für die Langlebigkeit des Projekts identifiziert.
|
||||
* **Analyse:** Die bestehenden, skriptbasierten Gradle-Tasks (`archGuard...`) wurden als clever, aber fragil und nicht universell genug bewertet.
|
||||
* **Entscheidung:** Es wurde beschlossen, auf **ArchUnit** als zentrales, typsicheres Werkzeug für die Architektur-Verifizierung zu migrieren.
|
||||
|
||||
### 2. Implementierung (Iterativer Prozess & Fehlerbehebung)
|
||||
Die Implementierung war ein mehrstufiger Prozess, der mehrere Herausforderungen aufdeckte:
|
||||
|
||||
1. **Modul-Erstellung:** Ein neues Modul `:platform:architecture-tests` wurde erstellt und die ArchUnit-Abhängigkeiten (Version `1.4.1`) wurden im zentralen Versionskatalog `gradle/libs.versions.toml` deklariert.
|
||||
|
||||
2. **Abhängigkeits-Problem:** Der erste Versuch, die Abhängigkeiten dynamisch zu sammeln (`rootProject.subprojects.filter`), schlug fehl, da er versuchte, nicht-baubare Verzeichnis-Module (z.B. `:backend`) einzubinden.
|
||||
* **Lösung:** Umstellung auf eine explizite, manuelle Liste von `implementation(project(":..."))`-Abhängigkeiten in der `build.gradle.kts` des Test-Moduls.
|
||||
|
||||
3. **Klassen-Auffindungs-Problem:** Die ersten Test-Implementierungen schlugen mit der Meldung `Rule '...' failed to check any classes` fehl. Dies lag an einer Kombination aus falschen Paket-Mustern und einer inkorrekten Konfiguration des ArchUnit-Klassen-Imports.
|
||||
* **Lösung:** Die finale, robuste Lösung besteht darin, die `@AnalyzeClasses`-Annotation in den Testklassen zu verwenden und den `packages`-Parameter auf das Root-Package (`at.mocode`) zu setzen. Dies stellt sicher, dass ArchUnit den gesamten relevanten Classpath scannt, der von Gradle durch die expliziten Abhängigkeiten bereitgestellt wird.
|
||||
|
||||
4. **Syntax-Korrekturen:** Mehrere Iterationen waren nötig, um die korrekte Syntax für die ArchUnit-Regeln (insbesondere `slices().matching(...)` und die Paket-Identifier) zu finden.
|
||||
|
||||
### 3. Finale Konfiguration
|
||||
|
||||
* **`build.gradle.kts` (`:platform:architecture-tests`):** Enthält eine explizite, manuell gepflegte Liste von Abhängigkeiten zu allen Modulen, die Code enthalten.
|
||||
* **`FrontendArchitectureTest.kt`:** Verwendet `@AnalyzeClasses(packages = ["at.mocode.frontend"])` und die Regel `slices().matching("..frontend.features.(*)..").should().notDependOnEachOther()`.
|
||||
* **`BackendArchitectureTest.kt`:** Verwendet `@AnalyzeClasses(packages = ["at.mocode.backend"])` und eine explizite `noClasses()..`-Regel, da die Backend-Services keine einheitliche Paketstruktur haben.
|
||||
* **`README.md`:** Eine neue `README.md` wurde im Modul erstellt, um dessen Zweck und Verwendung zu dokumentieren.
|
||||
|
||||
## Ergebnis & Status
|
||||
* **BUILD SUCCESSFUL:** Die Architektur-Tests kompilieren und laufen erfolgreich durch.
|
||||
* **Keine Verletzungen gefunden:** Die bestehende Codebasis ist sauber und verstößt nicht gegen die neu aufgestellten Regeln.
|
||||
* Das Projekt verfügt nun über ein zentrales, robustes und erweiterbares System zur Durchsetzung von Architektur-Regeln, das in der CI-Pipeline ausgeführt wird.
|
||||
* Die alten `archGuard`-Tasks wurden aus der Root-Build-Datei entfernt.
|
||||
Reference in New Issue
Block a user