ADR-0006: Monorepo, contract-first, single version policy
Status: Accepted · Date: 2026-10-19
Decision (adapted from Google monorepo practice to Gradle)
- One repo, trunk-based. Small, reviewed changes to
main, guarded by a presubmit (./gradlew presubmit). - Contracts are first-class source under
api/, owned via CODEOWNERS. Server interfaces and client models are generated at build time and never committed. A contract change is a reviewed diff in YAML. - Single version policy: every third-party version lives in
gradle/libs.versions.toml, aligned through the Spring Boot BOM. Modules never declare versions. - Shared build logic in
build-logic/convention plugins, the Gradle equivalent of Bazel macros. - Small modules with explicit dependencies:
libs/(nomain) vsservices/(deployables). Dependencies point inward only. - One formatter: google-java-format via Spotless, enforced in presubmit.
- Hermetic tests: Postgres and the wallet stub run in containers (Testcontainers). No shared environments in CI.
- One stub, two uses:
stubs/wallet-wiremock/mappingsserve both docker-compose and tests.
Consequences
- + Atomic cross-cutting changes (contract + client + service + stub in one PR).
- − Gradle is not Bazel: build-graph visibility is enforced by review and CODEOWNERS, not by the build tool.