8.0 KiB
Project Number Traceability 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 a standalone project_no field and preserve it from inbound document creation through inbound details, job details, and inventory master/detail records.
Architecture: The inbound master form is the single input point. The backend copies the master value to every inbound detail, SQL Server procedures carry the detail value into job details and inventory rows, and Java/MyBatis models expose the value consistently as projectNo. Archive tables receive the same column because current completion procedures archive with INSERT ... SELECT *.
Tech Stack: Vue 2 + Element UI, Spring Boot/Java 17, MyBatis XML, SQL Server, JUnit 5/Mockito/AssertJ
Task 1: Lock down the project-number propagation contract
Files:
-
Modify:
ruoyi-admin/src/test/java/com/ruoyi/in/stockin/service/impl/InStockinServiceImplTest.java -
Modify:
ruoyi-admin/src/test/java/com/ruoyi/in/job/mapper/MydoJobMapperSqlTest.java -
Create:
ruoyi-admin/src/test/java/com/ruoyi/in/stockin/mapper/ProjectNoMapperSqlTest.java -
Step 1: Add a service test that verifies the master project number is copied to each inbound detail
saveDTO.setProjectNo("PRJ-001");
service.saveInStockinWithDetails(saveDTO);
assertThat(detailCaptor.getValue().getProjectNo()).isEqualTo("PRJ-001");
- Step 2: Add mapper/procedure text tests for all required columns and transfers
assertThat(inStockinMapperXml).contains("project_no", "#{projectNo}");
assertThat(jobDetailMapperXml).contains("project_no", "#{projectNo}");
assertThat(stockMapperXml).contains("project_no", "#{projectNo}");
assertThat(projectMigrationSql)
.contains("in_stockin", "in_stockin_detail", "mydo_job_detail")
.contains("bas_stock", "bas_stock_detail");
- Step 3: Run focused tests and verify they fail before implementation
Run: mvn -pl ruoyi-admin -Dtest=InStockinServiceImplTest,ProjectNoMapperSqlTest,MydoJobMapperSqlTest test
Expected: FAIL because projectNo properties, SQL mappings, and migration do not exist yet.
Task 2: Add the database migration and procedure propagation
Files:
-
Create:
sql/20260714_project_no_traceability.sql -
Modify:
sql/proc_add_in_job_trace.sql -
Modify:
sql/bas_stock_master_detail.sql -
Step 1: Add nullable project-number columns idempotently
IF COL_LENGTH(N'dbo.in_stockin', N'project_no') IS NULL
ALTER TABLE dbo.in_stockin ADD project_no nvarchar(80) NULL;
Repeat for in_stockin_detail, in_stockin_finish, in_stockin_detail_finish, mydo_job_detail, mydo_job_detail_finish, bas_stock, and bas_stock_detail.
- Step 2: Backfill existing traceable rows
UPDATE d
SET d.project_no = h.project_no
FROM dbo.in_stockin_detail d
JOIN dbo.in_stockin h ON h.stockin_id = d.stockin_id
WHERE d.project_no IS NULL AND h.project_no IS NOT NULL;
Backfill job details from inbound details, inventory details from job/inbound details, and inventory masters from their inventory details.
- Step 3: Update
proc_add_in_jobto copyin_stockin_detail.project_nointomydo_job_detail.project_no
SELECT ..., d.project_no
FROM dbo.in_tray_msg tm
LEFT JOIN dbo.in_stockin_detail d ON tm.stockin_detail_id = d.stockin_detail_id;
INSERT INTO dbo.mydo_job_detail (..., project_no)
VALUES (..., @project_no);
- Step 4: Update
proc_complete_in_jobto copy the job detail project number into inventory master and detail rows
INSERT INTO bas_stock (..., project_no)
VALUES (..., @project_no);
INSERT INTO bas_stock_detail (..., project_no)
VALUES (..., @project_no);
- Step 5: Keep baseline procedure scripts consistent with the deployable migration
Update the existing standalone procedure scripts with the same cursor variables, selected columns, and insert columns.
Task 3: Expose projectNo in backend entities and MyBatis mappings
Files:
-
Modify:
ruoyi-admin/src/main/java/com/ruoyi/in/stockin/domain/InStockin.java -
Modify:
ruoyi-admin/src/main/java/com/ruoyi/in/sotckindetail/domain/InStockinDetail.java -
Modify:
ruoyi-admin/src/main/java/com/ruoyi/in/jobdetail/domain/MydoJobDetail.java -
Modify:
ruoyi-admin/src/main/java/com/ruoyi/bas/stock/domain/BasStock.java -
Modify:
ruoyi-admin/src/main/java/com/ruoyi/bas/stock/domain/BasStockDetail.java -
Modify:
ruoyi-admin/src/main/resources/mapper/in/InStockinMapper.xml -
Modify:
ruoyi-admin/src/main/resources/mapper/in/InStockinDetailMapper.xml -
Modify:
ruoyi-admin/src/main/resources/mapper/in/MydoJobDetailMapper.xml -
Modify:
ruoyi-admin/src/main/resources/mapper/bas/BasStockMapper.xml -
Modify:
ruoyi-admin/src/main/resources/mapper/bas/BasStockDetailMapper.xml -
Step 1: Add the Java property to all five domain models
/** 项目号 */
@Excel(name = "项目号")
private String projectNo;
public String getProjectNo() { return projectNo; }
public void setProjectNo(String projectNo) { this.projectNo = projectNo; }
- Step 2: Add
project_noto every result map, select list, query filter, insert, and update section
<result property="projectNo" column="project_no" />
<if test="projectNo != null and projectNo != ''">project_no,</if>
<if test="projectNo != null and projectNo != ''">#{projectNo},</if>
- Step 3: Run mapper contract tests
Run: mvn -pl ruoyi-admin -Dtest=ProjectNoMapperSqlTest test
Expected: PASS.
Task 4: Copy the master project number to inbound details and support the create form
Files:
-
Modify:
ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/impl/InStockinServiceImpl.java -
Modify:
ruoyi-ui/src/views/in/add/index.vue -
Step 1: Enforce server-side master-to-detail copying
detail.setStockinId(saveDTO.getStockinId());
detail.setProjectNo(saveDTO.getProjectNo());
- Step 2: Add the project-number input to the main inbound form
<el-form-item label="项目号" prop="projectNo">
<el-input v-model="mainForm.projectNo" placeholder="请输入项目号" clearable />
</el-form-item>
- Step 3: Include
projectNoin the form model and detail payload
mainForm: { projectNo: null }
// detail DTO
projectNo: this.mainForm.projectNo
- Step 4: Run the inbound service test
Run: mvn -pl ruoyi-admin -Dtest=InStockinServiceImplTest test
Expected: PASS and the captured detail contains the master projectNo.
Task 5: Preserve project number when jobs are created from existing inventory
Files:
-
Modify:
ruoyi-admin/src/main/java/com/ruoyi/out/location/service/impl/LocationOutboundServiceImpl.java -
Modify:
ruoyi-admin/src/main/java/com/ruoyi/pd/stockpd/service/impl/PdStockpdServiceImpl.java -
Modify:
ruoyi-admin/src/main/java/com/ruoyi/pda/service/impl/PdaServiceImpl.java -
Step 1: Copy inventory-detail project numbers into outbound and inventory job details
jobDetail.setProjectNo(stockDetail.getProjectNo());
- Step 2: Include
projectNoin inventory material map queries used for return jobs and copy it into return-job details
returnDetail.setProjectNo(mapString(material, "projectNo"));
- Step 3: Run focused service tests
Run: mvn -pl ruoyi-admin -Dtest=LocationOutboundServiceImplTest,PdStockpdServiceImplTest,PdaServiceImplTest test
Expected: PASS.
Task 6: Verify the end-to-end change
Files:
-
Verify: all files listed above
-
Step 1: Run all backend tests
Run: mvn -pl ruoyi-admin test
Expected: BUILD SUCCESS.
- Step 2: Build the frontend production bundle
Run: cd ruoyi-ui && npm run build:prod
Expected: Build completes successfully.
- Step 3: Inspect the final diff for unrelated or overwritten work
Run: git diff --check && git status --short
Expected: no whitespace errors; existing user changes remain intact.