feat(mongodb): implement the MongoDB document persistence platform
Implements the mongodb-superpowers-package design: Stable Tasks 1-50 and Advanced Tasks 1-15. The design assumes 19 Stable + 12 Advanced Gradle projects under modules/mongodb*. This repository's fail-closed registry declares exactly 19 leaf identities, so those modules become package boundaries inside the registered leaf :adapter:outbound:persistence-mongo, with the design's module dependency table enforced by ten ArchUnit rules. The mapping and every deviation are recorded in docs/mongodb/repository-adaptation.md. Contract highlights, all enforced by tests rather than convention: - Transaction body retry and commit retry are separate loops. A new session per body attempt; commit-only retry on an unknown commit. The body is never replayed after a commit ambiguity, so a failover cannot become a duplicate. - MongoExecutionOutcome keeps both ambiguous outcomes distinct from success and failure, and MongoFailureContext records only the design-permitted fields. - Failure classification reads server error labels before numeric codes. - BSON representations come from a pinned manifest, never a library default, and a golden type-signature gate fails on any drift. - Index and validator changes go through the manifest and the admin plane; metadata ownership gates every drop. - Every Advanced capability refuses construction unless its flag is enabled. Verified against real servers, not only unit tests. Running the lanes for the first time exposed four defects that a green `check` had hidden: - Four release lanes passed while executing zero tests; the gate now counts executed tests per lane and fails on zero. - The "single replica set" fixture was a standalone, because Testcontainers 2.x needs withReplicaSet(); its test only asserted a connection string. - The three-node fixture was three independent clusters, so no election could occur, and awaitNewPrimary() compared against the post-stop primary. - The migration lease checked modifiedCount, so a same-millisecond refresh read as a lost lease. scripts/verify-mongodb-platform.sh now reports: 9 lanes, 0 skipped, 0 failed, every evidence category produced. scripts/verify-mongodb-advanced.sh reports NOT PROMOTABLE: actual-topology evidence (real sharded cluster, real KMS, real target deployment) is unobtainable here, so it is named rather than assumed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3b5aee50e3
commit
d57d2f62a0
@@ -8,27 +8,34 @@
|
||||
- Runtime baseline: Java 21; repository framework baseline: Spring Boot 4.0.0.
|
||||
- Registry SSOT: `src/config/architecture/modules.json`.
|
||||
|
||||
Package root: `dev.caskeleton.adapter.outbound.mongo`. Driven (outbound) adapter — opt-in Spring
|
||||
Data MongoDB infrastructure. Design rationale lives in [README.md](README.md).
|
||||
Package root: `dev.caskeleton.adapter.outbound.mongo`. Driven (outbound) adapter — opt-in MongoDB
|
||||
Document Persistence Platform. Design rationale lives in [README.md](README.md); the mapping from the
|
||||
design package's assumed module layout onto this leaf lives in
|
||||
`docs/mongodb/repository-adaptation.md` and is the file to update when that mapping changes.
|
||||
|
||||
## Responsibility
|
||||
|
||||
- Provide opt-in Mongo client and template infrastructure without shipping a fake business domain.
|
||||
- Real forks add their own document, repository, mapper, and application/domain port implementation.
|
||||
- Provide the opt-in Mongo client, template and **platform policy** surface without shipping a fake
|
||||
business domain. Real forks add their own document, repository, mapper, and application/domain port
|
||||
implementation.
|
||||
- It does **not** reimplement idempotency / outbox / lock on Mongo (those stay JPA-only).
|
||||
- Opt-in: `MongoPersistenceConfig` re-imports the Mongo auto-configuration (`@ImportAutoConfiguration`)
|
||||
only when `ca-skeleton.persistence-mongo.enabled=true` (default off). The connection URI and
|
||||
database come from Spring's standard `spring.data.mongodb.*` settings.
|
||||
only when `ca-skeleton.persistence-mongo.enabled=true` (default off). `MongoPlatformAutoConfiguration`
|
||||
is gated on the same flag. The connection URI and database come from Spring's standard
|
||||
`spring.data.mongodb.*` settings; platform profiles come from
|
||||
`ca-skeleton.persistence-mongo.platform.*`.
|
||||
- `MongoOptInAutoConfigurationImportFilter`, registered through `META-INF/spring.factories`, blocks
|
||||
Boot 4's classpath-driven sync/reactive/data/repository/health/metrics Mongo auto-configuration
|
||||
when the module enable flag is absent or false.
|
||||
|
||||
## Allowed
|
||||
|
||||
- No project dependency is required by the generic infrastructure. The allowed-edge SSOT remains
|
||||
the `adapter-outbound-persistence-mongo` entry in `src/config/architecture/modules.json`.
|
||||
- External: `org.springframework.boot:spring-boot-starter-data-mongodb` (version via the shared
|
||||
Spring Boot BOM), `spring-boot-configuration-processor` (annotation processor).
|
||||
- No project dependency is required. The allowed-edge SSOT remains the
|
||||
`adapter-outbound-persistence-mongo` entry in `src/config/architecture/modules.json`.
|
||||
- External: `spring-boot-starter-data-mongodb` and `-reactive`, `spring-boot-autoconfigure`,
|
||||
`micrometer-core`, `slf4j-api`, `spring-boot-configuration-processor` (annotation processor).
|
||||
Versions come from the shared Spring Boot BOM; never pin the driver directly.
|
||||
- Test-only: ArchUnit, reactor-test, Testcontainers (`mongodb`, `toxiproxy`).
|
||||
|
||||
## Forbidden
|
||||
|
||||
@@ -38,13 +45,47 @@ Data MongoDB infrastructure. Design rationale lives in [README.md](README.md).
|
||||
- Adding idempotency/outbox/lock on Mongo without a separately approved contract.
|
||||
- Fully-qualified inline type references; more than one public top-level type per file.
|
||||
|
||||
### Package-boundary rules (`MongoModuleBoundaryTest`)
|
||||
|
||||
These reproduce the design's module dependency table. Breaking one fails the build:
|
||||
|
||||
- `…mongo.api..` must not import Spring, the MongoDB driver, BSON or Reactor. It is the
|
||||
framework-free core contract; `api/package-info.java` records why.
|
||||
- No Stable package may depend on `…mongo.advanced..`.
|
||||
- No production package may depend on `…mongo.testkit..`.
|
||||
- `imperative` ↛ `reactive`, `query` ↛ `aggregation`, `schema` ↛ execution packages,
|
||||
`observation` ↛ execution packages, `migration` ↛ `migration.flamingock`.
|
||||
|
||||
### Platform invariants that are not stylistic
|
||||
|
||||
- Transaction body retry and commit retry are **separate loops**: a new session per body attempt, and
|
||||
commit-only retry on an unknown commit. The body is never replayed after a commit ambiguity
|
||||
(`MongoTransactionRetryCoordinator`, ADR-MONGO-003).
|
||||
- `MongoExecutionOutcome`'s two ambiguous values must not be collapsed into success or failure.
|
||||
- BSON representations come from `MongoTypeRepresentationManifest`, never from a library default
|
||||
(ADR-MONGO-002).
|
||||
- Index and validator changes go through the manifest and the admin plane; ownership gates every drop
|
||||
(ADR-MONGO-004).
|
||||
- Every Advanced entry point refuses construction unless its `MongoAdvancedCapabilityFlags` capability
|
||||
is enabled.
|
||||
- Observation tags are limited to `MongoObservationConvention`'s allowlist.
|
||||
|
||||
## Tests
|
||||
|
||||
`MongoPersistenceConfigTest` proves default/false behavior through an actual
|
||||
`@EnableAutoConfiguration` context, typed enablement binding, and enabled infrastructure with a
|
||||
mock `MongoClient` plus a real `MongoTemplate` without a network connection.
|
||||
mock `MongoClient` plus a real `MongoTemplate` without a network connection. It must keep passing —
|
||||
the platform additions are opt-in and must not turn the module on by existing.
|
||||
|
||||
Hermetic contract tests carry `@Tag("mongodb-contract")` and run in `mongoStableContractTest`, which
|
||||
`check` depends on. Container lanes carry `mongodb-replicaset` / `mongodb-failover` and run only in
|
||||
their own tasks; the default `test` task excludes them, because a lane that needs Docker inside
|
||||
`check` teaches people to skip `check`.
|
||||
|
||||
```bash
|
||||
cd src
|
||||
./gradlew :adapter:outbound:persistence-mongo:check
|
||||
./gradlew :adapter:outbound:persistence-mongo:check --console=plain
|
||||
```
|
||||
|
||||
Release gates run from the repository root: `scripts/verify-mongodb-platform.sh` (Stable) and
|
||||
`scripts/verify-mongodb-advanced.sh` (Advanced).
|
||||
|
||||
Reference in New Issue
Block a user