Skip to main content
Version: V2-Next

Code Style

This page defines mandatory architecture and style rules for Model Forge.

Layers​

Host application call
↓
ModelForge facade – contract mapping, input validation, diagnostics → exceptions
↓
Service – Domain logic, orchestration, transactions
↓
Port / Adapter – Infrastructure (PostgreSQL artifact registry, XRepository/HTTP clients, in-memory cache)
↓
Contract – public records: commands, results, queries (Java records)

Rules:

  • The facade contains no domain logic — only contract mapping and delegation
  • Services inject no web or transport artifacts (HttpServletRequest, ResponseEntity) — the library modules stay free of org.springframework.web
  • Infrastructure details (URLs, retries, encoding) belong in adapter/client classes, not in services

ArchUnit tests (architecture/*ArchitectureTest in model-forge-contract and per-slice tests inside model-forge-runtime for the core, application, integrations and persistence packages) enforce these boundaries — the contract stays transport- and infrastructure-free, the facade depends only on the contract and the application port layer, and core/application never depend on web, servlet, SQL or persistence types — and violations fail the build.

Obligations per class​

ClassJavadocMagic-string ban
Every public class✓ mandatoryprivate static final constants
Every @Service bean✓–

Forbidden patterns​

// ✗ Forbidden: a new HttpClient per call inside a method
HttpResponse<String> r = HttpClient.newHttpClient().send(request, BodyHandlers.ofString());

// ✓ Correct: HttpClient as a field, built once in the constructor
private final HttpClient http;

// ✗ Forbidden: fully qualified class names in method bodies
tools.jackson.databind.ObjectMapper om = new tools.jackson.databind.ObjectMapper();

// ✓ Correct: import + injection via constructor
private final ObjectMapper mapper; // injected

// ✗ Forbidden: web/transport types outside the adapter packages
import org.springframework.web.client.RestClient; // in contract/core/application → ArchUnit fails the build

// ✓ Correct: HTTP and SQL live in the adapter packages (integrations, persistence)

// ✗ Forbidden: var with a type that is not immediately evident
var result = someService.getStuff();

// ✓ Allowed: var only when the type is directly evident from the right-hand side
var mapper = new ObjectMapper(); // clear: ObjectMapper

Magic strings / numbers → constants​

// ✗
String sql = "select * from artifact where artifact_type = 'element'";

// ✓
private static final String ARTIFACT_TYPE_ELEMENT = "element";
private static final String SELECT_BY_TYPE =
"select * from artifact where artifact_type = ?";

Error handling​

  • No generic catch (Exception e) { return empty; } without log output
  • Distinguish caller errors from backend failures clearly: bad input surfaces as a validation error (IllegalArgumentException, or a ValidationFailedException carrying diagnostics), an unexpected infrastructure failure as an IllegalStateException / domain-level upstream-failure exception — never collapse both into one generic failure
  • Optional.empty() signals "not found"; no exceptions for the normal case

Known technical debt​

IDDescriptionStatus / Impact
TD-005Cross-artifact search returns a bare List<ArtifactSummary> from ModelForge.search(ArtifactSearchQuery)Accepted: offset/limit paging on the facade query is deliberate

Automated checks​

ToolPurposeWhere
SpotlessWhitespace hygiene (trailing whitespace, final newline)Maven verify
SpotBugsStatic bug analysis over all modules' main bytecode; build fails on findingsMaven verify
JaCoCoCoverage agent + report in model-forge-contract only — no hard coverage gate, the build does not fail on coverageMaven verify
ArchUnitLayer dependencies, no package cyclesTest suite
commitlintConventional-commit messagesRepo-wide concern — not run per module (no lefthook.yml in the Model Forge module)

SpotBugs runs at effort=Max / threshold=Medium (configured once in the parent pom.xml, so all modules are analysed) and fails the build on any finding at or above that confidence. Idiomatic/framework false positives — record EI_EXPOSE_REP* on Jackson-serialised payloads and EI_EXPOSE_REP2 on Spring beans storing injected collaborators — are scoped out in the repo-level spotbugs-exclude.xml, each entry justified inline. Genuine bugs are fixed in the code rather than excluded.

Checkstyle/SonarQube remain candidates for future automation; the Javadoc obligations above are currently enforced through code review.

Quality reviews​

The mandatory style rules above are enforced by the automated checks and by code review. The broader, periodic code- and architecture-quality review — covering correctness, design, security, tests, documentation, dependencies, minimalism and architectural aesthetics, with its own report structure and process — has its own rubric: see Code Review.