You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
5.3 KiB
122 lines
5.3 KiB
|
4 weeks ago
|
# Handoff: CRM Controller IO Conventions Implementation
|
||
|
|
|
||
|
|
**Date:** 2026-08-10
|
||
|
|
**Branch:** master
|
||
|
|
**Last commits:** `ae103a1` (ticket 01 main), `80bc063` (ticket 01 status update)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. What This Project Is
|
||
|
|
|
||
|
|
CRM 后端(Java 17 + Spring Boot 3 + MyBatis-Plus,Maven 多模块单体)。正在统一 Controller 出入参约定,由 ADR-0017 驱动,推翻旧的三类方案(SaveParam/PageParam/DTO),改为两类(Param/DTO)。
|
||
|
|
|
||
|
|
**核心工件(勿重复,引用即可):**
|
||
|
|
- **ADR-0017:** `docs/adr/0017-controller-io-param-dto-conventions.md`
|
||
|
|
- **Spec:** `.scratch/controller-io-conventions/spec.md`
|
||
|
|
- **7 个 Ticket:** `.scratch/controller-io-conventions/issues/01-*.md` 至 `07-*.md`
|
||
|
|
- **研究文档:** `docs/research/2026-08-10-dto-vo-param-conventions.md`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. What's Done
|
||
|
|
|
||
|
|
### Ticket 01 — BaseDTO 重构 + IBaseService 清理(resolved)
|
||
|
|
|
||
|
|
Commit `ae103a1`,15 files, +360/-62。
|
||
|
|
|
||
|
|
| 文件 | 改动 |
|
||
|
|
|---|---|
|
||
|
|
| `crm-base/.../domain/dto/BaseDTO.java` | `abstract`,仅 `id`/`createTime`/`updateTime`(`@JsonInclude NON_NULL`),移除 `creatorId`/`updaterId`/`deleted`/`toEntity(Supplier)` |
|
||
|
|
| `crm-base/.../service/IBaseService.java` | 删除 `saveDTO`/`updateDTO` 死代码 |
|
||
|
|
| `crm-base/.../utils/BeanCopyUtils.java` | javadoc 移除 `BaseDTO.toEntity` 引用 |
|
||
|
|
| `README.md` | §3/§4/§10 同步更新 |
|
||
|
|
| `crm-auth/.../ResourceController.java` | 修复预存 UTF-8 BOM |
|
||
|
|
| `crm-auth/.../RoleController.java` | 修复预存 UTF-8 BOM |
|
||
|
|
|
||
|
|
验证:`mvn clean compile` 全 6 模块 SUCCESS;`mvn test` 45 tests, 0 failures, 0 errors。
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Key Technical Decisions(ADR-0017 摘要)
|
||
|
|
|
||
|
|
1. **两类对象**:`XxxParam`(查询/分页入参,extends `BaseParam`)+ `XxxDTO`(写入参+出参双向,Route A)
|
||
|
|
2. **BaseDTO**:abstract,仅 `id`/`createTime`/`updateTime`,`@JsonInclude(NON_NULL)`;统计/聚合类不继承
|
||
|
|
3. **Mass assignment 防御**:全局 `@ControllerAdvice` + `@InitBinder` + `setDisallowedFields`,strip 掉 `createTime`/`updateTime`/`creatorId`/`updaterId`/`deleted`/`builtin`(尚未实现 = ticket 02)
|
||
|
|
4. **硬约束**:Entity 不出现在 Controller 签名;`deleted`/`creatorId`/`updaterId` 不出现在 HTTP 响应
|
||
|
|
5. **封装阈值**:≥3 参数封 `XxxDTO`,≤2 保持 `@RequestParam`(纯参数个数)
|
||
|
|
6. **转换**:`fromEntity()`/`toEntity()` 写在各 DTO 类上,Service 层调用
|
||
|
|
7. **表单绑定**:隐式 `@ModelAttribute`(不加 `@RequestBody`),契合 `application/x-www-form-urlencoded` 契约
|
||
|
|
8. **全量回填**:所有存量违规代码全改(非仅新代码)
|
||
|
|
9. **命名**:`dto/` 包内 HTTP 出入参类一律 `XxxDTO` 后缀;存量 VO 已重命名
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Frontier — What's Next
|
||
|
|
|
||
|
|
### Ticket 02 — 全局 @InitBinder Mass Assignment 防御(无阻塞,可立即开始)
|
||
|
|
|
||
|
|
**目标**:创建全局 `@ControllerAdvice` + `@InitBinder`,用 `setDisallowedFields` strip 掉服务端裁定的字段。
|
||
|
|
|
||
|
|
**strip 字段列表**:`createTime`, `updateTime`, `creatorId`, `updaterId`, `deleted`, `builtin`
|
||
|
|
|
||
|
|
**实现位置**:`crm-base/src/main/java/com/crm/base/advice/` 包下新建类(已有 `GlobalExceptionHandler` 在同包)
|
||
|
|
|
||
|
|
**验收标准**(见 `02-init-binder-mass-assignment.md`):
|
||
|
|
- [ ] 创建 `@ControllerAdvice` 类,含 `@InitBinder` 方法
|
||
|
|
- [ ] 调用 `binder.setDisallowedFields(...)` 覆盖 6 个字段
|
||
|
|
- [ ] 不影响已有 `@ModelAttribute` 绑定的正常工作
|
||
|
|
- [ ] 编译通过 + 测试通过
|
||
|
|
|
||
|
|
### Ticket 02 完成后解锁
|
||
|
|
|
||
|
|
Tickets 03/04/05/06 同时解锁:
|
||
|
|
- **03** DictGroup Controller IO(blocked by 02)
|
||
|
|
- **04** DictItem Controller IO(blocked by 02)
|
||
|
|
- **05** ResourceNode 重命名为 ResourceDTO(blocked by 02)
|
||
|
|
- **06** RoleController IO 改造(blocked by 02)
|
||
|
|
|
||
|
|
Ticket 07(SystemController IO)blocked by 05。
|
||
|
|
|
||
|
|
### 依赖图
|
||
|
|
|
||
|
|
```
|
||
|
|
01 (resolved) ──┐
|
||
|
|
├─► 02 (ready) ──┬─► 03
|
||
|
|
│ ├─► 04
|
||
|
|
│ ├─► 05 ──► 07
|
||
|
|
│ └─► 06
|
||
|
|
└─────────────────────────────────► (done)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Environment Notes
|
||
|
|
|
||
|
|
- **Maven 路径**:`D:\apache-maven-3.9.9\bin\mvn.cmd`(不在系统 PATH 上,需用全路径调用)
|
||
|
|
- **PowerShell**:不支持 `&&`,用 `;` 分隔
|
||
|
|
- **Java**:JDK 17
|
||
|
|
- **编译命令**:`cd d:\code\crm-backend-matt; D:\apache-maven-3.9.9\bin\mvn.cmd clean compile`
|
||
|
|
- **测试命令**:`cd d:\code\crm-backend-matt; D:\apache-maven-3.9.9\bin\mvn.cmd test`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. Suggested Skills
|
||
|
|
|
||
|
|
| Skill | When to use |
|
||
|
|
|---|---|
|
||
|
|
| `/implement` | 实现 ticket 02-07,每次一个 ticket |
|
||
|
|
| `/code-review` | 每个 ticket 实现后审查(Standards + Spec 双轴) |
|
||
|
|
| `/diagnosing-bugs` | 如果编译或测试出现意外错误 |
|
||
|
|
| `/tdd` | 如果想先写测试再实现(ticket 02 的 @InitBinder 适合 TDD) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. Conventions to Follow
|
||
|
|
|
||
|
|
- 每个 ticket 完成后:编译 + 测试 + 提交 + 更新 ticket 状态为 `resolved`
|
||
|
|
- 提交信息格式:`refactor: <description> (ADR-0017 ticket 0N)`
|
||
|
|
- 代码风格:匹配周围代码的注释密度、命名、惯用法
|
||
|
|
- 不要提交 `target/` 目录下的构建产物
|
||
|
|
- 不要提交 `.idea/` 目录下的 IDE 配置
|
||
|
|
- ADR + spec + tickets 已存在,勿重复创建,只更新
|