Files
FTC25009/docs/superpowers/plans/2026-07-14-cargo-area-direction.md

187 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cargo Area Direction 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:** Convert warehouse 03 cargo-area codes from `1`–`8` to `A`–`H`, add configurable access directions, and apply those directions to dense-storage inbound and outbound candidate ordering.
**Architecture:** `bas_cargo_area_config` is the source of truth per warehouse and area. Direction values are `1` (small-to-large), `2` (large-to-small), and `3` (both ends); missing configuration falls back to `1` so other warehouses and existing behavior remain stable. Warehouse 03 cargo spaces are migrated transactionally, and both current allocation SQL paths join the configuration table.
**Tech Stack:** SQL Server, Spring Boot/Java 17, MyBatis XML, Vue 2, JUnit 5/AssertJ, Playwright
---
### Task 1: Define executable migration contracts
**Files:**
- Create: `ruoyi-admin/src/test/java/com/ruoyi/bas/cargospace/mapper/CargoAreaDirectionMigrationSqlTest.java`
- Modify: `ruoyi-admin/src/test/java/com/ruoyi/pda/mapper/PdaMapperSqlTest.java`
- Modify: `ruoyi-admin/src/test/java/com/ruoyi/bas/cargospace/mapper/BasCargoSpaceMapperSqlTest.java`
- [ ] **Step 1: Add migration assertions for table structure, A-H conversion, and seed directions**
```java
assertThat(sql)
.contains("create table dbo.bas_cargo_area_config")
.contains("direction_type")
.contains("nchar(unicode(n'a')")
.contains("n'a'", "n'h'");
```
- [ ] **Step 2: Add mapper assertions for all three direction branches**
```java
assertThat(lockSql)
.contains("bas_cargo_area_config")
.contains("when '1' then")
.contains("when direction_type = '2'")
.contains("when direction_type = '3'");
```
- [ ] **Step 3: Run focused tests before implementation**
Run: `mvn -pl ruoyi-admin -am -Dtest=CargoAreaDirectionMigrationSqlTest,PdaMapperSqlTest,BasCargoSpaceMapperSqlTest -Dsurefire.failIfNoSpecifiedTests=false test`
Expected: FAIL until the migration and mapper ordering exist.
### Task 2: Create and seed cargo-area direction configuration
**Files:**
- Create: `sql/20260714_cargo_area_direction.sql`
- Modify: `sql/20260714_warehouse_03_cargo_spaces.sql`
- [ ] **Step 1: Create the configuration table with a unique warehouse/area key**
```sql
CREATE TABLE dbo.bas_cargo_area_config (
id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
warehouse_id nvarchar(80) NOT NULL,
cargo_area_code nvarchar(10) NOT NULL,
cargo_area_name nvarchar(80) NOT NULL,
direction_type nvarchar(2) NOT NULL,
is_active nchar(1) NOT NULL CONSTRAINT DF_bas_cargo_area_config_active DEFAULT N'1',
create_by nvarchar(64) NULL,
create_time datetime2(3) NULL,
update_by nvarchar(64) NULL,
update_time datetime2(3) NULL,
remark nvarchar(500) NULL,
CONSTRAINT UQ_bas_cargo_area_config UNIQUE (warehouse_id, cargo_area_code),
CONSTRAINT CK_bas_cargo_area_config_direction CHECK (direction_type IN (N'1', N'2', N'3'))
);
```
- [ ] **Step 2: Convert warehouse 03 numeric codes to letters transactionally**
```sql
UPDATE dbo.bas_cargo_space
SET this_cargo_area = NCHAR(UNICODE(N'A') + TRY_CONVERT(int, this_cargo_area) - 1)
WHERE warehouse_id = N'03'
AND TRY_CONVERT(int, this_cargo_area) BETWEEN 1 AND 8;
```
- [ ] **Step 3: Seed A-H with direction `1` to preserve current ordering**
```sql
INSERT INTO dbo.bas_cargo_area_config (warehouse_id, cargo_area_code, cargo_area_name, direction_type, is_active)
SELECT N'03', area_code, area_code + N'货区', N'1', N'1'
FROM (VALUES (N'A'),(N'B'),(N'C'),(N'D'),(N'E'),(N'F'),(N'G'),(N'H')) x(area_code);
```
- [ ] **Step 4: Make the warehouse-03 generator emit A-H directly**
Use `NCHAR(UNICODE(N'A') + area_number - 1)` instead of converting the area number to text.
### Task 3: Apply direction to inbound allocation
**Files:**
- Modify: `ruoyi-admin/src/main/resources/mapper/pda/PdaMapper.xml`
- Modify: `ruoyi-admin/src/main/resources/mapper/bas/BasCargoSpaceMapper.xml`
- [ ] **Step 1: Join active area configuration in the atomic WCS allocator**
```sql
LEFT JOIN bas_cargo_area_config cac
ON cac.warehouse_id = bcs.warehouse_id
AND cac.cargo_area_code = bcs.this_cargo_area
AND cac.is_active = N'1'
```
- [ ] **Step 2: Calculate each area's column bounds and order by direction**
```sql
CASE WHEN direction_type = N'1' THEN the_column END ASC,
CASE WHEN direction_type = N'2' THEN the_column END DESC,
CASE WHEN direction_type = N'3'
THEN CASE WHEN the_column - area_min_column <= area_max_column - the_column
THEN the_column - area_min_column ELSE area_max_column - the_column END
END ASC
```
- [ ] **Step 3: Apply identical fallback ordering to occupied-location reallocation**
Keep height priority and platoon balancing ahead of the direction-specific column order.
### Task 4: Apply direction to outbound inventory candidates
**Files:**
- Modify: `sql/out_stockout_flow.sql`
- [ ] **Step 1: Join area configuration and derive area bounds in manual allocation**
```sql
LEFT JOIN dbo.bas_cargo_area_config cac
ON cac.warehouse_id = bs.warehouse_id
AND cac.cargo_area_code = bcs.this_cargo_area
AND cac.is_active = N'1'
```
- [ ] **Step 2: Put direction ordering before FIFO tie breakers**
Order by configured column direction, then `bs.in_date`, `bs.cargo_space_id`, and `bsd.detail_id`.
- [ ] **Step 3: Apply the same ordering to automatic allocation cursor candidates**
Use the same `1`/`2`/`3` CASE expressions in both outbound procedures.
### Task 5: Update dense-map area labels
**Files:**
- Modify: `ruoyi-ui/src/views/kpi/plan/components/DenseCargoSpaceMap.vue`
- Modify: `scripts/verify_dense_cargo_space_plan.py`
- [ ] **Step 1: Display letter area codes without numeric padding or the old `Z` prefix**
```vue
<span v-if="activeLocation.thisCargoArea">货区 {{ activeLocation.thisCargoArea }}</span>
```
- [ ] **Step 2: Add browser assertions for A-H values**
Click an ordinary node and assert the footer contains `货区 A`–`货区 H`, never `区域 Z`.
### Task 6: Verify and deploy
**Files:**
- Verify: all files above
- [ ] **Step 1: Run focused backend tests**
Run: `mvn -pl ruoyi-admin -am -Dtest=CargoAreaDirectionMigrationSqlTest,PdaMapperSqlTest,BasCargoSpaceMapperSqlTest -Dsurefire.failIfNoSpecifiedTests=false test`
Expected: PASS.
- [ ] **Step 2: Execute the SQL migration in one database transaction**
Expected: warehouse 03 has exactly 1028 ordinary nodes with A-H and eight active configuration rows.
- [ ] **Step 3: Build the frontend**
Run: `cd ruoyi-ui && npm run build:prod`
Expected: build completes successfully.
- [ ] **Step 4: Run the dense-map browser verification**
Run: `python scripts/verify_dense_cargo_space_plan.py`
Expected: both floors render, no overflow occurs, A-H area labels display, and legacy warehouse rendering remains visible.