diff --git a/docs/superpowers/plans/2026-07-24-wms-manual-tidy-capacity.md b/docs/superpowers/plans/2026-07-24-wms-manual-tidy-capacity.md new file mode 100644 index 0000000..a16842d --- /dev/null +++ b/docs/superpowers/plans/2026-07-24-wms-manual-tidy-capacity.md @@ -0,0 +1,161 @@ +# WMS Manual Tidy Capacity 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:** Make WMS use the WCS snapshot only as a dynamic manual-tidy admission signal while WCS remains the sole owner of physical vehicle selection. + +**Architecture:** `TidyVehicleCapacity` combines current healthy online idle vehicles with a configured active-workflow ceiling. `ManualTidyScheduler` starts planner candidates up to that slot count without selecting or persisting a vehicle identifier. Existing schema columns remain for compatibility, but the runtime mapper binding operations are removed. + +**Tech Stack:** Java 17, Spring Boot configuration properties, MyBatis XML, JUnit 5, AssertJ, Mockito, Maven. + +## Global Constraints + +- WCS remains the sole owner of physical vehicle dispatch. +- Keep the WCS snapshot fail-closed: missing or invalid snapshots create zero new manual workflows. +- Add `fortucky.algorithm.tidy-manual-max-concurrency` with default `3`. +- Keep the `alg.tidy_workflow.vehicle_id` database column and diagnostic projection for compatibility. +- Do not change automatic tidy scheduling or WCS APIs. + +--- + +### Task 1: Dynamic Capacity Contract + +**Files:** +- Modify: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacityTest.java` +- Modify: `fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/AlgorithmConfigurationTest.java` +- Modify: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacity.java` +- Modify: `fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/AlgorithmProperties.java` +- Modify: `ruoyi-admin/src/main/resources/application.yml` + +**Interfaces:** +- Produces: `CapacityResult calculate(List vehicles, int activeManualWorkflows, int maxConcurrency)`. +- Produces: `int AlgorithmProperties.getTidyManualMaxConcurrency()` and `void setTidyManualMaxConcurrency(int value)`. + +- [ ] **Step 1: Write failing capacity and default tests** + +Replace assigned-vehicle assertions with literal cases proving: + +```java +assertThat(capacity.calculate(vehiclesWithTwoIdleAndOneBusy, 1, 3).newSlots()).isEqualTo(2); +assertThat(capacity.calculate(threeIdleVehicles, 1, 2).newSlots()).isEqualTo(1); +assertThat(capacity.calculate(threeIdleVehicles, 2, 2).newSlots()).isZero(); +assertThat(capacity.calculate(unavailableVehicles, 0, 3).newSlots()).isZero(); +assertThat(new AlgorithmProperties().getTidyManualMaxConcurrency()).isEqualTo(3); +``` + +- [ ] **Step 2: Run tests and verify RED** + +Run: + +```powershell +mvn -pl ruoyi-admin -am -Dtest=TidyVehicleCapacityTest,AlgorithmConfigurationTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +Expected: test compilation fails because the new capacity signature and property getter do not exist. + +- [ ] **Step 3: Implement the minimal capacity and configuration changes** + +Implement: + +```java +int idle = (int) vehicles.stream().filter(VehicleSnapshot::availableForManualTidy).count(); +int remainingByLimit = Math.max(0, maxConcurrency - Math.max(0, activeManualWorkflows)); +int newSlots = Math.min(idle, remainingByLimit); +``` + +Add `tidyManualMaxConcurrency = 3` plus getter/setter to `AlgorithmProperties`, and bind: + +```yaml +tidy-manual-max-concurrency: ${FORTUCKY_TIDY_MANUAL_MAX_CONCURRENCY:3} +``` + +- [ ] **Step 4: Run focused tests and verify GREEN** + +Run the command from Step 2. Expected: all specified tests pass. + +### Task 2: Scheduler Ownership and Binding Removal + +**Files:** +- Create: `ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ManualTidySchedulerTest.java` +- Modify: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ManualTidyScheduler.java` +- Modify: `ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsAlgorithmMapper.java` +- Modify: `ruoyi-admin/src/main/resources/mapper/algorithm/WmsAlgorithmMapper.xml` + +**Interfaces:** +- Consumes: `TidyVehicleCapacity.calculate(vehicles, activeWorkflows, properties.getTidyManualMaxConcurrency())`. +- Removes: `selectActiveManualTidyVehicleIds` and `assignTidyWorkflowVehicle` runtime mapper operations. + +- [ ] **Step 1: Write a failing scheduler behavior test** + +Create a scheduler with mocked database/external boundaries. Return two healthy idle vehicles, one active workflow, maximum concurrency `3`, and two planner candidates. Assert that `TidyWorkflowTransaction.start` receives both candidates in planner order. The existing implementation starts only one because it subtracts the active workflow from the already-idle snapshot. + +- [ ] **Step 2: Run the scheduler test and verify RED** + +Run: + +```powershell +mvn -pl ruoyi-admin -am -Dtest=ManualTidySchedulerTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +Expected: FAIL because only one workflow is started or compilation fails until the scheduler adopts the new capacity signature. + +- [ ] **Step 3: Implement scheduler ownership changes** + +Remove assigned-vehicle collection and the vehicle iterator. Calculate slots with the configured ceiling, iterate only planner candidates, and call: + +```java +workflows.start(TidyOrigin.MANUAL_TIDY, warehouseId, candidate); +``` + +Do not update a workflow vehicle. Log a candidate-oriented warning if workflow creation fails. + +Remove the two unused vehicle-binding methods from `WmsAlgorithmMapper` and their MyBatis XML statements. Leave the schema column and diagnostics unchanged. + +- [ ] **Step 4: Run focused tidy tests and verify GREEN** + +Run: + +```powershell +mvn -pl ruoyi-admin -am -Dtest=TidyVehicleCapacityTest,ManualTidySchedulerTest,WcsVehicleSnapshotClientTest,AlgorithmConfigurationTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +Expected: all specified tests pass. + +### Task 3: Documentation, Full Verification, and Commit + +**Files:** +- Modify: `docs/superpowers/specs/2026-07-24-wms-manual-tidy-capacity-design.md` only if implementation details changed. +- Modify outside the WMS Git repository: `D:/workSpace/PROJECT_SPACE/FT546/docs/FT546-WMS-history-replay-handoff-2026-07-22.md`. + +**Interfaces:** +- Produces: deployable `ruoyi-admin/target/ruoyi-admin.jar` and an updated handoff record. + +- [ ] **Step 1: Run source and diff checks** + +```powershell +git diff --check +``` + +- [ ] **Step 2: Run the full reactor tests** + +```powershell +mvn test +``` + +Expected: all reactor tests pass with zero failures and errors. + +- [ ] **Step 3: Build the deployment artifact** + +```powershell +mvn -DskipTests package +``` + +Expected: all reactor modules report `SUCCESS`. + +- [ ] **Step 4: Update the handoff record** + +Record the capacity-ownership change, verification totals, JAR size, and current SHA-256. Preserve the existing statement that an actual-WCS read-only snapshot smoke test remains a deployment step. + +- [ ] **Step 5: Review and commit exact files** + +Run `git diff --cached --check`, inspect the complete staged diff, and commit only the implementation, tests, configuration, spec/plan files that belong to this change. Verify `git show --name-status HEAD` after committing.