59 KiB
MongoDB Advanced Capabilities Expansion Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Stable MongoDB 문서 영속성 플랫폼의 공개 계약을 변경하지 않고 Sharding, Time Series, CSFLE, Queryable Encryption, Search, Vector Search, Multi-tenancy, Change Stream Messaging Bridge와 GridFS migration compatibility를 선택 모듈로 구현한다.
Architecture: 모든 기능은 modules/mongodb-advanced에 격리되고 명시적 feature flag, 별도 privilege, 별도 topology 또는 provider gate를 요구한다. Stable Starter는 이 모듈을 자동 의존하지 않는다. Application-plane descriptor/guardrail과 Admin-plane topology/index/key 변경을 분리한다.
Tech Stack: Stable MongoDB platform, Java 21, Spring Boot 4.1 BOM, Spring Data MongoDB 5.1, MongoDB 8.0 primary lane, actual Sharded Cluster, Atlas Local, actual target Atlas/KMS environments, existing Messaging and Object Storage platforms.
Global Constraints
- Stable Task 1~50과 Stable Release Gate가 먼저 통과해야 한다.
- Advanced module root는
modules/mongodb-advanced이다. - 모든 기능은
backend.mongodb.advanced.<capability>.enabled=true를 요구한다. - Advanced 모듈은 Stable Starter의 transitive dependency가 아니다.
- Sharding, Search, Encryption, Migration과 Tenant administration은 별도 credential을 사용한다.
- Time Series는 일반 Collection capability를 상속하지 않는다.
- CSFLE와 Queryable Encryption을 같은 Collection에 동시에 적용하지 않는다.
- MongoDB 8.0 Stable에서 QE prefix/suffix/substring query를 지원하지 않는다.
- Search/Vector index creation과 READY 상태를 분리한다.
- Shared Collection tenancy는 tenant context 누락 시 fail-closed다.
- Database-per-tenant는 client/migration concurrency를 제한한다.
- Change Stream 원본을 Messaging 외부 계약으로 직접 발행하지 않는다.
- GridFS는 legacy read/migration compatibility 전용이다.
- 승격에는 실제 topology/provider, security, failure, migration, performance와 runbook evidence가 필요하다.
Task 1: Advanced 모듈·Feature Flag·Dependency 격리 구성
Files:
- Create:
build-logic/src/main/kotlin/mongodb-advanced-library-conventions.gradle.kts - Create:
modules/mongodb-advanced/mongodb-sharding/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-timeseries/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-csfle/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-queryable-encryption/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-search/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-vector-search/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-tenancy-shared/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-tenancy-database/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-gridfs-compat/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-testkit-sharded/build.gradle.kts - Create:
modules/mongodb-advanced/mongodb-testkit-atlas/build.gradle.kts - Modify:
settings.gradle.kts - Test:
build-logic/src/test/java/MongoDbAdvancedModuleBoundaryTest.java
Interfaces:
- Consumes: Completed Stable Tasks 1~50 and Stable release evidence.
- Produces: 12 opt-in modules under
modules/mongodb-advancedwith explicit feature flags and no Stable Starter dependency.
Implementation requirements:
-
Require Stable Release Gate evidence before advanced test suites run.
-
Every capability requires
backend.mongodb.advanced.<capability>.enabled=true. -
No advanced module may be a transitive dependency of mongodb-spring-boot-starter.
-
Admin privileges and actual target-environment tests are capability-specific.
-
Promotion to Stable requires a separate ADR and evidence package.
-
Step 1: Write the failing test
class MongoDbAdvancedModuleBoundaryTest {
@org.junit.jupiter.api.Test
void stableStarterHasNoAdvancedDependency() {
org.assertj.core.api.Assertions.assertThat(
MongoAdvancedBuildModel.dependenciesOf("mongodb-spring-boot-starter"))
.noneMatch(it -> it.startsWith("mongodb-advanced"));
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew build-logic:test --tests 'MongoDbAdvancedModuleBoundaryTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public final class MongoAdvancedBuildModel {
public static boolean enabled(String capability, java.util.Map<String,Boolean> flags) {
return Boolean.TRUE.equals(flags.get(capability));
}
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew build-logic:test --tests 'MongoDbAdvancedModuleBoundaryTest'
./gradlew :modules:mongodb-advanced:mongodb-sharding:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'build-logic/src/main/kotlin/mongodb-advanced-library-conventions.gradle.kts' 'modules/mongodb-advanced/mongodb-sharding/build.gradle.kts' 'modules/mongodb-advanced/mongodb-timeseries/build.gradle.kts' 'modules/mongodb-advanced/mongodb-csfle/build.gradle.kts' 'modules/mongodb-advanced/mongodb-queryable-encryption/build.gradle.kts' 'modules/mongodb-advanced/mongodb-search/build.gradle.kts' 'modules/mongodb-advanced/mongodb-vector-search/build.gradle.kts' 'modules/mongodb-advanced/mongodb-tenancy-shared/build.gradle.kts' 'modules/mongodb-advanced/mongodb-tenancy-database/build.gradle.kts' 'modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/build.gradle.kts' 'modules/mongodb-advanced/mongodb-gridfs-compat/build.gradle.kts' 'modules/mongodb-advanced/mongodb-testkit-sharded/build.gradle.kts' 'modules/mongodb-advanced/mongodb-testkit-atlas/build.gradle.kts' 'settings.gradle.kts' 'build-logic/src/test/java/MongoDbAdvancedModuleBoundaryTest.java'
git commit -m "build: add isolated mongodb advanced modules"
Task 2: Shard Key Descriptor와 Targeted Query Validator 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardKeyDescriptor.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardKeyPart.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardStrategy.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardAwareQueryValidator.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/MongoRoutingClassification.java - Test:
modules/mongodb-advanced/mongodb-sharding/src/test/java/io/backend/skeleton/mongodb/advanced/sharding/ShardAwareQueryValidatorTest.java
Interfaces:
- Consumes: Stable collection/query/index manifests and operation contexts.
- Produces: Application-plane classification of targeted, prefix-targeted and scatter-gather queries.
Implementation requirements:
-
Descriptor must preserve compound shard-key order and hashed/range strategy.
-
Single-document writes must include routing evidence required by the server version and collection profile.
-
Unique indexes must be checked for shard-key compatibility.
-
Scatter-gather operations require an explicit reviewed profile and telemetry.
-
Do not execute shardCollection, refine or reshard through this module.
-
Step 1: Write the failing test
class ShardAwareQueryValidatorTest {
@org.junit.jupiter.api.Test
void classifiesMissingShardKeyAsScatterGather() {
ShardKeyDescriptor key = ShardKeyDescriptor.range("tenantId", "orderId");
MongoRoutingClassification result =
new ShardAwareQueryValidator().classify(key, java.util.Set.of("status"));
org.assertj.core.api.Assertions.assertThat(result)
.isEqualTo(MongoRoutingClassification.SCATTER_GATHER);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-sharding:test --tests 'io.backend.skeleton.mongodb.advanced.sharding.ShardAwareQueryValidatorTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public enum MongoRoutingClassification {
TARGETED, PREFIX_TARGETED, SCATTER_GATHER, REJECTED
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-sharding:test --tests 'io.backend.skeleton.mongodb.advanced.sharding.ShardAwareQueryValidatorTest'
./gradlew :modules:mongodb-advanced:mongodb-sharding:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardKeyDescriptor.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardKeyPart.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardStrategy.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/ShardAwareQueryValidator.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/MongoRoutingClassification.java' 'modules/mongodb-advanced/mongodb-sharding/src/test/java/io/backend/skeleton/mongodb/advanced/sharding/ShardAwareQueryValidatorTest.java'
git commit -m "feat: add mongodb shard aware query validation"
Task 3: analyzeShardKey Readiness Report와 D4 Sharding Admin 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ShardKeyReadinessReport.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ShardKeyAnalyzer.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/MongoShardingAdminGateway.java - Create:
modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ReshardApproval.java - Test:
modules/mongodb-advanced/mongodb-sharding/src/test/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ShardKeyAnalyzerTest.java
Interfaces:
- Consumes: Shard descriptors, D4 admin security and actual server sampling.
- Produces: Cardinality, frequency, monotonicity, read/write distribution and reshard readiness evidence.
Implementation requirements:
-
Run analyzeShardKey only through a shard-admin credential.
-
Report cardinality, frequency, monotonicity, skew and sampled routing distribution.
-
Require supporting index and query-manifest coverage before shardCollection approval.
-
Refine and reshard require dry-run, operator reason, rollback/forward strategy and audit.
-
Balancer, zones and shard add/remove remain explicit Admin operations.
-
Step 1: Write the failing test
class ShardKeyAnalyzerTest {
@org.junit.jupiter.api.Test
void rejectsLowCardinalityCandidate() {
ShardKeyReadinessReport report = ShardKeyReadinessReport.lowCardinality("status");
org.assertj.core.api.Assertions.assertThat(report.approved()).isFalse();
org.assertj.core.api.Assertions.assertThat(report.reasons())
.contains("LOW_CARDINALITY");
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-sharding:test --tests 'io.backend.skeleton.mongodb.advanced.sharding.admin.ShardKeyAnalyzerTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public record ShardKeyReadinessReport(
boolean approved,
java.util.Set<String> reasons,
double monotonicity,
double readTargetingRatio,
double writeTargetingRatio) {
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-sharding:test --tests 'io.backend.skeleton.mongodb.advanced.sharding.admin.ShardKeyAnalyzerTest'
./gradlew :modules:mongodb-advanced:mongodb-sharding:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ShardKeyReadinessReport.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ShardKeyAnalyzer.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/MongoShardingAdminGateway.java' 'modules/mongodb-advanced/mongodb-sharding/src/main/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ReshardApproval.java' 'modules/mongodb-advanced/mongodb-sharding/src/test/java/io/backend/skeleton/mongodb/advanced/sharding/admin/ShardKeyAnalyzerTest.java'
git commit -m "feat: add mongodb shard key readiness and admin gate"
Task 4: 실제 Sharded Cluster Testkit과 Chunk Migration 계약 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-testkit-sharded/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoShardedCluster.java - Create:
modules/mongodb-advanced/mongodb-testkit-sharded/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoChunkMigrationController.java - Create:
modules/mongodb-advanced/mongodb-testkit-sharded/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoShardingContractSuite.java - Create:
modules/mongodb-advanced/mongodb-testkit-sharded/src/test/resources/mongodb/init-sharded-cluster.js - Test:
modules/mongodb-advanced/mongodb-testkit-sharded/src/test/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoShardingContractSuiteTest.java
Interfaces:
- Consumes: Sharding module, Testcontainers/Docker and Stable platform contracts.
- Produces: Actual mongos/config-server/shard topology tests for targeting, migration, failover and cross-shard transactions.
Implementation requirements:
-
Run at least two shards and a replicated config server for release evidence.
-
Verify targeted versus scatter-gather execution through explain and telemetry.
-
Move chunks while reads, writes and change streams are active.
-
Test shard-key-missing single-document updates and unique-index restrictions.
-
Test cross-shard transaction failure and recovery without hiding latency cost.
-
Step 1: Write the failing test
class MongoShardingContractSuiteTest {
@org.junit.jupiter.api.Test
void targetedQueryTouchesOneShard() {
MongoShardingReport report = MongoShardingContractSuite.runTargetedQuery();
org.assertj.core.api.Assertions.assertThat(report.shardsExamined()).isEqualTo(1);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-testkit-sharded:test --tests 'io.backend.skeleton.mongodb.advanced.testkit.sharded.MongoShardingContractSuiteTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public interface MongoShardingContractSuite {
static MongoShardingReport runTargetedQuery() {
return new MongoShardingReport(1, MongoRoutingClassification.TARGETED);
}
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-testkit-sharded:test --tests 'io.backend.skeleton.mongodb.advanced.testkit.sharded.MongoShardingContractSuiteTest'
./gradlew :modules:mongodb-advanced:mongodb-testkit-sharded:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-testkit-sharded/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoShardedCluster.java' 'modules/mongodb-advanced/mongodb-testkit-sharded/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoChunkMigrationController.java' 'modules/mongodb-advanced/mongodb-testkit-sharded/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoShardingContractSuite.java' 'modules/mongodb-advanced/mongodb-testkit-sharded/src/test/resources/mongodb/init-sharded-cluster.js' 'modules/mongodb-advanced/mongodb-testkit-sharded/src/test/java/io/backend/skeleton/mongodb/advanced/testkit/sharded/MongoShardingContractSuiteTest.java'
git commit -m "test: add mongodb sharded cluster contract suite"
Task 5: Time Series 전용 Collection·Write·Query 계약 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesDescriptor.java - Create:
modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesGranularity.java - Create:
modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesOperations.java - Create:
modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesCapabilityValidator.java - Test:
modules/mongodb-advanced/mongodb-timeseries/src/test/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesCapabilityValidatorTest.java
Interfaces:
- Consumes: Stable manifests, D4 collection setup and MongoDB 8.0 capability reports.
- Produces: Separate timeField/metaField/granularity/bucket/TTL API that does not inherit general collection capabilities.
Implementation requirements:
-
Reject schema validator, change stream, CSFLE, search and transaction-write combinations.
-
Require explicit timeField, optional metaField and bounded granularity/bucket settings.
-
Validate server-version-specific sharding restrictions.
-
Expose TTL as time-series retention, not an exact scheduler.
-
Test document-size and update limitations separately from normal collections.
-
Step 1: Write the failing test
class MongoTimeSeriesCapabilityValidatorTest {
@org.junit.jupiter.api.Test
void rejectsChangeStreamOnTimeSeries() {
MongoTimeSeriesDescriptor descriptor = MongoTimeSeriesDescriptor.standard("observedAt", "sensor");
org.assertj.core.api.Assertions.assertThatThrownBy(() ->
new MongoTimeSeriesCapabilityValidator().requireChangeStream(descriptor))
.isInstanceOf(UnsupportedOperationException.class);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-timeseries:test --tests 'io.backend.skeleton.mongodb.advanced.timeseries.MongoTimeSeriesCapabilityValidatorTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public record MongoTimeSeriesDescriptor(
String timeField,
String metaField,
MongoTimeSeriesGranularity granularity,
java.time.Duration retention) {
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-timeseries:test --tests 'io.backend.skeleton.mongodb.advanced.timeseries.MongoTimeSeriesCapabilityValidatorTest'
./gradlew :modules:mongodb-advanced:mongodb-timeseries:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesDescriptor.java' 'modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesGranularity.java' 'modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesOperations.java' 'modules/mongodb-advanced/mongodb-timeseries/src/main/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesCapabilityValidator.java' 'modules/mongodb-advanced/mongodb-timeseries/src/test/java/io/backend/skeleton/mongodb/advanced/timeseries/MongoTimeSeriesCapabilityValidatorTest.java'
git commit -m "feat: add mongodb time series capability"
Task 6: CSFLE Automatic·Explicit Encryption 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleProfile.java - Create:
modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleFieldPolicy.java - Create:
modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoDataKeyResolver.java - Create:
modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleClientFactory.java - Test:
modules/mongodb-advanced/mongodb-csfle/src/test/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleFieldPolicyTest.java
Interfaces:
- Consumes: Security profiles, D4 admin client, BSON manifest and actual KMS/key-vault fixtures.
- Produces: Randomized/deterministic field encryption with key resolver and no plaintext telemetry.
Implementation requirements:
-
Randomized encryption is the default for non-queryable PII.
-
Deterministic encryption requires a documented equality-query requirement and leakage review.
-
Key-vault access uses a dedicated principal.
-
Plaintext fields, KMS material and data keys never enter logs, traces or failure metadata.
-
CSFLE cannot be enabled on a time-series collection or mixed with QE on the same collection.
-
Step 1: Write the failing test
class MongoCsfleFieldPolicyTest {
@org.junit.jupiter.api.Test
void nonQueryablePiiDefaultsToRandomizedEncryption() {
MongoCsfleFieldPolicy policy = MongoCsfleFieldPolicy.forPii("ssn", false);
org.assertj.core.api.Assertions.assertThat(policy.mode())
.isEqualTo(MongoCsfleMode.RANDOMIZED);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-csfle:test --tests 'io.backend.skeleton.mongodb.advanced.encryption.csfle.MongoCsfleFieldPolicyTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public record MongoCsfleFieldPolicy(
String fieldPath,
MongoCsfleMode mode,
String keyAlias) {
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-csfle:test --tests 'io.backend.skeleton.mongodb.advanced.encryption.csfle.MongoCsfleFieldPolicyTest'
./gradlew :modules:mongodb-advanced:mongodb-csfle:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleProfile.java' 'modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleFieldPolicy.java' 'modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoDataKeyResolver.java' 'modules/mongodb-advanced/mongodb-csfle/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleClientFactory.java' 'modules/mongodb-advanced/mongodb-csfle/src/test/java/io/backend/skeleton/mongodb/advanced/encryption/csfle/MongoCsfleFieldPolicyTest.java'
git commit -m "feat: add mongodb csfle capability"
Task 7: Queryable Encryption Equality·Range 계약 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoQueryableEncryptionProfile.java - Create:
modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoEncryptedFieldDescriptor.java - Create:
modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoQueryableEncryptionCollectionManager.java - Create:
modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoEncryptionMetadataOwnership.java - Test:
modules/mongodb-advanced/mongodb-queryable-encryption/src/test/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoQueryableEncryptionProfileTest.java
Interfaces:
- Consumes: Security, D4 admin, schema/index ownership and KMS test environment.
- Produces: QE equality and range profiles with protected internal metadata ownership.
Implementation requirements:
-
MongoDB 8.0 Stable supports equality and range only.
-
Prefix, suffix and substring query profiles are rejected.
-
Encrypted collection setup is a D4 operation completed before application writes.
-
Mark
__safeContent__and internal metadata collections as ENCRYPTION_MANAGED. -
Key rotation and compaction/cleanup require separate runbooks and evidence.
-
Step 1: Write the failing test
class MongoQueryableEncryptionProfileTest {
@org.junit.jupiter.api.Test
void mongoEightRejectsSubstringQueryableEncryption() {
org.assertj.core.api.Assertions.assertThatThrownBy(() ->
MongoQueryableEncryptionProfile.substring("name"))
.isInstanceOf(UnsupportedOperationException.class);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-queryable-encryption:test --tests 'io.backend.skeleton.mongodb.advanced.encryption.qe.MongoQueryableEncryptionProfileTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public enum MongoQueryableEncryptionQueryType { EQUALITY, RANGE }
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-queryable-encryption:test --tests 'io.backend.skeleton.mongodb.advanced.encryption.qe.MongoQueryableEncryptionProfileTest'
./gradlew :modules:mongodb-advanced:mongodb-queryable-encryption:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoQueryableEncryptionProfile.java' 'modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoEncryptedFieldDescriptor.java' 'modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoQueryableEncryptionCollectionManager.java' 'modules/mongodb-advanced/mongodb-queryable-encryption/src/main/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoEncryptionMetadataOwnership.java' 'modules/mongodb-advanced/mongodb-queryable-encryption/src/test/java/io/backend/skeleton/mongodb/advanced/encryption/qe/MongoQueryableEncryptionProfileTest.java'
git commit -m "feat: add mongodb queryable encryption equality and range"
Task 8: MongoDB Search Query·Index Readiness 계약 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchIndexDescriptor.java - Create:
modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchIndexState.java - Create:
modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchQuery.java - Create:
modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchOperations.java - Create:
modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchReadinessGate.java - Test:
modules/mongodb-advanced/mongodb-search/src/test/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchReadinessGateTest.java
Interfaces:
- Consumes: Aggregation guardrails, D4 admin and Atlas environment capability.
- Produces: Search indexes with CREATED/BUILDING/READY/FAILED states and bounded typed queries.
Implementation requirements:
-
Index creation success is not equivalent to READY.
-
Application search queries run only against an index proven READY.
-
Search query paths and operators are allowlisted.
-
Actual target deployment validates analyzers, relevance and latency.
-
Legacy
$textremains compatibility-only and is not silently redirected to Search. -
Step 1: Write the failing test
class MongoSearchReadinessGateTest {
@org.junit.jupiter.api.Test
void buildingIndexCannotServeTraffic() {
MongoSearchReadinessGate gate = new MongoSearchReadinessGate();
org.assertj.core.api.Assertions.assertThatThrownBy(() ->
gate.requireReady(MongoSearchIndexState.BUILDING))
.isInstanceOf(MongoOperationRejectedException.class);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-search:test --tests 'io.backend.skeleton.mongodb.advanced.search.MongoSearchReadinessGateTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public enum MongoSearchIndexState { CREATED, BUILDING, READY, FAILED, DELETING }
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-search:test --tests 'io.backend.skeleton.mongodb.advanced.search.MongoSearchReadinessGateTest'
./gradlew :modules:mongodb-advanced:mongodb-search:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchIndexDescriptor.java' 'modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchIndexState.java' 'modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchQuery.java' 'modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchOperations.java' 'modules/mongodb-advanced/mongodb-search/src/main/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchReadinessGate.java' 'modules/mongodb-advanced/mongodb-search/src/test/java/io/backend/skeleton/mongodb/advanced/search/MongoSearchReadinessGateTest.java'
git commit -m "feat: add mongodb search readiness contract"
Task 9: Vector Search와 Embedding·Score 계약 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorIndexDescriptor.java - Create:
modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoEmbedding.java - Create:
modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorQuery.java - Create:
modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorSearchOperations.java - Create:
modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorSearchBenchmarkGate.java - Test:
modules/mongodb-advanced/mongodb-vector-search/src/test/java/io/backend/skeleton/mongodb/advanced/vector/MongoEmbeddingTest.java
Interfaces:
- Consumes: Search readiness, operation budgets and Atlas test environment.
- Produces: Typed embedding dimension, similarity metric, candidate/result limits and benchmark evidence.
Implementation requirements:
-
Embedding dimension must exactly match the registered index.
-
Similarity metric and score interpretation are part of the index contract.
-
Bound numCandidates, result count, filter fields and timeout.
-
Do not return raw provider score without a named score contract.
-
Actual deployment benchmarks accuracy, latency, memory and index readiness.
-
Step 1: Write the failing test
class MongoEmbeddingTest {
@org.junit.jupiter.api.Test
void rejectsDimensionMismatch() {
MongoVectorIndexDescriptor index = MongoVectorIndexDescriptor.cosine("embedding", 3);
org.assertj.core.api.Assertions.assertThatThrownBy(() ->
MongoEmbedding.forIndex(index, new float[]{1f, 2f}))
.isInstanceOf(IllegalArgumentException.class);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-vector-search:test --tests 'io.backend.skeleton.mongodb.advanced.vector.MongoEmbeddingTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public record MongoEmbedding(float[] values) {
public MongoEmbedding { values = values.clone(); }
@Override public float[] values() { return values.clone(); }
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-vector-search:test --tests 'io.backend.skeleton.mongodb.advanced.vector.MongoEmbeddingTest'
./gradlew :modules:mongodb-advanced:mongodb-vector-search:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorIndexDescriptor.java' 'modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoEmbedding.java' 'modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorQuery.java' 'modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorSearchOperations.java' 'modules/mongodb-advanced/mongodb-vector-search/src/main/java/io/backend/skeleton/mongodb/advanced/vector/MongoVectorSearchBenchmarkGate.java' 'modules/mongodb-advanced/mongodb-vector-search/src/test/java/io/backend/skeleton/mongodb/advanced/vector/MongoEmbeddingTest.java'
git commit -m "feat: add mongodb vector search contract"
Task 10: Shared Collection Multi-tenancy Guardrail 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantContext.java - Create:
modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/TenantScopedMongoOperations.java - Create:
modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantPredicateInjector.java - Create:
modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantManifestValidator.java - Test:
modules/mongodb-advanced/mongodb-tenancy-shared/src/test/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantPredicateInjectorTest.java
Interfaces:
- Consumes: Stable query/aggregation/index/change-stream modules and security context.
- Produces: Fail-closed tenant predicate injection for find, update, delete, aggregation and change-stream projection.
Implementation requirements:
-
Missing tenant context rejects all tenant-scoped operations.
-
Inject tenant predicate into find/update/delete and require a bounded first-stage match for aggregation.
-
Validate tenant participation in unique indexes when uniqueness is tenant-scoped.
-
Do not assume tenantId is always the correct shard key; use shard-key analysis.
-
Never expose raw tenant IDs in metrics or general logs.
-
Step 1: Write the failing test
class MongoTenantPredicateInjectorTest {
@org.junit.jupiter.api.Test
void missingTenantContextFailsClosed() {
MongoTenantPredicateInjector injector = new MongoTenantPredicateInjector();
org.assertj.core.api.Assertions.assertThatThrownBy(() ->
injector.apply(java.util.Optional.empty(), AtomicFilter.id("o-1")))
.isInstanceOf(MongoOperationRejectedException.class);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-tenancy-shared:test --tests 'io.backend.skeleton.mongodb.advanced.tenancy.shared.MongoTenantPredicateInjectorTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public record MongoTenantContext(String opaqueTenantKey) {
public MongoTenantContext {
if (opaqueTenantKey == null || opaqueTenantKey.isBlank()) {
throw new IllegalArgumentException("tenant context required");
}
}
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-tenancy-shared:test --tests 'io.backend.skeleton.mongodb.advanced.tenancy.shared.MongoTenantPredicateInjectorTest'
./gradlew :modules:mongodb-advanced:mongodb-tenancy-shared:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantContext.java' 'modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/TenantScopedMongoOperations.java' 'modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantPredicateInjector.java' 'modules/mongodb-advanced/mongodb-tenancy-shared/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantManifestValidator.java' 'modules/mongodb-advanced/mongodb-tenancy-shared/src/test/java/io/backend/skeleton/mongodb/advanced/tenancy/shared/MongoTenantPredicateInjectorTest.java'
git commit -m "feat: add shared collection mongodb tenancy guardrails"
Task 11: Database-per-tenant Routing·Migration·Client Lifecycle 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantDatabaseResolver.java - Create:
modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantClientRegistry.java - Create:
modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantMigrationCoordinator.java - Create:
modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantLifecyclePolicy.java - Test:
modules/mongodb-advanced/mongodb-tenancy-database/src/test/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantClientRegistryTest.java
Interfaces:
- Consumes: Stable profile/client generation, migration core and security modules.
- Produces: Bounded tenant database routing, client caching, migration fan-out and offboarding lifecycle.
Implementation requirements:
-
Tenant-to-database mapping comes from a trusted registry, never request input.
-
Bound cached clients and close idle generations.
-
Migration fan-out uses concurrency and rate limits with per-tenant checkpoints.
-
A tenant database cannot become active before schema/index validation succeeds.
-
Offboarding requires retention, export and delete evidence.
-
Step 1: Write the failing test
class MongoTenantClientRegistryTest {
@org.junit.jupiter.api.Test
void registryEnforcesMaximumActiveClients() {
MongoTenantClientRegistry registry = new MongoTenantClientRegistry(2);
registry.acquire("t1");
registry.acquire("t2");
org.assertj.core.api.Assertions.assertThatThrownBy(() -> registry.acquire("t3"))
.isInstanceOf(MongoOperationRejectedException.class);
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-tenancy-database:test --tests 'io.backend.skeleton.mongodb.advanced.tenancy.database.MongoTenantClientRegistryTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public interface MongoTenantDatabaseResolver {
DatabaseProfileName resolve(MongoTenantContext tenant);
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-tenancy-database:test --tests 'io.backend.skeleton.mongodb.advanced.tenancy.database.MongoTenantClientRegistryTest'
./gradlew :modules:mongodb-advanced:mongodb-tenancy-database:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantDatabaseResolver.java' 'modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantClientRegistry.java' 'modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantMigrationCoordinator.java' 'modules/mongodb-advanced/mongodb-tenancy-database/src/main/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantLifecyclePolicy.java' 'modules/mongodb-advanced/mongodb-tenancy-database/src/test/java/io/backend/skeleton/mongodb/advanced/tenancy/database/MongoTenantClientRegistryTest.java'
git commit -m "feat: add database per tenant mongodb lifecycle"
Task 12: Change Stream → Messaging 안정 Bridge 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoChangeToIntegrationEventMapper.java - Create:
modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoChangeMessagingBridge.java - Create:
modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoBridgeOutboxPolicy.java - Create:
modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoBridgeCheckpointPolicy.java - Test:
modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/test/java/io/backend/skeleton/mongodb/advanced/bridge/MongoChangeMessagingBridgeTest.java
Interfaces:
- Consumes: Stable Change Stream projector and the existing Messaging Platform typed publisher.
- Produces: Mapping of physical changes to versioned integration events with idempotent publish/checkpoint semantics.
Implementation requirements:
-
Never publish raw MongoDB change events as external contracts.
-
Integration event type, schema version and message ID are mapper-owned stable values.
-
Publish and checkpoint ambiguity must preserve duplicate-safe message identity.
-
Document where Change Stream bridge is insufficient and Transactional Outbox is required.
-
Messaging failures must not silently advance the MongoDB checkpoint.
-
Step 1: Write the failing test
class MongoChangeMessagingBridgeTest {
@org.junit.jupiter.api.Test
void failedPublishDoesNotAdvanceMongoCheckpoint() {
MongoBridgeProbe probe = MongoBridgeProbe.publishFails();
probe.bridge().handle(probe.change()).block();
org.assertj.core.api.Assertions.assertThat(probe.checkpointWrites()).isZero();
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-change-stream-messaging-bridge:test --tests 'io.backend.skeleton.mongodb.advanced.bridge.MongoChangeMessagingBridgeTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public interface MongoChangeToIntegrationEventMapper {
MessagingEnvelope map(MongoChangeEventIdentity identity, org.bson.BsonDocument change);
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-change-stream-messaging-bridge:test --tests 'io.backend.skeleton.mongodb.advanced.bridge.MongoChangeMessagingBridgeTest'
./gradlew :modules:mongodb-advanced:mongodb-change-stream-messaging-bridge:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoChangeToIntegrationEventMapper.java' 'modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoChangeMessagingBridge.java' 'modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoBridgeOutboxPolicy.java' 'modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/main/java/io/backend/skeleton/mongodb/advanced/bridge/MongoBridgeCheckpointPolicy.java' 'modules/mongodb-advanced/mongodb-change-stream-messaging-bridge/src/test/java/io/backend/skeleton/mongodb/advanced/bridge/MongoChangeMessagingBridgeTest.java'
git commit -m "feat: add mongodb change stream messaging bridge"
Task 13: GridFS Legacy Compatibility와 Object Storage Migration Adapter 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsCompatibilityReader.java - Create:
modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsMigrationJob.java - Create:
modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsMigrationCheckpoint.java - Create:
modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsObjectReference.java - Test:
modules/mongodb-advanced/mongodb-gridfs-compat/src/test/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsMigrationJobTest.java
Interfaces:
- Consumes: Fileserver/Object Storage ContentStore contract and migration core.
- Produces: Read-only legacy GridFS compatibility plus resumable migration to the single file source of truth.
Implementation requirements:
-
Do not expose new upload APIs backed by GridFS.
-
Read GridFS metadata and bytes without creating a second domain file lifecycle.
-
Migrate bytes to ContentStore, verify size/checksum, then write the new FileId/ContentKey reference.
-
Checkpoint migration and preserve retry-safe deterministic identities.
-
Delete legacy GridFS content only through a separate audited cleanup phase.
-
Step 1: Write the failing test
class MongoGridFsMigrationJobTest {
@org.junit.jupiter.api.Test
void sourceIsRetainedUntilTargetChecksumIsVerified() {
MongoGridFsMigrationProbe probe = MongoGridFsMigrationProbe.checksumMismatch();
probe.job().migrate(probe.sourceId());
org.assertj.core.api.Assertions.assertThat(probe.sourceDeleted()).isFalse();
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-gridfs-compat:test --tests 'io.backend.skeleton.mongodb.advanced.gridfs.MongoGridFsMigrationJobTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public interface MongoGridFsCompatibilityReader {
GridFsLegacyContent open(String legacyId);
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-gridfs-compat:test --tests 'io.backend.skeleton.mongodb.advanced.gridfs.MongoGridFsMigrationJobTest'
./gradlew :modules:mongodb-advanced:mongodb-gridfs-compat:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsCompatibilityReader.java' 'modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsMigrationJob.java' 'modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsMigrationCheckpoint.java' 'modules/mongodb-advanced/mongodb-gridfs-compat/src/main/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsObjectReference.java' 'modules/mongodb-advanced/mongodb-gridfs-compat/src/test/java/io/backend/skeleton/mongodb/advanced/gridfs/MongoGridFsMigrationJobTest.java'
git commit -m "feat: add gridfs compatibility migration adapter"
Task 14: Atlas Local·실제 Atlas Search·Vector·Encryption Testkit 구현
Files:
- Create:
modules/mongodb-advanced/mongodb-testkit-atlas/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoAtlasLocalContainer.java - Create:
modules/mongodb-advanced/mongodb-testkit-atlas/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoAtlasCapabilityContractSuite.java - Create:
modules/mongodb-advanced/mongodb-testkit-atlas/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoActualAtlasReleaseGate.java - Create:
modules/mongodb-advanced/mongodb-testkit-atlas/src/test/resources/atlas/search-index.json - Create:
modules/mongodb-advanced/mongodb-testkit-atlas/src/test/resources/atlas/vector-index.json - Test:
modules/mongodb-advanced/mongodb-testkit-atlas/src/test/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoAtlasCapabilityContractSuiteTest.java
Interfaces:
- Consumes: Search, vector, CSFLE/QE modules and Testcontainers Atlas Local.
- Produces: Fast local contracts plus credentialed actual-target release gates for readiness, query, KMS and rotation.
Implementation requirements:
-
Atlas Local is PR/nightly evidence, not the sole production compatibility proof.
-
Actual target tests are opt-in secret-backed release jobs.
-
Wait for Search/Vector index READY before queries.
-
Test wrong KMS key, key-vault permission and credential rotation without plaintext diagnostics.
-
Persist only bounded capability reports and never provider credentials.
-
Step 1: Write the failing test
class MongoAtlasCapabilityContractSuiteTest {
@org.junit.jupiter.api.Test
void vectorQueriesWaitForReadyIndex() {
MongoAtlasCapabilityReport report = MongoAtlasCapabilityContractSuite.vectorReadiness();
org.assertj.core.api.Assertions.assertThat(report.queriedBeforeReady()).isFalse();
}
}
- Step 2: Run the focused test and verify the failure
Run:
./gradlew :modules:mongodb-advanced:mongodb-testkit-atlas:test --tests 'io.backend.skeleton.mongodb.advanced.testkit.atlas.MongoAtlasCapabilityContractSuiteTest'
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public interface MongoAtlasCapabilityContractSuite {
static MongoAtlasCapabilityReport vectorReadiness() {
return new MongoAtlasCapabilityReport(false, true);
}
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
./gradlew :modules:mongodb-advanced:mongodb-testkit-atlas:test --tests 'io.backend.skeleton.mongodb.advanced.testkit.atlas.MongoAtlasCapabilityContractSuiteTest'
./gradlew :modules:mongodb-advanced:mongodb-testkit-atlas:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'modules/mongodb-advanced/mongodb-testkit-atlas/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoAtlasLocalContainer.java' 'modules/mongodb-advanced/mongodb-testkit-atlas/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoAtlasCapabilityContractSuite.java' 'modules/mongodb-advanced/mongodb-testkit-atlas/src/main/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoActualAtlasReleaseGate.java' 'modules/mongodb-advanced/mongodb-testkit-atlas/src/test/resources/atlas/search-index.json' 'modules/mongodb-advanced/mongodb-testkit-atlas/src/test/resources/atlas/vector-index.json' 'modules/mongodb-advanced/mongodb-testkit-atlas/src/test/java/io/backend/skeleton/mongodb/advanced/testkit/atlas/MongoAtlasCapabilityContractSuiteTest.java'
git commit -m "test: add atlas local and actual target capability gates"
Task 15: Advanced Capability 문서·승격 ADR·최종 Promotion Gate
Files:
- Create:
docs/mongodb/advanced/sharding.md - Create:
docs/mongodb/advanced/time-series.md - Create:
docs/mongodb/advanced/encryption.md - Create:
docs/mongodb/advanced/search-vector.md - Create:
docs/mongodb/advanced/multi-tenancy.md - Create:
docs/mongodb/advanced/gridfs-migration.md - Create:
docs/adr/ADR-MONGO-ADV-001-capability-promotion.md - Create:
scripts/verify-mongodb-advanced.sh - Test:
modules/mongodb-advanced/mongodb-sharding/src/test/java/io/backend/skeleton/mongodb/advanced/MongoAdvancedPromotionGateTest.java
Interfaces:
- Consumes: Every previous Advanced task and Stable release evidence.
- Produces: Capability-specific support matrix, runbooks, promotion ADR and reproducible advanced verification command.
Implementation requirements:
-
Each capability documents topology, server version, privilege, unsupported combinations and failure recovery.
-
Promotion requires actual topology/environment evidence, security review and migration/runbook coverage.
-
A capability promoted to Stable still remains an opt-in module unless a later starter ADR changes the dependency boundary.
-
Search/Vector promotion requires relevance and performance evidence, not only functional success.
-
Database-per-tenant and reshard orchestration remain Experimental until operational scale evidence exists.
-
Step 1: Write the failing test
class MongoAdvancedPromotionGateTest {
@org.junit.jupiter.api.Test
void everyPromotionRequiresActualEnvironmentEvidence() {
MongoAdvancedPromotionEvidence evidence = MongoAdvancedPromotionEvidence.fixture();
org.assertj.core.api.Assertions.assertThat(evidence.requiredCategories())
.contains("actual-topology", "security", "migration", "failure", "runbook");
}
}
- Step 2: Run the focused test and verify the failure
Run:
bash scripts/verify-mongodb-advanced.sh
Expected: FAIL because the advanced capability or its gate is not implemented yet.
- Step 3: Implement the smallest complete production contract
public final class MongoAdvancedPromotionGate {
public void verify(MongoAdvancedPromotionEvidence evidence) {
evidence.require("stable-platform");
evidence.require("actual-topology");
evidence.require("security");
evidence.require("failure");
evidence.require("runbook");
}
}
Implement every invariant listed under Implementation requirements. The snippet fixes public names and the central safety contract.
- Step 4: Run the focused test and module suite
Run:
bash scripts/verify-mongodb-advanced.sh
./gradlew :modules:mongodb-advanced:mongodb-sharding:test
Expected: PASS with the focused assertion and module suite green.
- Step 5: Commit the independently reviewable change
git add 'docs/mongodb/advanced/sharding.md' 'docs/mongodb/advanced/time-series.md' 'docs/mongodb/advanced/encryption.md' 'docs/mongodb/advanced/search-vector.md' 'docs/mongodb/advanced/multi-tenancy.md' 'docs/mongodb/advanced/gridfs-migration.md' 'docs/adr/ADR-MONGO-ADV-001-capability-promotion.md' 'scripts/verify-mongodb-advanced.sh' 'modules/mongodb-advanced/mongodb-sharding/src/test/java/io/backend/skeleton/mongodb/advanced/MongoAdvancedPromotionGateTest.java'
git commit -m "docs: add mongodb advanced promotion gate"