diff --git a/docs/superpowers/plans/2026-05-18-dto-request-result-refactor.md b/docs/superpowers/plans/2026-05-18-dto-request-result-refactor.md new file mode 100644 index 0000000..3465d4c --- /dev/null +++ b/docs/superpowers/plans/2026-05-18-dto-request-result-refactor.md @@ -0,0 +1,414 @@ +# DTO And RequestResult Refactor 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:** 将现有枚举、附件、RAG 三块接口统一改造成 DTO 入参与 DTO 返回,并引入 `RequestResult` 作为统一响应包装。 + +**Architecture:** `controller`、`service`、`mapper` 三层都尽量以 DTO 作为边界对象,实体类仅用于 MyBatis-Plus 持久化与表映射。控制层统一返回 `RequestResult`,查询条件走 request/query DTO,列表和详情都返回 response DTO,避免继续直接暴露实体和零散参数。 + +**Tech Stack:** Java 21、Spring Boot 4、MyBatis-Plus、Spring MVC、JUnit 5 + +--- + +### Task 1: 建立统一响应体和 DTO 包结构 + +**Files:** +- Create: `src/main/java/com/bruce/common/dto/RequestResult.java` +- Create: `src/main/java/com/bruce/common/dto/request/` +- Create: `src/main/java/com/bruce/common/dto/response/` +- Create: `src/main/java/com/bruce/rag/dto/request/` +- Create: `src/main/java/com/bruce/rag/dto/response/` +- Modify: `src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java` +- Modify: `src/test/java/com/bruce/rag/RagComponentStructureTests.java` + +- [ ] **Step 1: 写失败测试,固定统一返回体存在且控制层不再暴露裸实体** + + 在结构测试中增加如下断言思路: + + ```java + Method saveOrUpdateMethod = SysEnumController.class.getMethod("saveOrUpdate", SysEnumSaveRequest.class); + assertEquals(RequestResult.class, saveOrUpdateMethod.getReturnType()); + ``` + + ```java + Method listMethod = RagStoreController.class.getMethod("list", RagStoreQueryRequest.class); + assertEquals(RequestResult.class, listMethod.getReturnType()); + ``` + +- [ ] **Step 2: 运行测试并确认失败** + + Run: `.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests,RagComponentStructureTests" test` + + Expected: FAIL,提示 DTO 或 `RequestResult` 类型不存在,或控制器方法签名不匹配。 + +- [ ] **Step 3: 最小化实现统一响应体和基础 DTO 目录** + + `RequestResult.java` 采用如下结构: + + ```java + @Data + @NoArgsConstructor + @AllArgsConstructor + public class RequestResult { + private boolean success; + private String code; + private String message; + private T data; + + public static RequestResult success(T data) { + return new RequestResult<>(true, "SUCCESS", "操作成功", data); + } + + public static RequestResult success(String message, T data) { + return new RequestResult<>(true, "SUCCESS", message, data); + } + + public static RequestResult failure(String code, String message) { + return new RequestResult<>(false, code, message, null); + } + } + ``` + +- [ ] **Step 4: 运行测试并确认通过** + + Run: `.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests,RagComponentStructureTests" test` + + Expected: PASS 或只剩下后续控制器签名相关失败。 + +- [ ] **Step 5: Commit** + + ```bash + git add src/main/java/com/bruce/common/dto src/main/java/com/bruce/rag/dto src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java src/test/java/com/bruce/rag/RagComponentStructureTests.java + git commit -m "refactor: 增加统一响应体与DTO结构" + ``` + +### Task 2: 重构 sys_enum 模块为 DTO 入参与 DTO 返回 + +**Files:** +- Create: `src/main/java/com/bruce/common/dto/request/SysEnumQueryRequest.java` +- Create: `src/main/java/com/bruce/common/dto/request/SysEnumSaveRequest.java` +- Create: `src/main/java/com/bruce/common/dto/response/SysEnumResponse.java` +- Modify: `src/main/java/com/bruce/common/controller/SysEnumController.java` +- Modify: `src/main/java/com/bruce/common/service/ISysEnumService.java` +- Modify: `src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java` +- Modify: `src/main/java/com/bruce/common/mapper/SysEnumMapper.java` +- Modify: `src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java` + +- [ ] **Step 1: 写失败测试,固定 sys_enum 控制器和服务都使用 DTO** + + 在 `SysEnumComponentStructureTests` 中增加断言: + + ```java + Method queryMethod = SysEnumController.class.getMethod("queryByCatalogAndType", SysEnumQueryRequest.class); + Method saveMethod = SysEnumController.class.getMethod("saveOrUpdate", SysEnumSaveRequest.class); + Method serviceMethod = ISysEnumService.class.getMethod("listByCatalogAndType", SysEnumQueryRequest.class); + ``` + +- [ ] **Step 2: 运行测试并确认失败** + + Run: `.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests" test` + + Expected: FAIL,提示方法签名仍然是 `String` 或 `SysEnum`。 + +- [ ] **Step 3: 最小化实现 request/response DTO** + + `SysEnumQueryRequest.java`: + + ```java + @Data + public class SysEnumQueryRequest { + private String catalog; + private String type; + } + ``` + + `SysEnumSaveRequest.java`: + + ```java + @Data + public class SysEnumSaveRequest { + private Long id; + private String catalog; + private String type; + private String name; + private Integer value; + private String strvalue; + private Integer sort; + private String remark; + } + ``` + + `SysEnumResponse.java`: + + ```java + @Data + public class SysEnumResponse { + private Long id; + private String catalog; + private String type; + private String name; + private Integer value; + private String strvalue; + private Integer sort; + private String remark; + } + ``` + +- [ ] **Step 4: 修改 mapper/service/controller** + + - `ISysEnumService` 返回 `List`,保存返回 `SysEnumResponse` + - `SysEnumServiceImpl` 新增 DTO 与实体互转私有方法 + - `SysEnumMapper` 保留 MP 基础能力;如需自定义查询,新增 DTO 查询方法签名 + - `SysEnumController` 所有接口返回 `RequestResult` + + 控制器目标形态: + + ```java + @PostMapping("/query") + public RequestResult> queryByCatalogAndType(@RequestBody SysEnumQueryRequest request) { + return RequestResult.success(sysEnumService.listByCatalogAndType(request)); + } + ``` + +- [ ] **Step 5: 运行测试并确认通过** + + Run: `.\mvnw.cmd "-Dtest=SysEnumComponentStructureTests" test` + + Expected: PASS + +- [ ] **Step 6: Commit** + + ```bash + git add src/main/java/com/bruce/common/controller/SysEnumController.java src/main/java/com/bruce/common/service/ISysEnumService.java src/main/java/com/bruce/common/service/impl/SysEnumServiceImpl.java src/main/java/com/bruce/common/dto/request/SysEnumQueryRequest.java src/main/java/com/bruce/common/dto/request/SysEnumSaveRequest.java src/main/java/com/bruce/common/dto/response/SysEnumResponse.java src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java + git commit -m "refactor: 调整sys_enum接口为DTO模式" + ``` + +### Task 3: 重构 sys_attachment 模块为 DTO 入参与 DTO 返回 + +**Files:** +- Create: `src/main/java/com/bruce/common/dto/request/SysAttachmentUploadRequest.java` +- Create: `src/main/java/com/bruce/common/dto/request/SysAttachmentQueryRequest.java` +- Create: `src/main/java/com/bruce/common/dto/response/SysAttachmentResponse.java` +- Modify: `src/main/java/com/bruce/common/controller/SysAttachmentController.java` +- Modify: `src/main/java/com/bruce/common/service/ISysAttachmentService.java` +- Modify: `src/main/java/com/bruce/common/service/impl/SysAttachmentServiceImpl.java` +- Modify: `src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java` + +- [ ] **Step 1: 写失败测试,固定附件接口返回 `RequestResult` 且 service 返回 DTO** + + 示例断言: + + ```java + Method uploadMethod = SysAttachmentController.class.getMethod("upload", MultipartFile.class, SysAttachmentUploadRequest.class); + assertEquals(RequestResult.class, uploadMethod.getReturnType()); + ``` + +- [ ] **Step 2: 运行测试并确认失败** + + Run: `.\mvnw.cmd "-Dtest=SysAttachmentComponentStructureTests" test` + + Expected: FAIL,提示控制器或服务方法签名不匹配。 + +- [ ] **Step 3: 新增附件 DTO** + + `SysAttachmentUploadRequest.java`: + + ```java + @Data + public class SysAttachmentUploadRequest { + private String sourceType; + private Long sourceId; + } + ``` + + `SysAttachmentQueryRequest.java`: + + ```java + @Data + public class SysAttachmentQueryRequest { + private String sourceType; + private Long sourceId; + } + ``` + + `SysAttachmentResponse.java`: + + ```java + @Data + public class SysAttachmentResponse { + private Long id; + private String sourceType; + private Long sourceId; + private String originalName; + private String fileName; + private String fileSuffix; + private String contentType; + private Long fileSize; + private String storageType; + private String filePath; + private String fileUrl; + private String remark; + } + ``` + +- [ ] **Step 4: 修改附件控制器和服务** + + - `ISysAttachmentService.upload` 返回 `SysAttachmentResponse` + - 控制器上传接口返回 `RequestResult` + - 如补充列表查询,也走 `SysAttachmentQueryRequest` + +- [ ] **Step 5: 运行测试并确认通过** + + Run: `.\mvnw.cmd "-Dtest=SysAttachmentComponentStructureTests" test` + + Expected: PASS + +- [ ] **Step 6: Commit** + + ```bash + git add src/main/java/com/bruce/common/controller/SysAttachmentController.java src/main/java/com/bruce/common/service/ISysAttachmentService.java src/main/java/com/bruce/common/service/impl/SysAttachmentServiceImpl.java src/main/java/com/bruce/common/dto/request/SysAttachmentUploadRequest.java src/main/java/com/bruce/common/dto/request/SysAttachmentQueryRequest.java src/main/java/com/bruce/common/dto/response/SysAttachmentResponse.java src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java + git commit -m "refactor: 调整附件接口为DTO模式" + ``` + +### Task 4: 重构 rag_store 与 rag_document 模块为 DTO 入参与 DTO 返回 + +**Files:** +- Create: `src/main/java/com/bruce/rag/dto/request/RagStoreQueryRequest.java` +- Create: `src/main/java/com/bruce/rag/dto/request/RagStoreSaveRequest.java` +- Create: `src/main/java/com/bruce/rag/dto/request/RagDocumentQueryRequest.java` +- Create: `src/main/java/com/bruce/rag/dto/request/RagDocumentSaveRequest.java` +- Create: `src/main/java/com/bruce/rag/dto/response/RagStoreResponse.java` +- Create: `src/main/java/com/bruce/rag/dto/response/RagDocumentResponse.java` +- Modify: `src/main/java/com/bruce/rag/controller/RagStoreController.java` +- Modify: `src/main/java/com/bruce/rag/controller/RagDocumentController.java` +- Modify: `src/main/java/com/bruce/rag/service/IRagStoreService.java` +- Modify: `src/main/java/com/bruce/rag/service/IRagDocumentService.java` +- Modify: `src/main/java/com/bruce/rag/service/impl/RagStoreServiceImpl.java` +- Modify: `src/main/java/com/bruce/rag/service/impl/RagDocumentServiceImpl.java` +- Modify: `src/test/java/com/bruce/rag/RagComponentStructureTests.java` + +- [ ] **Step 1: 写失败测试,固定 RAG 控制器和服务都使用 DTO** + + 示例断言: + + ```java + Method storeListMethod = RagStoreController.class.getMethod("list", RagStoreQueryRequest.class); + Method documentListMethod = RagDocumentController.class.getMethod("list", RagDocumentQueryRequest.class); + assertEquals(RequestResult.class, storeListMethod.getReturnType()); + assertEquals(RequestResult.class, documentListMethod.getReturnType()); + ``` + +- [ ] **Step 2: 运行测试并确认失败** + + Run: `.\mvnw.cmd "-Dtest=RagComponentStructureTests" test` + + Expected: FAIL,提示控制器和 service 仍然暴露实体或无 DTO。 + +- [ ] **Step 3: 新增 RAG DTO** + + `RagStoreQueryRequest.java`: + + ```java + @Data + public class RagStoreQueryRequest { + private String storeCode; + private String storeName; + private String status; + } + ``` + + `RagStoreResponse.java`: + + ```java + @Data + public class RagStoreResponse { + private Long id; + private String storeCode; + private String storeName; + private String description; + private String status; + private String remark; + } + ``` + + `RagDocumentQueryRequest.java`: + + ```java + @Data + public class RagDocumentQueryRequest { + private Long storeId; + private Long attachmentId; + private String parseStatus; + private String indexStatus; + private Boolean enabled; + } + ``` + + `RagDocumentResponse.java`: + + ```java + @Data + public class RagDocumentResponse { + private Long id; + private Long storeId; + private Long attachmentId; + private String documentTitle; + private String documentSummary; + private String parseStatus; + private String indexStatus; + private Boolean enabled; + private String errorMessage; + private String remark; + } + ``` + +- [ ] **Step 4: 修改 RAG service/controller** + + - `IRagStoreService`、`IRagDocumentService` 返回 DTO + - `RagStoreController` 和 `RagDocumentController` 返回 `RequestResult` + - 查询接口改为 `@PostMapping("/query")` + `@RequestBody QueryRequest` + +- [ ] **Step 5: 运行测试并确认通过** + + Run: `.\mvnw.cmd "-Dtest=RagComponentStructureTests" test` + + Expected: PASS + +- [ ] **Step 6: Commit** + + ```bash + git add src/main/java/com/bruce/rag/controller/RagStoreController.java src/main/java/com/bruce/rag/controller/RagDocumentController.java src/main/java/com/bruce/rag/service/IRagStoreService.java src/main/java/com/bruce/rag/service/IRagDocumentService.java src/main/java/com/bruce/rag/service/impl/RagStoreServiceImpl.java src/main/java/com/bruce/rag/service/impl/RagDocumentServiceImpl.java src/main/java/com/bruce/rag/dto/request src/main/java/com/bruce/rag/dto/response src/test/java/com/bruce/rag/RagComponentStructureTests.java + git commit -m "refactor: 调整RAG接口为DTO模式" + ``` + +### Task 5: 全量验证与整理 + +**Files:** +- Modify: `src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java` +- Modify: `src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java` +- Modify: `src/test/java/com/bruce/rag/RagComponentStructureTests.java` + +- [ ] **Step 1: 运行定向测试,确认三块 DTO 改造都覆盖到** + + Run: `.\mvnw.cmd "-Dtest=SysAttachmentComponentStructureTests,SysEnumComponentStructureTests,RagComponentStructureTests" test` + + Expected: PASS + +- [ ] **Step 2: 运行全量测试** + + Run: `.\mvnw.cmd test` + + Expected: `BUILD SUCCESS` + +- [ ] **Step 3: 检查工作区** + + Run: `git status --short` + + Expected: 仅显示本次预期文件,或为空(若已提交)。 + +- [ ] **Step 4: Commit** + + ```bash + git add src/test/java/com/bruce/common/attachment/SysAttachmentComponentStructureTests.java src/test/java/com/bruce/common/enumconfig/SysEnumComponentStructureTests.java src/test/java/com/bruce/rag/RagComponentStructureTests.java + git commit -m "test: 校验DTO接口改造结构" + ```