Files
FTC25009/docs/superpowers/plans/2026-07-16-dense-outbound-relocation-dispatch.md

24 KiB

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<String,Object>), 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.

assertThat(mapperXml)
    .contains("dispatch_status = 'SENDING'")
    .contains("auto_retry_count &lt; 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:

& '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
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.

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
& '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:

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
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<DenseLanePosition> 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
& '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
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<String> createBlockerRelocations(String blockedJobId).

  • Produces: RelocationPreview preview(RelocationGenerateRequest request) and List<String> 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
& '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
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
& '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
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
& '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
& '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
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
& '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
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
& '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
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

& '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
& '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
git add docs/testing/2026-07-16-dense-outbound-relocation-dispatch-report.md
git commit -m "test: verify dense outbound dispatch workflows"