Architecture
ADR-004 Enforce modular boundaries with ArchUnit
Status
Accepted
Context
The codebase is a modular monolith: many bounded contexts in one repository. Without enforcement, package dependencies creep across boundaries (“just one import”), cycles appear, and refactors become risky.
Decision
Use ArchUnit in ArchitectureTest to enforce:
- No cycles between top-level slices matching
com.jongsoft.finance.(*).. - Layering against the PlantUML diagram
src/test/resources/architecture/layer-design.puml(generated API, REST adapters, domain layers, JPA) - Explicit module layers for major domains (
core,banking,budget,classification,contract,spending,exporter,suggestion) with documented allowed dependencies
spendingmay accesscore,banking, andbudget(reads transactions and budgets via ports and shared domain types; no dependency onexporterorsuggestion).- Other modules must not depend on
spending.
CI and local ./gradlew test must keep these rules green.
Consequences
- Positive: Architectural intent is executable; violations fail the build instead of silently accumulating.
- Positive: The PlantUML diagram stays tied to reality via automated checks.
- Negative: New cross-module dependencies require updating tests (and often an ADR) rather than quick fixes.
- Negative: Packages outside the listed modules (for example
configuration, rootEventBus) still rely on manual discipline unless rules are extended.
Last modified on July 4, 2026
Edit this page on GitHub