# Dense Outbound Relocation And Dispatch 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:** Add durable WCS outbound retry compensation, dense-lane outermost enforcement, automatic/manual same-floor relocation, and dense-lane outbound workflows without changing existing inbound or non-dense outbound behavior. **Architecture:** Keep `mydo_job` as the business record and add a one-to-one `wcs_job_dispatch` outbox record. Route every outbound push through a single dispatch service that atomically claims attempts and calls a dense-lane eligibility service before selecting a type-specific WCS endpoint. Build relocation and lane-outbound workflows on shared dense-lane queries so automatic allocation, scheduled retry, manual push, location outbound, KPI relocation, and lane outbound enforce the same rules. **Tech Stack:** Java 17, Spring Boot, MyBatis XML, SQL Server, Quartz through RuoYi `sys_job`, JUnit 5/Mockito/AssertJ, Vue 2, Element UI, Maven 3.9.11, npm. ## Global Constraints - Preserve current RuoYi controller/domain/mapper/service/service.impl layering and naming style. - Do not alter the existing inbound WCS pull flow or non-03 warehouse outbound allocation semantics. - Apply dense-lane rules only to warehouse `03` cargo spaces with non-empty `group_coding`. - `in_or_out=23` is relocation and uses `util_serial_task '23'`. - Automatic WCS retries run at most five times after the initial failed call. - Relocation source and destination must be in the same warehouse and same floor, but different channel groups. - All WCS dispatch entry points must enforce current outermost eligibility immediately before the HTTP call. - Use `D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd` for Maven commands. - Use repeatable SQL Server migration statements; do not delete existing business data. --- ### Task 1: Dispatch Outbox Schema And Persistence **Files:** - Create: `sql/20260716_dense_outbound_relocation_dispatch.sql` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dispatch/domain/WcsJobDispatch.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dispatch/mapper/WcsJobDispatchMapper.java` - Create: `ruoyi-admin/src/main/resources/mapper/out/WcsJobDispatchMapper.xml` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/dispatch/mapper/WcsJobDispatchMapperSqlTest.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/in/job/domain/MydoJob.java` - Modify: `ruoyi-admin/src/main/resources/mapper/in/MydoJobMapper.xml` **Interfaces:** - Produces: `WcsJobDispatchMapper.insertIfAbsent(String jobId)`, `selectByJobId(String jobId)`, `selectRetryCandidates(Date now, int limit)`, `claimForSend(Map)`, `markBlocked(Map)`, `markRetryWait(Map)`, `markSuccess(Map)`, and `markExhausted(Map)`. - Produces: non-persistent `MydoJob.dispatchStatus`, `autoRetryCount`, `manualRetryCount`, and `lastDispatchError` populated by list/detail queries. - [ ] **Step 1: Write the failing mapper structure test** Create a JUnit test that reads the mapper XML and migration and asserts the six statuses, the retry-count predicate, atomic `SENDING` claim, dispatch join aliases, ID `23` seed, Quartz invocation, menu permissions, and repeatable `IF NOT EXISTS` guards. ```java assertThat(mapperXml) .contains("dispatch_status = 'SENDING'") .contains("auto_retry_count < 5") .contains("last_dispatch_error"); assertThat(migration) .contains("wcs_job_dispatch") .contains("wcsOutboundRetryTask.retryFailedJobs") .contains("out:denseLaneOutbound:generate"); ``` - [ ] **Step 2: Run the focused test and verify RED** Run: ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=WcsJobDispatchMapperSqlTest test ``` Expected: FAIL because the mapper and migration do not exist. - [ ] **Step 3: Implement the migration, domain, mapper, XML, and job query join** Use exact dispatch constants `PENDING`, `SENDING`, `BLOCKED`, `RETRY_WAIT`, `SUCCESS`, `EXHAUSTED`. The migration creates the table and indexes, inserts task type `23` only when absent, inserts the non-concurrent one-minute Quartz row, and inserts/updates the lane-outbound menu and three permissions. `claimForSend` must update exactly one eligible row and increment either `auto_retry_count` or `manual_retry_count` based on a parameter. - [ ] **Step 4: Run the focused test and verify GREEN** Run the command from Step 2. Expected: PASS. - [ ] **Step 5: Commit** ```powershell git add sql/20260716_dense_outbound_relocation_dispatch.sql ruoyi-admin/src/main/java/com/ruoyi/out/dispatch ruoyi-admin/src/main/resources/mapper/out/WcsJobDispatchMapper.xml ruoyi-admin/src/main/java/com/ruoyi/in/job/domain/MydoJob.java ruoyi-admin/src/main/resources/mapper/in/MydoJobMapper.xml ruoyi-admin/src/test/java/com/ruoyi/out/dispatch/mapper/WcsJobDispatchMapperSqlTest.java git commit -m "feat: add WCS dispatch outbox" ``` ### Task 2: WCS Routing And Durable Dispatch Service **Files:** - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dispatch/service/IOutboundDispatchService.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dispatch/service/impl/OutboundDispatchServiceImpl.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dispatch/domain/DispatchTrigger.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dispatch/task/WcsOutboundRetryTask.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/domain/DispatchEligibility.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/mapper/DenseLaneMapper.java` - Create: `ruoyi-admin/src/main/resources/mapper/out/DenseLaneMapper.xml` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/service/IDenseLaneService.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/service/impl/DenseLaneServiceImpl.java` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/dispatch/service/impl/OutboundDispatchServiceImplTest.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/api/client/WcsClient.java` - Modify: `ruoyi-admin/src/main/resources/application.yml` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/in/job/service/IMydoJobService.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/in/job/service/impl/MydoJobServiceImpl.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/job/controller/OutMydoJobController.java` **Interfaces:** - Produces: `AjaxResult dispatch(String jobId, DispatchTrigger trigger)` where trigger is `INITIAL`, `AUTO_RETRY`, or `MANUAL`. - Produces: `int retryFailedJobs()` for Quartz. - Produces: `WcsClient.sendOutboundTask(MydoJob)`, `sendLocationOutboundTask(MydoJob)`, and `sendRelocationTask(MydoJob)`. - [ ] **Step 1: Write failing service tests** Cover initial failure with count 0, five auto retries then exhausted, manual send past exhaustion, successful status/phase update, atomic claim rejection, and route selection for types 20, 21, and 23. Mock only mapper and WCS boundaries; assert real service decisions. ```java assertThat(service.dispatch("CK1", DispatchTrigger.INITIAL).isSuccess()).isTrue(); verify(dispatchMapper).markRetryWait(argThat(m -> Integer.valueOf(0).equals(m.get("autoRetryCount")))); verify(wcsClient).sendRelocationTask(jobOfType(23L)); ``` - [ ] **Step 2: Run the tests and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=OutboundDispatchServiceImplTest test ``` Expected: FAIL because the dispatch API and WCS methods do not exist. - [ ] **Step 3: Implement dispatch state transitions, the minimal dense eligibility guard, and WCS routes** The service creates the outbox row if absent, delegates dense eligibility to `IDenseLaneService`, claims `SENDING`, calls the type route, records failures without throwing away the business job, and updates `mydo_job.status='3'`, `execution_phase='1'`, `start_time` only after success. The minimal dense mapper answers whether the job source is the current outermost occupied cargo position; non-03 or non-dense jobs are immediately eligible. Add `PUT /out/job/pushWcs/{jobId}` as the manual trigger backed by this service. Configure: ```yaml sendRetrieveTask: ${WCS_OUTBOUND_PATH:/wcs/api/receiveWmsOutJob} sendLocationOutboundTask: ${WCS_LOCATION_OUTBOUND_PATH:/wcs/api/receiveWmsLocationOutJob} sendRelocationTask: ${WCS_RELOCATION_PATH:/wcs/api/receiveWmsMoveJob} ``` - [ ] **Step 4: Run the tests and verify GREEN** Run Step 2. Expected: PASS. - [ ] **Step 5: Commit** ```powershell git add ruoyi-admin/src/main/java/com/ruoyi/out/dispatch ruoyi-admin/src/main/java/com/ruoyi/api/client/WcsClient.java ruoyi-admin/src/main/resources/application.yml ruoyi-admin/src/main/java/com/ruoyi/in/job ruoyi-admin/src/main/java/com/ruoyi/out/job/controller/OutMydoJobController.java ruoyi-admin/src/test/java/com/ruoyi/out/dispatch/service/impl/OutboundDispatchServiceImplTest.java git commit -m "feat: add outbound WCS retry dispatch" ``` ### Task 3: Dense Lane Geometry And Eligibility **Files:** - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/domain/DenseLanePosition.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/domain/DenseRelocationCandidate.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/mapper/DenseLaneMapper.java` - Modify: `ruoyi-admin/src/main/resources/mapper/out/DenseLaneMapper.xml` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/service/IDenseLaneService.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/service/impl/DenseLaneServiceImpl.java` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/dense/service/impl/DenseLaneServiceImplTest.java` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/dense/mapper/DenseLaneMapperSqlTest.java` **Interfaces:** - Produces: `DispatchEligibility checkDispatchEligibility(MydoJob job)`. - Produces: `List selectBlockersForUpdate(String cargoSpaceId)` ordered outer-to-inner. - Produces: `BasCargoSpace selectRelocationTargetForUpdate(RelocationTargetQuery query)`. - Produces: lane summary, tray preview, and inventory detail queries consumed by Tasks 6 and 7. - [ ] **Step 1: Write failing direction and SQL tests** Assert direction 1 treats the maximum occupied column as outermost, direction 2 treats the minimum as outermost, direction 3 uses nearest boundary, non-03 jobs bypass the rule, blockers exclude trays already covered by active outbound jobs, and destination SQL enforces same floor and different `group_coding`. - [ ] **Step 2: Run focused tests and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=DenseLaneServiceImplTest,DenseLaneMapperSqlTest test ``` Expected: FAIL because dense-lane classes do not exist. - [ ] **Step 3: Implement pure ordering helpers and locked mapper queries** Centralize direction ordering in one service. SQL uses `UPDLOCK,HOLDLOCK` for blocker/destination selection, treats cargo statuses 2/3/4 with tray codes as occupied, excludes active jobs for destination reservations, and joins stock profiles used by current inbound rules. - [ ] **Step 4: Run tests and verify GREEN** Run Step 2. Expected: PASS. - [ ] **Step 5: Commit** ```powershell git add ruoyi-admin/src/main/java/com/ruoyi/out/dense ruoyi-admin/src/main/resources/mapper/out/DenseLaneMapper.xml ruoyi-admin/src/test/java/com/ruoyi/out/dense git commit -m "feat: enforce dense lane outermost order" ``` ### Task 4: Relocation Job Generation And Completion **Files:** - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/relocation/domain/RelocationGenerateRequest.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/relocation/domain/RelocationPreview.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/relocation/mapper/RelocationJobMapper.java` - Create: `ruoyi-admin/src/main/resources/mapper/out/RelocationJobMapper.xml` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/relocation/service/IRelocationJobService.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/relocation/service/impl/RelocationJobServiceImpl.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/relocation/controller/RelocationJobController.java` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/relocation/service/impl/RelocationJobServiceImplTest.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/api/controller/ExternalApiController.java` **Interfaces:** - Produces: `List createBlockerRelocations(String blockedJobId)`. - Produces: `RelocationPreview preview(RelocationGenerateRequest request)` and `List generate(RelocationGenerateRequest request)`. - Produces: `AjaxResult completeFromWcs(String jobId)`. - [ ] **Step 1: Write failing relocation tests** Cover type 23/task sequence, one main job per tray, one detail per stock detail, same-floor/different-lane rejection, source status 4/target status 3 reservation, all-or-nothing capacity validation, completion inventory move, cargo status swap, archive, duplicate callback, and dispatch wake-up after commit. - [ ] **Step 2: Run test and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=RelocationJobServiceImplTest test ``` Expected: FAIL because relocation service does not exist. - [ ] **Step 3: Implement transactional generation and completion** Use `@Transactional(rollbackFor = Exception.class)`. Generate blockers outer-to-inner, reserve all destinations before inserting jobs, copy stock trace fields into job details, and create dispatch rows. On completion, lock and validate active type 23, update every `bas_stock` row for the tray, switch cargo statuses, archive job/detail with explicit column lists, delete active rows, then dispatch the next eligible source-lane job after commit. - [ ] **Step 4: Route WCS completion by type** In `ExternalApiController.completeOutbound`, type 23 calls `relocationJobService.completeFromWcs`; all other outbound types keep current phase-5/PDA behavior. - [ ] **Step 5: Run tests and verify GREEN** Run Step 2. Expected: PASS. - [ ] **Step 6: Commit** ```powershell git add ruoyi-admin/src/main/java/com/ruoyi/out/relocation ruoyi-admin/src/main/resources/mapper/out/RelocationJobMapper.xml ruoyi-admin/src/main/java/com/ruoyi/api/controller/ExternalApiController.java ruoyi-admin/src/test/java/com/ruoyi/out/relocation git commit -m "feat: add dense warehouse relocation jobs" ``` ### Task 5: Integrate Existing Outbound Allocation And Location Outbound **Files:** - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/stockout/service/impl/OutStockoutServiceImpl.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/out/location/service/impl/LocationOutboundServiceImpl.java` - Modify: `ruoyi-admin/src/test/java/com/ruoyi/out/stockout/service/impl/OutStockoutServiceImplTest.java` - Modify: `ruoyi-admin/src/test/java/com/ruoyi/out/location/service/impl/LocationOutboundServiceImplTest.java` **Interfaces:** - Consumes: relocation blocker generation and unified dispatch from Tasks 2 and 4. - Produces: allocation responses that distinguish dispatched, queued-for-retry, and blocked-by-relocation jobs. - [ ] **Step 1: Add failing integration-unit tests** Assert auto/manual allocation no longer calls `MydoJobService.pushOutJobToWcs`, specified stock allocation creates blocker relocations before dispatch, normal non-03 allocation dispatches directly, location outbound creates relocations for non-outbound full blockers, and WCS failure returns business success with compensation message. - [ ] **Step 2: Run tests and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=OutStockoutServiceImplTest,LocationOutboundServiceImplTest test ``` - [ ] **Step 3: Replace direct push calls with prepare-and-dispatch orchestration** After each successful database allocation, call blocker generation for the selected job, create dispatch rows for every new job, and dispatch only currently eligible jobs. Keep existing non-dense procedure behavior and stock-status filters unchanged. - [ ] **Step 4: Run tests and verify GREEN** Run Step 2. Expected: PASS. - [ ] **Step 5: Commit** ```powershell git add ruoyi-admin/src/main/java/com/ruoyi/out/stockout/service/impl/OutStockoutServiceImpl.java ruoyi-admin/src/main/java/com/ruoyi/out/location/service/impl/LocationOutboundServiceImpl.java ruoyi-admin/src/test/java/com/ruoyi/out/stockout ruoyi-admin/src/test/java/com/ruoyi/out/location git commit -m "feat: prepare dense blockers during outbound allocation" ``` ### Task 6: KPI Dense Plan Manual Relocation **Files:** - Modify: `ruoyi-admin/src/main/java/com/ruoyi/kpi/controller/KpiController.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/kpi/service/KpiService.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/kpi/service/impl/KpiServiceImpl.java` - Modify: `ruoyi-ui/src/api/kpi/kpi.js` - Modify: `ruoyi-ui/src/views/kpi/plan/index.vue` - Modify: `ruoyi-ui/src/views/kpi/plan/components/DenseCargoSpaceMap.vue` - Create: `ruoyi-admin/src/test/java/com/ruoyi/kpi/service/impl/KpiDenseRelocationServiceTest.java` **Interfaces:** - Produces: `GET /kpi/denseRelocation/options`, `POST /kpi/denseRelocation/preview`, and `POST /kpi/denseRelocation/generate`. - [ ] **Step 1: Write failing controller/service tests** Assert only warehouse 03 is accepted, target lane floor equals source/current floor, options require sufficient compatible capacity, preview returns exact outer trays and inventory totals, and generate revalidates state. - [ ] **Step 2: Run Java tests and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=KpiDenseRelocationServiceTest test ``` - [ ] **Step 3: Implement backend endpoints and existing-style UI** Add a compact “指定移库” button to the dense toolbar. Use an Element UI dialog with source lane, numeric tray count, target lane, and a fixed-height preview table. Do not add decorative cards or alter map dimensions. Refresh map data after successful generation. - [ ] **Step 4: Run Java tests and production UI build** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=KpiDenseRelocationServiceTest test Set-Location ruoyi-ui npm run build:prod ``` Expected: tests PASS and Vue build exits 0. - [ ] **Step 5: Commit** ```powershell git add ruoyi-admin/src/main/java/com/ruoyi/kpi ruoyi-admin/src/test/java/com/ruoyi/kpi ruoyi-ui/src/api/kpi/kpi.js ruoyi-ui/src/views/kpi/plan git commit -m "feat: add KPI dense lane relocation" ``` ### Task 7: Dense Lane Outbound Menu And Workflow **Files:** - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/controller/DenseLaneOutboundController.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/domain/DenseLaneOutboundQuery.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/domain/DenseLaneOutboundRequest.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/domain/DenseLaneSummary.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/service/IDenseLaneOutboundService.java` - Create: `ruoyi-admin/src/main/java/com/ruoyi/out/dense/service/impl/DenseLaneOutboundServiceImpl.java` - Create: `ruoyi-ui/src/api/out/denseLaneOutbound.js` - Create: `ruoyi-ui/src/views/out/denseLaneOutbound/index.vue` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/dense/service/impl/DenseLaneOutboundServiceImplTest.java` **Interfaces:** - Produces: `GET /out/denseLaneOutbound/list`, `GET /out/denseLaneOutbound/preview`, and `POST /out/denseLaneOutbound/generate`. - [ ] **Step 1: Write failing service tests** Assert list groups only full 03 dense lanes, totals all stock details per tray, preview selects exactly outermost N unreserved trays, quantity over capacity fails, stale preview fails generation, exit compatibility is validated, and every generated type-20 job contains the selected tray's complete inventory details. - [ ] **Step 2: Run tests and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=DenseLaneOutboundServiceImplTest test ``` - [ ] **Step 3: Implement backend and menu page** Use the migration permissions from Task 1. The page displays group code, area, row, floor, full/available tray counts, total stock, current outer tray, and expandable inventory details. Generation dialog uses an integer stepper, exit selector, and preview table showing exact trays and quantities. - [ ] **Step 4: Verify tests and UI build** Run Task 6 Step 4 with `DenseLaneOutboundServiceImplTest`. Expected: PASS and build exit 0. - [ ] **Step 5: Commit** ```powershell git add ruoyi-admin/src/main/java/com/ruoyi/out/dense ruoyi-admin/src/test/java/com/ruoyi/out/dense ruoyi-ui/src/api/out/denseLaneOutbound.js ruoyi-ui/src/views/out/denseLaneOutbound sql/20260716_dense_outbound_relocation_dispatch.sql git commit -m "feat: add dense lane outbound workflow" ``` ### Task 8: Outbound Job Management Dispatch UI **Files:** - Modify: `ruoyi-ui/src/api/out/job.js` - Modify: `ruoyi-ui/src/views/out/job/index.vue` - Modify: `sql/20260716_dense_outbound_relocation_dispatch.sql` - Create: `ruoyi-admin/src/test/java/com/ruoyi/out/job/controller/OutMydoJobDispatchControllerTest.java` **Interfaces:** - Consumes: dispatch fields and `PUT /out/job/pushWcs/{jobId}`. - [ ] **Step 1: Write failing controller permission/state test** Assert the endpoint requires `out:job:pushWcs`, delegates with `MANUAL`, rejects completed jobs, and returns blocked reason without calling WCS when a dense job is not outermost. - [ ] **Step 2: Run test and verify RED** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -Dtest=OutMydoJobDispatchControllerTest test ``` - [ ] **Step 3: Implement UI columns and manual action** Add WCS status, automatic retry count, and last-error tooltip columns. Use the existing send icon button with tooltip “手动下发 WCS”, permission `out:job:pushWcs`, and a confirmation message containing attempts and last error. Show it for pending, retry-wait, exhausted, and blocked active jobs; backend remains authoritative. - [ ] **Step 4: Verify controller and UI build** Run Step 2 and `npm run build:prod`. Expected: PASS and build exit 0. - [ ] **Step 5: Commit** ```powershell git add ruoyi-admin/src/test/java/com/ruoyi/out/job ruoyi-ui/src/api/out/job.js ruoyi-ui/src/views/out/job/index.vue sql/20260716_dense_outbound_relocation_dispatch.sql git commit -m "feat: add manual WCS dispatch action" ``` ### Task 9: Full Regression, Migration, And Runtime Scenarios **Files:** - Create: `docs/testing/2026-07-16-dense-outbound-relocation-dispatch-report.md` **Interfaces:** - Verifies all interfaces produced above as one workflow. - [ ] **Step 1: Run all backend tests** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' -pl ruoyi-admin -am test ``` Expected: BUILD SUCCESS with zero test failures. - [ ] **Step 2: Run backend package and frontend production build** ```powershell & 'D:\BDevTools\maven\apache-maven-3.9.11\bin\mvn.cmd' clean package -DskipTests Set-Location ruoyi-ui npm run build:prod ``` Expected: both commands exit 0. - [ ] **Step 3: Apply migration to the configured disposable/local database** Execute `sql/20260716_dense_outbound_relocation_dispatch.sql` twice. Expected: both runs succeed, one task type 23 row, one Quartz task, one menu, three button permissions, and no duplicate indexes. - [ ] **Step 4: Run runtime integration scenarios** Verify with controlled WCS mock responses: initial failure plus five retries reaches exhausted; manual recovery succeeds; direction-1 and direction-2 lanes reject inner jobs; blocker relocation completes source/target inventory atomically; location outbound creates blockers; KPI manual relocation stays same-floor; lane outbound selects exactly outer N; non-03 outbound remains direct. - [ ] **Step 5: Verify UI with Playwright screenshots** Check outbound job management, KPI relocation dialog, and dense lane outbound page at desktop and mobile/narrow viewports. Verify no overlap, clipped button text, blank table, or broken dialog sizing. - [ ] **Step 6: Write the report and run requirement audit** Record commands, counts, screenshots, created job IDs, retry transitions, relocation source/target IDs, lane outbound selections, and residual risks. Map each of the six user requirements to direct evidence. - [ ] **Step 7: Commit the verification report** ```powershell git add docs/testing/2026-07-16-dense-outbound-relocation-dispatch-report.md git commit -m "test: verify dense outbound dispatch workflows" ```