Commit f318427ae399865e73e5d1b74daecc9e23a19550

Authored by zichun
1 parent 8a1b01bd

docs(review:REQ-USR-002:r1): approve

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