Skip to content

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/ (no main) vs services/ (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/mappings serve 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.