From f318427ae399865e73e5d1b74daecc9e23a19550 Mon Sep 17 00:00:00 2001 From: zichun Date: Mon, 1 Jun 2026 14:10:14 +0800 Subject: [PATCH] docs(review:REQ-USR-002:r1): approve --- docs/superpowers/reviews/2026-06-01-REQ-USR-002.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+), 0 deletions(-) create mode 100644 docs/superpowers/reviews/2026-06-01-REQ-USR-002.md diff --git a/docs/superpowers/reviews/2026-06-01-REQ-USR-002.md b/docs/superpowers/reviews/2026-06-01-REQ-USR-002.md new file mode 100644 index 0000000..e56fe3a --- /dev/null +++ b/docs/superpowers/reviews/2026-06-01-REQ-USR-002.md @@ -0,0 +1,74 @@ +# REQ-USR-002 修改用户 — AI 自审报告(review, round 1) + +> 阶段:后端(backend)。spec:`docs/superpowers/specs/2026-06-01-REQ-USR-002.md`。 +> 分支:`module-usr`;审查范围 = 本 REQ diff(`09db895..8a1b01b`)。 +> 维度:通用后端代码审查(plan-alignment / 正确性 / 边界 / 错误处理 / 一致性 / 架构 / 文档)。 + +--- + +## 裁决 + +**verdict = approve**(issues = 空数组)。 + +实现与 spec / docs/05 契约 / docs/04 技术规范一致,8 条验收标准均有对应实现与测试覆盖,无客观可验证的 must-fix 缺陷。 + +--- + +## 1. 变更清单 + +| 文件 | 性质 | +|---|---| +| `backend/.../usr/dto/UpdateUserDTO.java` | 新增入参 DTO(匈牙利前缀 + `@JsonProperty` 锁键名 + Bean Validation) | +| `backend/.../usr/service/UsrUserService.java` | 接口新增 `updateUser(Integer, UpdateUserDTO)` | +| `backend/.../usr/service/impl/UsrUserServiceImpl.java` | 新增 `updateUser` 实现(存在性校验 / 部分更新 / 权限全量覆盖 / 单事务) | +| `backend/.../usr/controller/UsrUserController.java` | 新增 `PUT /api/usr/users/{id}` + 管理员前置 | +| `backend/.../usr/dto/UpdateUserDTOValidationTest.java` | DTO 校验单测(5) | +| `backend/.../usr/service/UsrUserServiceImplTest.java` | Service 单测续写(T2 3 + T3 5) | +| `backend/.../usr/controller/UsrUserControllerTest.java` | Controller 单测续写(4) | +| `backend/.../usr/UsrUserUpdateIT.java` | 端到端验收回归(6,AC1/2/3/6/7/8) | + +无 SQL migration 变更(符合 D5:所需表均在 V1 建好);无跨模块改动。 + +--- + +## 2. plan-alignment(与 spec / 契约对照) + +- 端点 / 方法 / 路径与 `docs/05 § REQ-USR-002`(`PUT /api/usr/users/{id}`)一致;响应 `Result<{id}>`、`code=0` 一致。 +- DTO 字段集与契约请求体逐项吻合:`sUserNo / iEmployeeId / sUserType / sLanguage / iCanModifyBill / iIsVoid / permissionIds`;不接收 `sUserName / sPassword / 审计列 / 租户列`(spec § 2.1 注)。 +- 决策落实:D1(不碰密码)、D2(`iIsVoid` 承载禁用)、D3(可选列 null = 不更新)、D4(`permissionIds` 全量覆盖 / `[]` 清空 / null 不改)、D5(不新增 migration)、D6(管理员 = `超级管理员`)。 +- 错误码:`40401`(不存在)/ `40001`(关联职员或权限元素不存在、枚举越界)/ `40301`(非管理员)/ `0`(成功)——与 spec § 6 一致。 + +## 3. 正确性 / 边界 / 错误处理 + +- 目标用户存在性校验置于所有写入之前,命中即 `40401` 且不落库(AC2)。 +- 关联职员、权限元素存在性校验置于主记录更新前,非法即抛 `40001`,配合 `@Transactional(rollbackFor=Exception.class)` 整体回滚、无副作用(AC3)。 +- 权限全量覆盖:先删该用户全部旧授权再按去重集合逐行插入;`[]` → 只删不插(清空);`null` → 不进入分支(不改);`distinct()` + `Objects::nonNull` 过滤去重去空(AC6)。 +- 主记录部分更新:仅 set 主键 + 必填两列 + 非 null 可选列;密码 / `sUserName` / 审计列 / 租户列全不 set,依赖 MP `updateById` 默认 `NOT_NULL` 字段策略(已核对 `MybatisPlusConfig` 与 `application.yml` 无策略覆盖)从 SET 子句剔除,保持原值(AC1 / AC8)。 +- 响应仅 `{id}`,`sPassword` 实体侧 `@JsonIgnore`,IT 断言响应体不含 `password` 子串(AC8)。 + +## 4. 架构 / 一致性 + +- 分层正确:Controller 仅 `@Valid` + 管理员前置 + 委派,未直接调 Mapper;业务在 Service;数据访问走 `LambdaQueryWrapper` / MP 内置(docs/04 § 1.2 / § 3.4)。 +- 复用 REQ-USR-001 已建 controller / service / mapper / entity,未另起类,未跨 `modules/usr/**` 之外(spec § 4)。 +- 统一响应 / 全局异常 / 错误码枚举沿用既有公共设施,风格一致。 + +## 5. 文档 + +- 类 / 方法 Javadoc 完整,含 `REQ-USR-002` 追溯标记与决策引用,符合项目注释约定。 + +--- + +## 6. 非阻塞建议(口头,非 must-fix) + +1. **路径参数非正整数口径**:spec § 2.1 / § 6 期望非正整数 `id` 返回 `40001`,当前 Controller 未加 `@Positive`,`0` / 负数 `id` 会落到 `selectById` 返回 null → `40401`。因 `0` / 负数主键实际不可能命中记录,行为安全(仍被拒绝、不产生数据污染),但与契约文字口径略有出入;后续可在 `@PathVariable` 加 `@Positive` 并开启 `@Validated` 使其归一为 `40001`。 +2. **注释 tag 笔误**:`UsrUserController` 中管理员判定注释引用 `spec § 8 D2`,实际管理员口径决策为 `D6`(D2 是 `iIsVoid` 状态决策);纯注释问题,不影响行为。 +3. **并发健壮性(理论)**:权限"先删后插"在高并发同一用户授权场景下存在间隙锁 / 死锁的理论可能;当前管理员低频写场景可接受,不构成缺陷。 +4. **非整数 `iIsVoid` / `iCanModifyBill` 反序列化**:传入非数字会触发 Jackson `HttpMessageNotReadableException`,落到兜底 `Exception` 处理器返回 `50000` 而非 `40001`;此为既有全局行为(与 REQ-USR-001 一致),不在本 REQ 作用域单独修。 + +--- + +## 7. 测试与闸门 + +- verify 证据(`2026-06-01-REQ-USR-002-verify.md`):`mvn checkstyle:check` exit 0、`mvn test` 36 通过 / 0 失败,`BUILD SUCCESS`。 +- 单测覆盖:DTO 校验、Service 存在性 / 部分更新 / 关联职员 / 权限全量覆盖(含去重、清空、不改)、Controller 管理员前置 / 路由 / 404 转译。 +- IT 覆盖 AC1/2/3/6/7/8;AC4(禁用实时生效)/ AC5(角色变更实时生效)依赖 REQ-USR-004 / REQ-USR-003,本 REQ 以"落库层读回等价验证"覆盖,符合 spec § 7 边界说明。 -- libgit2 0.22.2