--- req_id: REQ-USR-004 date: 2026-05-15 round: 2 reviewer: superpower-code-reviewer --- # Review: REQ-USR-004 — round 2 ## 结论 approve ## Must-fix (无) ## Nice-to-have - backend/src/main/java/com/xly/erp/module/usr/service/impl/UserListServiceImpl.java:148 — `normalizeQueryValue` 用全限定 `java.time.LocalDate.parse` 而非顶部 import,纯风格瑕疵 - matchMode 白名单校验在 forced-equals 覆盖之前;调用方传 matchMode=contains + queryField=isDeleted 时白名单接受 contains 再静默覆盖为 equals — 行为正确但稍不透明,可加 logger.debug 留痕 - UserListServiceImplTest 末尾 `@Autowired JdbcTemplate jdbc` 字段定义在测试方法之后,风格不一致;建议挪到类顶部 - round 1 已标记『推迟』的 4 项保持不变(queryField=userType 不走 USER_TYPES 白名单;UserQueryParams public 可变字段;list_emptyTable_returnsZeroTotal 命名;mapper ORDER BY 硬编码 u.* 前缀) ## 反例 / 测试覆盖缺口 Round 2 测试覆盖完整:spec § 业务规则 3 的 isDeleted/lastLoginDate matchMode 强制 equals + 类型归一化由 3 个新测试明确断言;spec § 验收 1-26 由 198+3 测试映射;spec § 验收 26 空表场景由 list_emptyTable_returnsZeroTotal(虽命名不准)覆盖。Reviewer 子会话无本地 MySQL,未独立复跑 mvn test;信任 commit 8bf84c9 + 主会话 feature-verify 报告的 201/0 结果。 ## 本轮变更归档 Round 1 全部修复落地: | # | 项目 | 状态 | |---|------|-----| | M1 | EQUALS_ONLY_FIELDS 强制 matchMode=equals | ✓ 仅在 queryField+queryValue 都非空时覆盖,scoped 严格,不影响其他路径 | | M2 | lastLoginDate 类型归一化 | ✓ 支持 LocalDateTime / LocalDate,非法值抛 40001 | | M3 | queryValue 用 isBlank 判空 | ✓ | | M4 | docs/05 错误码补 sortField + 40101 | ✓ | | Test | 新增 3 个回归测试 | ✓ | 未引入新回归。verdict=approve。