2026-06-01-REQ-USR-001.md 4.68 KB

REQ-USR-001 增加用户 — AI 自审报告(review, round 1)

阶段:后端(backend)。审查维度:通用代码审查(plan-alignment / quality / architecture / docs)。 上游 spec:docs/superpowers/specs/2026-06-01-REQ-USR-001.md API 契约:docs/05-API接口契约.md § REQ-USR-001 Schema SSoT:sql/migrations/V1__initial_schema.sql(对齐 docs/03) 被审提交:c9cbcea(HEAD);本 REQ diff 自 cc0c846 起 审查时间:2026-06-01 CST


1. 裁决

verdict = approve(issues = 空)。

本轮引入的后端代码在四个标准维度上均无客观、可验证的 must-fix 缺陷;测试证据 24/24 全绿(见 verify 报告),工作树干净。


2. 维度核对

2.1 plan-alignment(实现 ↔ spec / 契约)

核对项 结论
端点 POST /api/usr/users 一致(UsrUserController @PostMapping("/users") + @RequestMapping("/api/usr")
DTO 字段与校验(spec § 2.1) 一致:sUserName @NotBlank+@Pattern(3-20)sUserNo @Size(50)sUserType `@Pattern(普通用户\
错误码 40001 / 40301 / 40901 / 0 一致(ResultCode 枚举;GlobalExceptionHandlerResult
业务规则 1-9(spec § 3) 全部落地:用户名查重→40901、并发 DuplicateKey 兜底→40901、密码 BCrypt+禁明文、用户类型/语言枚举约束、职员/权限存在性→40001、权限去重批量授权、iIsVoid=0 新建即生效、审计字段、管理员前置→40301
Schema 列 / 唯一索引 实体 UsrUser / UsrUserPermission 列映射与 V1 一致;uk_usr_user_username / uk_usr_user_permission 对齐
多租户列 sBrandsId/sSubsidiaryId 由 DB 默认值 1111111111 兜底(spec § 2.1 系统生成字段),与 spec 设计一致

2.2 quality(正确性 / 边界 / 错误处理 / 安全)

  • 用户名先查重再插入,且 DuplicateKeyException 兜底转 40901,并发安全(UsrUserServiceImpl 第 64-68 / 115-119 行)。
  • 密码:BCryptPasswordEncoder 哈希;UsrUser.sPassword@JsonIgnore;响应仅 data.id。AC6/AC7 端到端验证(UsrUserCreateITpasswordEncoder.matches("666666", hash) 断言,响应体不含 "password"/"666666")。
  • 关联职员 / 权限存在性校验在插入前完成,失败抛 40001 且无副作用(单测 never().insert(...) 断言)。
  • @Transactional(rollbackFor = Exception.class) 覆盖 usr_user + usr_user_permission 多表写,AC2 端到端验证回滚。
  • iCanModifyBill 在 Service 兜底为非空 Integer 后再做拆箱比较,无 NPE 风险。
  • 全局兜底异常只记栈、对外返回 50000,不泄露内部细节。

2.3 architecture(分层 / 集成 / 可扩展)

  • 分层正确:Controller 仅做 @Valid + 管理员前置 + 委派,不碰 Mapper;Service 持有 4 个 Mapper + Encoder。
  • 包路径 com.xly.erp.modules.usr.{controller,service,service.impl,mapper,entity,dto} 与 spec § 4 一致;作用域限于 modules/usr/** + common/** 基础设施,未跨业务模块、未触 frontend/
  • 公共基础设施(Result / ResultCode / BusinessException / GlobalExceptionHandler / BaseEntity / MybatisPlusConfig / Security/JWT)一次性建好并预留后续 REQ 复用,合理。

2.4 docs(注释 / 约定)

  • 各类 Javadoc 标注 REQ 追溯(REQ-USR-001 Tn)与 SSoT 引用,符合 CLAUDE.md 约定。
  • commit 信息遵循 <type>(<scope>): <subject> REQ-USR-001 规范。

3. 非阻塞建议(口头,非 must-fix)

  1. UsrUserServiceImpl.java:124-125new LinkedHashSet<>(dedupedPermissionIds) 包裹的列表在第 78-81 行已 .distinct() 去重,此处再次去重为冗余防御代码,可简化直接遍历 dedupedPermissionIds。无功能影响。
  2. UsrUserController.java:38-41:管理员判定位于 @Valid 之后,故非管理员携带非法 body 时先返回 40001 而非 40301。这是对 spec § 3.9「先于业务校验」的合理解读(bean 校验属框架层,区别于 Service 业务规则),且 AC5 仅以合法 body 验证 40301,故不构成缺陷;若后续业务要求 40301 严格优先于 40001,可将权限判定前移至过滤器 / 拦截器层。
  3. application.yml / application-test.yml 将 DB 凭据与 JWT 密钥作为 env 默认值内联。按项目约定其单一来源为 config-vars.yaml 经 env 注入,属既定模式(非纯硬编码),仅作安全提示。

4. 结论

四维均无客观 must-fix 缺陷;测试 24/24 全绿、AC1-AC7 全覆盖;工作树干净。判定 approve。