Junjie
1 天以前 baf1a7a138976f098ddbbf95a9373e0ed4adebe0
docs: add station reroute refactor plan
1个文件已添加
337 ■■■■■ 已修改文件
docs/superpowers/plans/2026-03-24-station-reroute-refactor.md 337 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/superpowers/plans/2026-03-24-station-reroute-refactor.md
New file
@@ -0,0 +1,337 @@
# 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"
```