Files
clean-architecture-backend-…/mongodb-superpowers-package/docs/superpowers/plans/2026-08-11-mongodb-advanced-capabilities-expansion-plan.md
T

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-advanced with 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 $text remains 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"