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

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 已存在,勿重复创建,只更新