| New file |
| | |
| | | # Station Reroute Refactor 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:** Refactor `StationOperateProcessUtils` so run-block reroute, idle recover reroute, out-order dispatch, and watch-circle dispatch all execute through one shared reroute pipeline without changing current business behavior. |
| | | |
| | | **Architecture:** Keep the four public scan methods as entry points, but move shared reroute work into one internal pipeline inside `StationOperateProcessUtils`: context loading, decision resolution, command-plan building, execution guards, and post-dispatch effects. Keep `ZyStationV5Thread`, `StationMoveCoordinator`, Redis key usage, and current dispatch semantics unchanged; only reorganize code paths and add focused regression tests around the new seams. |
| | | |
| | | **Tech Stack:** Java 17, Spring Boot 3.5, MyBatis-Plus, RedisUtil, JUnit 5, Mockito |
| | | |
| | | --- |
| | | |
| | | ## File Map |
| | | |
| | | - Modify: `pom.xml` |
| | | - Add the minimal test dependency required to run focused JUnit 5 / Mockito tests. |
| | | - Modify: `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - Introduce shared reroute context / decision / command-plan structures and move the repeated flow into one pipeline. |
| | | - Create: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | - Cover the new package-private reroute seams and guard ordering with focused unit tests. |
| | | |
| | | ### Task 1: Add Test Harness For The New Reroute Seams |
| | | |
| | | **Files:** |
| | | - Modify: `pom.xml` |
| | | - Create: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | |
| | | - [ ] **Step 1: Write the failing test file for the reroute seam** |
| | | |
| | | ```java |
| | | package com.zy.core.utils; |
| | | |
| | | import org.junit.jupiter.api.Test; |
| | | |
| | | class StationOperateProcessUtilsReroutePipelineTest { |
| | | |
| | | @Test |
| | | void choosesRunBlockCommandBuilderForRunBlockRerouteScene() { |
| | | // compile-time failing seam: package-private helper does not exist yet |
| | | StationOperateProcessUtils.RerouteSceneType scene = |
| | | StationOperateProcessUtils.RerouteSceneType.RUN_BLOCK_REROUTE; |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Run the test to verify it fails** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest test` |
| | | Expected: FAIL because JUnit test dependency and/or the new reroute seam types are missing. |
| | | |
| | | - [ ] **Step 3: Add minimal test dependency and keep scope tight** |
| | | |
| | | ```xml |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-test</artifactId> |
| | | <scope>test</scope> |
| | | </dependency> |
| | | ``` |
| | | |
| | | - [ ] **Step 4: Re-run the same test to verify it still fails for the right reason** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest test` |
| | | Expected: FAIL because `RerouteSceneType` and the package-private reroute seam types do not exist yet. |
| | | |
| | | - [ ] **Step 5: Commit the harness-only change** |
| | | |
| | | ```bash |
| | | git add pom.xml src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |
| | | git commit -m "test: add station reroute pipeline harness" |
| | | ``` |
| | | |
| | | ### Task 2: Extract Shared Reroute Types And The First Decision Seam |
| | | |
| | | **Files:** |
| | | - Modify: `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - Modify: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | |
| | | - [ ] **Step 1: Write a failing test for the first shared decision seam** |
| | | |
| | | ```java |
| | | @Test |
| | | void resolveExecutionTarget_skipsWhenTargetEqualsCurrentStation() { |
| | | StationOperateProcessUtils.RerouteDecision decision = |
| | | StationOperateProcessUtils.RerouteDecision.skip("same-station"); |
| | | |
| | | assert decision.skip(); |
| | | assert "same-station".equals(decision.skipReason()); |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Run the focused test to verify it fails** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#resolveExecutionTarget_skipsWhenTargetEqualsCurrentStation test` |
| | | Expected: FAIL because `RerouteDecision` and its skip contract do not exist yet. |
| | | |
| | | - [ ] **Step 3: Add the minimal shared reroute types in `StationOperateProcessUtils.java`** |
| | | |
| | | ```java |
| | | static enum RerouteSceneType { |
| | | RUN_BLOCK_REROUTE, |
| | | IDLE_RECOVER, |
| | | OUT_ORDER, |
| | | WATCH_CIRCLE |
| | | } |
| | | |
| | | static final class RerouteDecision { |
| | | private final boolean skip; |
| | | private final String skipReason; |
| | | private final Integer targetStationId; |
| | | |
| | | static RerouteDecision skip(String reason) { |
| | | return new RerouteDecision(true, reason, null); |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | Implementation notes: |
| | | - Keep these types inside `StationOperateProcessUtils.java`. |
| | | - Make them package-private or static nested so tests in the same package can reach them without creating a new runtime component. |
| | | - Do not change public behavior yet. |
| | | |
| | | - [ ] **Step 4: Re-run the focused test to verify it passes** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#resolveExecutionTarget_skipsWhenTargetEqualsCurrentStation test` |
| | | Expected: PASS |
| | | |
| | | - [ ] **Step 5: Commit the shared-type extraction** |
| | | |
| | | ```bash |
| | | git add src/main/java/com/zy/core/utils/StationOperateProcessUtils.java src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |
| | | git commit -m "refactor: add station reroute shared types" |
| | | ``` |
| | | |
| | | ### Task 3: Build The Shared Execution Guards And Command Plan |
| | | |
| | | **Files:** |
| | | - Modify: `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - Modify: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | |
| | | - [ ] **Step 1: Write failing tests for guard behavior and command-builder selection** |
| | | |
| | | ```java |
| | | @Test |
| | | void buildCommandPlan_usesRunBlockCommandBuilderForRunBlockScene() { |
| | | // arrange mocked StationThread and context |
| | | // assert getRunBlockRerouteCommand is chosen |
| | | } |
| | | |
| | | @Test |
| | | void executePlan_skipsWhenCurrentTaskStillExistsInBuffer() { |
| | | // arrange task buffer with current taskNo |
| | | // assert executePlan returns skipped result and does not dispatch |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Run the focused tests to verify they fail** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#buildCommandPlan_usesRunBlockCommandBuilderForRunBlockScene,StationOperateProcessUtilsReroutePipelineTest#executePlan_skipsWhenCurrentTaskStillExistsInBuffer test` |
| | | Expected: FAIL because shared plan/guard methods do not exist yet. |
| | | |
| | | - [ ] **Step 3: Add the package-private execution helpers and keep order explicit** |
| | | |
| | | ```java |
| | | RerouteCommandPlan buildRerouteCommandPlan(RerouteContext context, RerouteDecision decision) { ... } |
| | | |
| | | RerouteExecutionResult executeReroutePlan(RerouteContext context, RerouteCommandPlan plan) { ... } |
| | | ``` |
| | | |
| | | Implementation notes: |
| | | - Keep buffer guard, recent-dispatch idle guard, out-order lock, and short-term dedup in one place. |
| | | - Preserve current order: |
| | | - cancel session when the scene requires it |
| | | - reset segment commands when the scene requires it |
| | | - clear idle-issued commands only for idle recover |
| | | - dispatch command |
| | | - apply post-dispatch effects only after successful dispatch |
| | | - Do not migrate the four public entry methods yet; only make the shared helpers real. |
| | | |
| | | - [ ] **Step 4: Re-run the focused tests to verify they pass** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#buildCommandPlan_usesRunBlockCommandBuilderForRunBlockScene,StationOperateProcessUtilsReroutePipelineTest#executePlan_skipsWhenCurrentTaskStillExistsInBuffer test` |
| | | Expected: PASS |
| | | |
| | | - [ ] **Step 5: Commit the shared plan/guard layer** |
| | | |
| | | ```bash |
| | | git add src/main/java/com/zy/core/utils/StationOperateProcessUtils.java src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |
| | | git commit -m "refactor: add station reroute execution pipeline" |
| | | ``` |
| | | |
| | | ### Task 4: Migrate `checkStationOutOrder` And `watchCircleStation` To The Shared Pipeline |
| | | |
| | | **Files:** |
| | | - Modify: `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - Modify: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | |
| | | - [ ] **Step 1: Write failing tests for the shared out-order / watch-circle flow** |
| | | |
| | | ```java |
| | | @Test |
| | | void outOrderAndWatchCircle_shareDecisionAndPostDispatchEffects() { |
| | | // arrange equivalent contexts with different scene types |
| | | // assert both use shared decision flow and sync watch state correctly |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Run the focused test to verify it fails** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#outOrderAndWatchCircle_shareDecisionAndPostDispatchEffects test` |
| | | Expected: FAIL because the entry methods still duplicate their own execution logic. |
| | | |
| | | - [ ] **Step 3: Migrate the two entry methods to the shared pipeline** |
| | | |
| | | ```java |
| | | public synchronized void checkStationOutOrder() { |
| | | // scan candidates |
| | | // build context |
| | | // executeReroute(context) |
| | | } |
| | | |
| | | public synchronized void watchCircleStation() { |
| | | // scan candidates |
| | | // build context |
| | | // executeReroute(context) |
| | | } |
| | | ``` |
| | | |
| | | Implementation notes: |
| | | - Keep the candidate scan conditions exactly as they are today. |
| | | - Do not change `resolveOutboundDispatchDecision`. |
| | | - Keep `syncOutOrderWatchState` and `recordDispatch` conditions identical. |
| | | |
| | | - [ ] **Step 4: Re-run the focused test to verify it passes** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#outOrderAndWatchCircle_shareDecisionAndPostDispatchEffects test` |
| | | Expected: PASS |
| | | |
| | | - [ ] **Step 5: Commit the out-order migration** |
| | | |
| | | ```bash |
| | | git add src/main/java/com/zy/core/utils/StationOperateProcessUtils.java src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |
| | | git commit -m "refactor: unify station out-order reroute flow" |
| | | ``` |
| | | |
| | | ### Task 5: Migrate `checkStationRunBlock` And `checkStationIdleRecover` To The Shared Pipeline |
| | | |
| | | **Files:** |
| | | - Modify: `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - Modify: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | |
| | | - [ ] **Step 1: Write failing tests for run-block and idle-recover specific behavior** |
| | | |
| | | ```java |
| | | @Test |
| | | void runBlockReroute_keepsDirectReassignAndNormalRerouteSeparate() { |
| | | // assert inbound run-block reassign does not use the normal reroute command path |
| | | } |
| | | |
| | | @Test |
| | | void idleRecover_skipsWhenLastDispatchIsTooRecent() { |
| | | // assert the existing recent-dispatch protection still short-circuits the reroute |
| | | } |
| | | ``` |
| | | |
| | | - [ ] **Step 2: Run the focused tests to verify they fail** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#runBlockReroute_keepsDirectReassignAndNormalRerouteSeparate,StationOperateProcessUtilsReroutePipelineTest#idleRecover_skipsWhenLastDispatchIsTooRecent test` |
| | | Expected: FAIL because the public methods still own their own scene-specific flow. |
| | | |
| | | - [ ] **Step 3: Migrate the two entry methods without changing semantics** |
| | | |
| | | ```java |
| | | public synchronized void checkStationRunBlock() { |
| | | // keep candidate scan and lock acquisition |
| | | // delegate each candidate to executeReroute(context) |
| | | } |
| | | |
| | | private void checkStationIdleRecover(...) { |
| | | // keep candidate scan and idle-track touch |
| | | // delegate the reroute execution to executeReroute(context) |
| | | } |
| | | ``` |
| | | |
| | | Implementation notes: |
| | | - Keep inbound run-block reassign flow intact, including WMS call, source/target loc updates, and task update order. |
| | | - Keep idle recover command cleanup count and log message intact. |
| | | - Preserve run-block lock and idle lock behavior. |
| | | |
| | | - [ ] **Step 4: Re-run the focused tests to verify they pass** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest#runBlockReroute_keepsDirectReassignAndNormalRerouteSeparate,StationOperateProcessUtilsReroutePipelineTest#idleRecover_skipsWhenLastDispatchIsTooRecent test` |
| | | Expected: PASS |
| | | |
| | | - [ ] **Step 5: Commit the final migration** |
| | | |
| | | ```bash |
| | | git add src/main/java/com/zy/core/utils/StationOperateProcessUtils.java src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |
| | | git commit -m "refactor: unify station run-block and idle reroute flow" |
| | | ``` |
| | | |
| | | ### Task 6: Run Full Verification And Clean Up The Diff |
| | | |
| | | **Files:** |
| | | - Modify: `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - Modify: `src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java` |
| | | - Modify: `pom.xml` |
| | | |
| | | - [ ] **Step 1: Run the focused regression test class** |
| | | |
| | | Run: `mvn -q -Dtest=StationOperateProcessUtilsReroutePipelineTest test` |
| | | Expected: PASS |
| | | |
| | | - [ ] **Step 2: Run compile verification** |
| | | |
| | | Run: `mvn -q -DskipTests compile` |
| | | Expected: PASS |
| | | |
| | | - [ ] **Step 3: If test runtime is stable, run the full test command** |
| | | |
| | | Run: `mvn test` |
| | | Expected: PASS, or document the exact blocker if legacy environment/test setup prevents it. |
| | | |
| | | - [ ] **Step 4: Review the final diff against the approved spec** |
| | | |
| | | Checklist: |
| | | - The four public entry methods still exist. |
| | | - `ZyStationV5Thread`, `StationMoveCoordinator`, Redis key names, and WMS interactions are unchanged. |
| | | - Shared reroute flow is centralized. |
| | | - No unrelated business behavior was added. |
| | | |
| | | - [ ] **Step 5: Commit the verified implementation** |
| | | |
| | | ```bash |
| | | git add pom.xml src/main/java/com/zy/core/utils/StationOperateProcessUtils.java src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |
| | | git commit -m "refactor: unify station reroute execution flow" |
| | | ``` |