refactor: 빌드 로직 개선, gradle 파일 경량화
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# JPA Evidence Gradle Model Decoupling 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:** Remove execution-time Gradle `Project`/`Task`/`TaskState` access from JPA evidence generation without changing evidence semantics.
|
||||
|
||||
**Architecture:** A shared `JpaEvidenceExecutionService` consumes Gradle task-completion events for non-Test task claims. The JPA evidence plugin snapshots/configures JUnit result directories, provenance, environment/profile values, and dependency versions as typed task inputs. `GenerateJpaEvidenceManifestsTask` becomes a pure evidence assembler over those inputs plus filesystem/exec services.
|
||||
|
||||
**Tech Stack:** Java 21, Gradle 9 BuildService + Tooling Events, JUnit 6/TestKit, Jackson 3.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-17-jpa-evidence-gradle-model-decoupling-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Preserve readiness-card schema and task names.
|
||||
- Preserve JUnit XML as test evidence.
|
||||
- Preserve task-claim meaning: only a successful producer task covers a task claim.
|
||||
- Preserve evidence grade, blocker, hashing, prerequisite, output, candidate/R2 semantics.
|
||||
- No execution-time `Project`, `Task`, or `TaskState` access in `GenerateJpaEvidenceManifestsTask`.
|
||||
- Do not stage, commit, amend, reset, or push existing worktree changes.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Task completion evidence service
|
||||
|
||||
**Files:**
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceExecutionService.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTaskOutcome.java`
|
||||
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidenceExecutionServiceTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `JpaEvidenceExecutionService.outcome(String taskPath)` and `completedSuccessfully(String taskPath)`.
|
||||
- Consumes: Gradle `TaskFinishEvent` via `OperationCompletionListener`.
|
||||
|
||||
- [ ] Write tests for success, failure, skipped, and unknown task paths.
|
||||
- [ ] Verify tests fail because the service/model do not exist.
|
||||
- [ ] Implement the typed outcome model and thread-safe service.
|
||||
- [ ] Verify focused tests pass.
|
||||
|
||||
### Task 2: Typed JUnit evidence inputs
|
||||
|
||||
**Files:**
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTestResultLocator.java`
|
||||
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTaskSupport.java`
|
||||
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTestResultLocatorTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `Map<String, String>` task-path to repository-relative/absolute JUnit XML directory.
|
||||
- Produces: `JpaGeneratedTestResult read(String taskPath)` without `Project` or `Test`.
|
||||
|
||||
- [ ] Write a failing test that creates JUnit XML under a temporary directory and resolves it by task path.
|
||||
- [ ] Implement file-based result lookup using `JUnitEvidenceReader`.
|
||||
- [ ] Remove the `readJUnitResult(Project, Test)` helper once no caller remains.
|
||||
- [ ] Verify focused tests pass.
|
||||
|
||||
### Task 3: Generator typed input surface
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/GenerateJpaEvidenceManifestsTask.java`
|
||||
- Test: extend `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidencePluginTypeTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Add typed properties for profile/CI/artifact/topology/provenance/dependency versions/JUnit result directories.
|
||||
- Add an internal/service reference to `JpaEvidenceExecutionService`.
|
||||
|
||||
- [ ] Add reflection/type tests asserting the new task properties exist and no generator source contains `getProject()` or `Task.getState()` usage.
|
||||
- [ ] Verify the test fails against the current generator.
|
||||
- [ ] Add the typed properties and service reference.
|
||||
- [ ] Replace Project/Task/TaskState/configuration/extra-property reads with typed inputs/service lookups.
|
||||
- [ ] Verify focused tests pass.
|
||||
|
||||
### Task 4: Plugin wiring
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidencePlugin.java`
|
||||
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidenceTaskSupport.java`
|
||||
- Test: add `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaEvidencePluginFunctionalTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Register shared execution service and task-completion listener.
|
||||
- Configure generator typed inputs.
|
||||
- Configure JUnit result-directory mapping for active readiness/support Test tasks.
|
||||
- Preserve existing `dependsOn` producer graph.
|
||||
|
||||
- [ ] Write TestKit fixture asserting typed generator inputs and task wiring.
|
||||
- [ ] Verify RED.
|
||||
- [ ] Register/wire the service and all generator properties.
|
||||
- [ ] Resolve dependency versions and release provenance during configuration/plugin wiring rather than task action.
|
||||
- [ ] Verify TestKit GREEN.
|
||||
|
||||
### Task 5: Regression and Gradle 10-preparation verification
|
||||
|
||||
**Files:**
|
||||
- Modify only if verification exposes a regression.
|
||||
|
||||
- [ ] Run `src/build-tools` full `check --warning-mode=fail`.
|
||||
- [ ] Run root `verifyJpaReadinessRegistry verifyJpaReleaseGateTasks --warning-mode=fail`.
|
||||
- [ ] Run `:adapter:outbound:persistence-jpa:check --warning-mode=fail`.
|
||||
- [ ] Run candidate evidence generation with `--warning-mode=all`; verify there is no `Task.project`/execution-time project deprecation from JPA evidence tooling.
|
||||
- [ ] Run adapter procedural-Groovy scan and confirm no regression.
|
||||
- [ ] Run `git diff --check`.
|
||||
- [ ] Record any environment-only Docker/Testcontainers limitation separately from code correctness.
|
||||
@@ -0,0 +1,46 @@
|
||||
# JPA Leaf Verification Java Migration 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:** Remove the remaining procedural JPA leaf verification logic from Groovy while deleting a redundant verifier-of-verifier task.
|
||||
|
||||
**Architecture:** Keep the security scenario as a declarative `strictTestLanes.requires(...)` contract and remove `verifyJpaSecurityFixtures` from both the leaf and readiness registry. Move the real PostgreSQL `set_config` source-safety rule into a typed task/verifier owned by the already-applied `ca.jpa-evidence` Java plugin.
|
||||
|
||||
**Tech Stack:** Java 21, Gradle 9 binary plugins/tasks, JUnit 6.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-16-verification-surface-reduction-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Preserve the `verifyJpaSqlConstructionSafety` task name because readiness registry/evidence tooling references it.
|
||||
- Preserve the PostgreSQL security method selector on `postgresqlSecurityBaselineIntegrationTest`.
|
||||
- Remove `verifyJpaSecurityFixtures` only together with its readiness-card support-task reference.
|
||||
- Do not add production dependencies or change JPA runtime behavior.
|
||||
- Do not stage, commit, amend, or push.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Typed SQL construction safety verifier
|
||||
|
||||
**Files:**
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaSqlConstructionSafetyVerifier.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaSqlConstructionSafetyResult.java`
|
||||
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/jpa/JpaSqlConstructionSafetyVerifierTest.java`
|
||||
|
||||
- [ ] **Step 1:** Write RED tests for parameterized `set_config`, non-parameterized `set_config`, comments, and nested source paths.
|
||||
- [ ] **Step 2:** Implement the minimal typed verifier preserving the current line-based rule.
|
||||
- [ ] **Step 3:** Run the focused verifier tests to GREEN.
|
||||
|
||||
### Task 2: Java task ownership and redundant task removal
|
||||
|
||||
**Files:**
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/VerifyJpaSqlConstructionSafetyTask.java`
|
||||
- Modify: `src/build-tools/src/main/java/dev/caskeleton/buildtools/jpa/JpaEvidencePlugin.java`
|
||||
- Modify: `src/adapter/outbound/persistence-jpa/build.gradle`
|
||||
- Modify: `src/config/jpa/readiness-cards.yaml`
|
||||
|
||||
- [ ] **Step 1:** Register `verifyJpaSqlConstructionSafety` as a typed task from `JpaEvidencePlugin`.
|
||||
- [ ] **Step 2:** Delete the Groovy implementation of `verifyJpaSqlConstructionSafety`.
|
||||
- [ ] **Step 3:** Delete `verifyJpaSecurityFixtures` and remove it from the security card support tasks while keeping the `requires(...)` selector.
|
||||
- [ ] **Step 4:** Verify readiness registry and SQL-safety tasks.
|
||||
- [ ] **Step 5:** Run `:adapter:outbound:persistence-jpa:check`, build-tools tests, and `git diff --check`.
|
||||
@@ -0,0 +1,19 @@
|
||||
# JPA Test Lanes Java Convention Plan
|
||||
|
||||
**Goal:** Remove the remaining Map-driven JPA lane factories from Groovy and make lane metadata compile-time checked Java records.
|
||||
|
||||
**Architecture:** `ca.jpa-test-lanes` lives in build-logic and configures `ca.strict-test-lane`. Typed record lists own the PostgreSQL readiness and tagged platform lane metadata. The JPA leaf keeps source-set/dependency declarations plus the explicit cross-project task edge.
|
||||
|
||||
## Constraints
|
||||
- Preserve all 14 PostgreSQL readiness task names and selectors.
|
||||
- Preserve the security method selector in addition to its class selector.
|
||||
- Preserve five tagged platform lanes and the pool contract lane.
|
||||
- Preserve UTC JVM args, PostgreSQL evidence image property, and `jpa.matrix.versions` default `16`.
|
||||
- Keep release orchestration outside the leaf.
|
||||
- Do not stage, commit, amend, or push.
|
||||
|
||||
## Steps
|
||||
- [ ] RED TestKit contract for registered lanes, typed selector metadata, and property defaults.
|
||||
- [ ] Implement Java record-backed `JpaTestLanesPlugin` and register `ca.jpa-test-lanes`.
|
||||
- [ ] Apply plugin in persistence-jpa and remove both Groovy `Map` factories plus pool-lane Groovy configuration.
|
||||
- [ ] Run focused build-logic tests, JPA check, adapter dynamic-model scan, and broad verification.
|
||||
@@ -0,0 +1,61 @@
|
||||
# Mongo Gradle Verification Java Migration 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:** Remove Mongo JUnit/XML and release-manifest verification algorithms from the Groovy leaf build script and move them into typed Java build tooling without changing task names or verification semantics.
|
||||
|
||||
**Architecture:** `ca.mongo-verification` lives in `src/build-tools` because the checks are repository certification tooling, not reusable compilation conventions. The plugin registers the two existing verification task names; normal Java verifier/parser classes own XML/JSON parsing and return typed records, while `persistence-mongo/build.gradle` keeps only plugin/lane/dependency declarations and `check` wiring.
|
||||
|
||||
**Tech Stack:** Java 21, Gradle 9 binary plugins/tasks, Jackson 3, JUnit 6, JUnit XML.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-16-verification-surface-reduction-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Preserve `verifyMongoTestLaneDisjointness` and `verifyMongoReleaseContractLanes` task names and report paths.
|
||||
- Preserve the existing `test` + `mongoStableContractTest` dependency graph.
|
||||
- Do not add or resolve new production dependencies in the Mongo leaf.
|
||||
- Keep Groovy only as declarative build DSL; no JSON/XML parsing or `doLast` verification algorithm remains in the leaf.
|
||||
- Do not stage, commit, amend, or push; repository policy is human-only commits.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Typed Mongo verification core
|
||||
|
||||
**Files:**
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoLaneDisjointnessVerifier.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoLaneDisjointnessResult.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoReleaseContract.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoReleaseContractManifestParser.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoReleaseContractLaneVerifier.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoReleaseContractLaneResult.java`
|
||||
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/mongo/MongoLaneDisjointnessVerifierTest.java`
|
||||
- Test: `src/build-tools/src/test/java/dev/caskeleton/buildtools/mongo/MongoReleaseContractLaneVerifierTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Gradle JUnit XML result directories and `config/mongodb/release-contracts.json`.
|
||||
- Produces: typed result records used by Gradle task classes.
|
||||
|
||||
- [ ] **Step 1: Write failing verifier tests** covering disjoint lanes, overlap failure data, manifest filtering to hermetic lanes, missing result XML, and minimum-executed checks.
|
||||
- [ ] **Step 2: Run** `cd src/build-tools && ../gradlew test --tests 'dev.caskeleton.buildtools.mongo.*' --console=plain` and confirm RED from missing production types.
|
||||
- [ ] **Step 3: Implement minimal typed records/parsers/verifiers** using fail-closed XML parsing and Jackson 3 JSON tree parsing.
|
||||
- [ ] **Step 4: Run the focused tests again** and confirm PASS.
|
||||
|
||||
### Task 2: Binary plugin/task ownership and leaf cleanup
|
||||
|
||||
**Files:**
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/MongoVerificationPlugin.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/VerifyMongoTestLaneDisjointnessTask.java`
|
||||
- Create: `src/build-tools/src/main/java/dev/caskeleton/buildtools/mongo/VerifyMongoReleaseContractLanesTask.java`
|
||||
- Modify: `src/build-tools/build.gradle`
|
||||
- Modify: `src/adapter/outbound/persistence-mongo/build.gradle`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: typed verifiers from Task 1.
|
||||
- Produces: existing task names `verifyMongoTestLaneDisjointness`, `verifyMongoReleaseContractLanes` with unchanged report paths.
|
||||
|
||||
- [ ] **Step 1: Register `ca.mongo-verification`** and the two typed tasks in Java.
|
||||
- [ ] **Step 2: Apply the plugin in the Mongo leaf and delete both Groovy `tasks.register { doLast { ... } }` implementations.**
|
||||
- [ ] **Step 3: Run** `cd src && ./gradlew :adapter:outbound:persistence-mongo:verifyMongoTestLaneDisjointness :adapter:outbound:persistence-mongo:verifyMongoReleaseContractLanes --console=plain`.
|
||||
- [ ] **Step 4: Run** `cd src && ./gradlew :adapter:outbound:persistence-mongo:check --console=plain`.
|
||||
- [ ] **Step 5: Run** `cd src/build-tools && ../gradlew test --console=plain` and `git diff --check`.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Redis Topology Lane Java Migration 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.
|
||||
|
||||
**Goal:** Remove the last adapter-level procedural Groovy test lifecycle logic by moving Redis topology qualification into a typed Java convention plugin.
|
||||
|
||||
**Architecture:** `ca.redis-topology-lane` belongs in `build-logic`: it configures the default test exclusion, declares the strict `redisTopologyTest` lane, validates mode/properties, forwards topology system properties, and verifies executed required classes/no skips. The Redis leaf keeps only plugin and dependency declarations.
|
||||
|
||||
**Tech Stack:** Java 21, Gradle 9, JUnit Platform test tasks.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-16-verification-surface-reduction-design.md`
|
||||
|
||||
## Constraints
|
||||
- Preserve supported modes: standalone, sentinel, cluster, tls.
|
||||
- Preserve TLS deployment-mode mapping to standalone.
|
||||
- Preserve required property and required executed-class semantics.
|
||||
- Preserve fail-closed behavior for unknown mode and skipped topology tests.
|
||||
- Keep `redisTopologyTest` opt-in; do not add it to normal `check`.
|
||||
- Do not stage, commit, amend, or push.
|
||||
|
||||
### Task 1: Typed topology contract
|
||||
- [ ] Write failing Java tests for mode validation, required properties, class coverage, and skipped-test rejection.
|
||||
- [ ] Implement typed contract/result records and get focused tests GREEN.
|
||||
|
||||
### Task 2: Java convention plugin
|
||||
- [ ] Implement `RedisTopologyLanePlugin` using `StrictTestLaneExtension` and a Java `TestListener` tracker.
|
||||
- [ ] Register `ca.redis-topology-lane` in build-logic.
|
||||
- [ ] Apply it in cache-redis and remove the Groovy topology lifecycle/configuration block.
|
||||
- [ ] Verify build-logic tests, Redis unit `check`, task configuration, invalid-mode fail-closed behavior, and `git diff --check`.
|
||||
@@ -0,0 +1,93 @@
|
||||
# Messaging Platform Bridge 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:** Connect the canonical application integration-event publish boundary to the messaging platform without re-encoding bytes or introducing broker-specific ownership in app-bootstrap.
|
||||
|
||||
**Architecture:** Add an application-owned publish port, implement it in `adapter/outbound/messaging/platformbridge`, and publish canonical pre-encoded envelopes through `EncodedMessagePublisher`. The bridge preserves identity/routing/evidence and maps platform publish evidence explicitly into application outcomes.
|
||||
|
||||
**Tech Stack:** Java 21, Gradle 9, Spring Boot auto-configuration, JUnit 5, AssertJ.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-18-messaging-platform-bridge-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Preserve existing uncommitted changes; do not reset, stage, commit, amend, or push.
|
||||
- Never invent missing canonical identity, timestamp, trace, tenant, schema, or routing values.
|
||||
- Never bypass `DefaultMessagePublisher` through transport SPI or native Kafka clients.
|
||||
- Preserve exact `ValidatedIntegrationEvent.envelopeBytes()`.
|
||||
- Fail closed before send when event or causation identity is not UUIDv7.
|
||||
- Legacy outbox storage/relay migration is outside this plan.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Application-owned canonical publish port
|
||||
|
||||
**Files:**
|
||||
- Create: `application-core/src/main/java/dev/caskeleton/application/messaging/event/IntegrationEventPublishPort.java`
|
||||
- Test: existing bridge test compile contract
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `CompletionStage<OutboxPublishOutcome> publish(ValidatedIntegrationEvent event)`
|
||||
|
||||
- [x] Create the minimal application-owned interface.
|
||||
- [x] Run the focused bridge test and verify remaining failures are platform dependencies/adapter implementation, not the port.
|
||||
|
||||
### Task 2: Outbound messaging platform API dependency
|
||||
|
||||
**Files:**
|
||||
- Modify: `adapter/outbound/messaging/build.gradle`
|
||||
- Modify: `adapter/outbound/messaging/gradle.lockfile` through Gradle lock writing
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `:messaging:messaging-core-api`, `:messaging:messaging-schema-api`.
|
||||
|
||||
- [x] Add only the platform API dependencies required by the bridge.
|
||||
- [x] Refresh this module's locks.
|
||||
- [x] Re-run focused bridge test and verify the missing type set is reduced to bridge production code.
|
||||
|
||||
### Task 3: Canonical platform bridge
|
||||
|
||||
**Files:**
|
||||
- Create: `adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/platformbridge/PlatformIntegrationEventPublishAdapter.java`
|
||||
- Test: `adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/platformbridge/PlatformIntegrationEventPublishAdapterTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `IntegrationEventPublishPort`, `EncodedMessagePublisher`.
|
||||
- Produces: canonical application-to-platform anti-corruption bridge.
|
||||
|
||||
- [x] Implement UUIDv7 parsing that rejects incompatible identity before publisher invocation.
|
||||
- [x] Map canonical metadata and exact bytes into `MessageEnvelope<EncodedMessage>`.
|
||||
- [x] Preserve non-first-class evidence in bounded `x-ca-*` headers.
|
||||
- [x] Map `PublishResult` using transmission evidence.
|
||||
- [x] Run all three focused bridge tests to GREEN.
|
||||
|
||||
### Task 4: Spring ownership while preserving the legacy seam
|
||||
|
||||
**Files:**
|
||||
- Modify: `adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/MessagingSettings.java`
|
||||
- Modify: `adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/autoconfigure/MessagingBridgeRootAutoConfiguration.java`
|
||||
- Test: focused auto-configuration ownership test
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Spring-provided `EncodedMessagePublisher`, explicit `app.messaging.producer-id`.
|
||||
- Produces: `IntegrationEventPublishPort` bean for canonical events.
|
||||
|
||||
- [x] Add explicit `producerId` to the existing `app.messaging` adapter settings.
|
||||
- [x] Register the canonical bridge only when `app.messaging.producer-id` is explicitly present.
|
||||
- [x] Keep `KafkaSender` / `KafkaMessageBroker` as a documented transitional dependency of legacy outbox/realtime only.
|
||||
- [x] Add a Spring test proving producer-id present => one canonical bridge bean, absent => no canonical bridge bean.
|
||||
- [x] Run outbound messaging tests.
|
||||
|
||||
### Task 5: Platform and composition regression verification
|
||||
|
||||
**Files:** no new production files unless a test exposes a real defect.
|
||||
|
||||
- [x] Run `:messaging:messaging-runtime-core:test`.
|
||||
- [x] Run `:messaging:messaging-spring-boot-starter:test`.
|
||||
- [x] Run `:adapter:outbound:messaging:check --warning-mode=fail`.
|
||||
- [x] Run `:app-bootstrap:architectureTest :app-bootstrap:systemTest --warning-mode=fail`.
|
||||
- [x] Search for direct app-bootstrap Kafka producer ownership.
|
||||
- [x] Run `git diff --check`.
|
||||
- [x] Report any remaining legacy outbox cutover blocker explicitly rather than inventing a migration.
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
# Outbox Transport-Only Cutover Implementation Plan
|
||||
|
||||
**Goal:** Preserve canonical integration-event bytes and metadata inside the existing legacy `outbox_event` authority, then route canonical claimed rows through the messaging platform while legacy rows keep the current broker path.
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-09-18-outbox-transport-only-cutover-design.md`
|
||||
|
||||
## Constraints
|
||||
|
||||
- Preserve all existing uncommitted work. No reset/checkout/stage/commit/amend/push.
|
||||
- Do not activate or switch to `POLLING_V2`.
|
||||
- Do not synthesize missing canonical metadata for legacy rows.
|
||||
- Do not re-encode a persisted canonical envelope.
|
||||
- One claimed row goes through exactly one publish branch.
|
||||
- Default configuration remains legacy-compatible and canonical transport is off.
|
||||
|
||||
### Task 1 — Split canonical and legacy append ports
|
||||
|
||||
- [x] Create `LegacyOutboxAppendPort` with the current `NewOutboxEvent` signature.
|
||||
- [x] Change `OutboxAppendPort` to accept `ValidatedIntegrationEvent`.
|
||||
- [x] Move all current raw production consumers and their tests to `LegacyOutboxAppendPort`.
|
||||
- [x] Make `OutboxStoreAdapter` implement `LegacyOutboxAppendPort` only.
|
||||
- [x] Run `:application-core:test` and focused sample/outbox compile tests.
|
||||
|
||||
### Task 2 — Add additive canonical columns to `outbox_event`
|
||||
|
||||
- [x] Add the next PostgreSQL migration after V12.
|
||||
- [x] Widen event/correlation identifiers as required.
|
||||
- [x] Add canonical metadata, exact `BYTEA`, hashes/revisions, and all-or-none check constraints.
|
||||
- [x] Extend `OutboxEventEntity` mappings.
|
||||
- [x] Update migration history expectations.
|
||||
- [x] Add real PostgreSQL integration assertions for legacy rows and canonical shape constraints.
|
||||
|
||||
### Task 3 — Implement canonical append adapter
|
||||
|
||||
- [x] Add `CanonicalOutboxAppendAdapter`.
|
||||
- [x] Strictly validate UTF-8 compatibility projection.
|
||||
- [x] Persist every canonical field and exact `envelopeBytes`.
|
||||
- [x] Preserve old required columns for legacy relay/storage compatibility.
|
||||
- [x] Add unit tests for byte equality, field mapping and invalid UTF-8.
|
||||
- [x] Gate bean exposure on `ca-skeleton.outbox.canonical-transport-enabled=true`.
|
||||
|
||||
### Task 4 — Split the claimed row model
|
||||
|
||||
- [x] Add sealed `ClaimedOutboxEvent`.
|
||||
- [x] Keep `OutboxEvent` as legacy subtype.
|
||||
- [x] Add `CanonicalClaimedOutboxEvent` carrying reconstructed `ValidatedIntegrationEvent`.
|
||||
- [x] Change `OutboxStorePort.claimBatch` to return the sealed type.
|
||||
- [x] Map all-canonical rows to canonical subtype and all-null rows to legacy subtype.
|
||||
- [x] Reject partial canonical rows.
|
||||
- [x] Update legacy relay tests without changing its state-machine semantics.
|
||||
|
||||
### Task 5 — Route canonical claims through the platform
|
||||
|
||||
- [x] Update `OutboxMessagePublishPort` to accept `ClaimedOutboxEvent`.
|
||||
- [x] Extend `OutboxMessagePublishAdapter` with canonical `IntegrationEventPublishPort`.
|
||||
- [x] Legacy subtype uses only `MessageBroker`.
|
||||
- [x] Canonical subtype uses only the application canonical publish port and exact stored bytes.
|
||||
- [x] Add focused branch-isolation and outcome tests.
|
||||
|
||||
### Task 6 — Add explicit activation and composition validation
|
||||
|
||||
- [x] Add `canonicalTransportEnabled` to `OutboxSettings` and `config/outbox.yml`, default false.
|
||||
- [x] Startup fails when canonical transport is enabled but no `IntegrationEventPublishPort` exists.
|
||||
- [x] Relay-enabled compatibility deployment still requires the legacy broker until a later zero-legacy-backlog proof.
|
||||
- [x] Default-off composition keeps the existing legacy path.
|
||||
- [x] Enabled composition exposes the canonical append/publish path without a second scheduler.
|
||||
- [x] Update configuration docs/SSOT.
|
||||
|
||||
### Task 7 — Regression and architecture verification
|
||||
|
||||
- [x] `:application-core:check`
|
||||
- [x] `:adapter:outbound:persistence-jpa:check`
|
||||
- [x] focused PostgreSQL migration/outbox integration lane
|
||||
- [x] `:adapter:outbound:messaging:check`
|
||||
- [ ] `:sample-portfolio:check` — blocked by pre-existing `JpaLiveEventReplayAdapter` missing `Duration` wiring; the same 3 `SampleApplicationContextTest` failures reproduce on clean HEAD.
|
||||
- [x] focused sample outbox regression tests (`PosterEventPublisherTest`, `CreateWorkLogOutboxTest`, `WorkLogUseCasesTest`, `WorkLogAuthorizationContractTest`)
|
||||
- [x] `:app-bootstrap:architectureTest :app-bootstrap:systemTest`
|
||||
- [x] `verifyCleanArchitectureDependencies`
|
||||
- [x] `:app-bootstrap:verifyEnvKeys`
|
||||
- [x] static scans: no platform runtime/Kafka import in canonical bridge
|
||||
- [x] `git diff --check`
|
||||
- [x] no separate LLM Wiki branch-note warranted; spec, plan, module README/CLAUDE and configuration reference carry the implementation decision.
|
||||
|
||||
## Verification result
|
||||
|
||||
Transport-only cutover implementation is complete for this slice.
|
||||
|
||||
Passed:
|
||||
- `:application-core:check`
|
||||
- `:adapter:outbound:persistence-jpa:check`
|
||||
- `:adapter:outbound:persistence-jpa:postgresqlMigrationIntegrationTest`
|
||||
- `:adapter:outbound:messaging:check`
|
||||
- focused sample outbox regression tests
|
||||
- `:app-bootstrap:test`
|
||||
- focused `:app-bootstrap:integrationTest` outbox append + row-lifecycle contracts
|
||||
- `:app-bootstrap:architectureTest`
|
||||
- `:app-bootstrap:systemTest`
|
||||
- `verifyCleanArchitectureDependencies`
|
||||
- `:app-bootstrap:verifyEnvKeys`
|
||||
- `git diff --check`
|
||||
|
||||
Known unrelated blocker:
|
||||
- full `:sample-portfolio:check` still fails only the 3 previously documented `SampleApplicationContextTest` cases because `JpaLiveEventReplayAdapter` requires an unbound `Duration` bean. This reproduces on clean HEAD and was not introduced by this cutover.
|
||||
|
||||
Publication authority remains `LEGACY_POLLING`; no code path in this slice activates `POLLING_V2`.
|
||||
Reference in New Issue
Block a user