🔴 Your architecture rules are dying in Confluence. Here's how to make them bite back.
Source: Dev.to
The 3‑Step Process
Step 1 — Copy your arch rules from Confluence/Wiki
Just grab the raw text. It doesn’t need to be perfectly formatted.
Example rules I copied
-
Classes extending a parent must use the parent name as suffix
e.g.,CacheDataProvider extends DataProvider✅ -
No string literals inside methods — use static final class members
e.g.,static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"✅ -
Controllers must live under
*.controller.*package only -
Domain objects must NOT be instantiated with
newinside methods
e.g.,new CacheHelper()inside a method ❌
Step 2 — Feed them to Claude Code with this prompt
Open Claude Code and paste the following prompt:
You are an expert Java architect specializing in ArchUnit — a Java library for checking architecture rules as unit tests.
You will receive architecture rules in plain english format and must convert it into a complete, compilable ArchUnit JUnit5 test class.
Rules:
A. Class must have parent class name as suffix while extending.
Ex: class CacheDataProvider when extends DataProvider
B. No string literals inside a method, always have static final class member.
Ex: String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
C. Package Naming Conventions like edu.pk.demo.archunit.controller.*
D. Method should not create domain object locally using "new" keyword.
Ex: final CacheHelper cacheHelper = new CacheHelper();
Requirements:
- Use @AnalyzeClasses(packages = "edu.pk.demo.archunit") # Use your project package name
- One @ArchTest per rule, named descriptively
- Use ArchUnit's fluent API (classes(), noClasses(), methods())
- Add a brief comment above each test explaining the rule intent
- Base package: edu.pk.demo.archunit
ArchUnit API Reference
- Class-level setup:
@AnalyzeClasses(packages = "com.example", importOptions = ImportOption.DoNotIncludeTests.class)
public class MyArchTest { ... }
- Rule declaration (always static final):
@ArchTest
static final ArchRule ruleName = ...;
- Fluent API for common patterns:
# CONTAINMENT (CONTAINED WITHIN / CONTAINS):
classes()
.that().resideInAPackage("com.example..")
.should().resideInAnyPackage("com.example.domain..", "com.example.service..")
.as("...").because("...");
# NO DEPENDENCY ON:
noClasses()
.that().resideInAPackage("com.example.web..")
.should().dependOnClassesThat().resideInAPackage("com.example.db..")
.as("...").because("...");
# CYCLE FREE:
slices()
.matching("com.example.(*)..")
.should().beFreeOfCycles();
# MUST USE LIBRARY (CONTAINS library):
classes()
.that().resideInAPackage("com.example.api..")
.should().dependOnClassesThat().resideInAPackage("com.security..")
.as("...").because("...");
Output Rules:
- Output ONLY valid Java source code
- No markdown code fences
- No explanation text before or after the class
- Full import statements required
- Class must be immediately runnable with ArchUnit + JUnit5 on the classpath
Step 3 — Drop the generated tests into your project and run
Claude generates something like this:
@AnalyzeClasses(packages = "edu.pk.demo.archunit")
public class ArchitectureRulesTest {
// Rule: Subclass name must end with the parent class simple name
@ArchTest
static final ArchRule subclassesShouldUseSuperclassNameAsSuffix =
classes()
.that().areAssignableTo(DataProvider.class)
.should().haveSimpleNameEndingWith("DataProvider")
.because("Subclasses must use the parent class name as suffix for discoverability");
// Additional rules would follow here …
}
Why this matters
Architecture drift happens because rules live in documents, not in pipelines.
When you encode rules as tests:
- ✅ Every PR is verified automatically
- ✅ New developers can’t accidentally break conventions
- ✅ Architecture decisions are self‑documenting in code
- ✅ No more “we agreed not to do this” code‑review comments
The best part? Claude Code handles the ArchUnit API fluency. You just describe what you want to enforce — it figures out how to write it.
Your architecture doc shouldn’t be a suggestion. Make it a compiler error.
Have you automated architecture enforcement in your team? What rules do you wish you’d enforced from day one? Drop them below 👇.