Commit 5fa080446e9fa3f39a1cc826e8b1024e7c2d3517

Authored by zichun
1 parent ebf3a399

chore(usr): 渲染 usr 模块 12 节完成报告(test-gate r1 green 后)

docs/superpowers/module-reports/2026-06-01-usr.md 0 → 100644
  1 +# 模块完成报告 — USR 用户管理(backend)
  2 +
  3 +> 生成时间:2026-06-01 CST
  4 +> 模块 id:usr|阶段:后端(backend)|功能分支:`module-usr`(自默认分支 `master` 分叉)
  5 +> 本报告为标准化 12 节模块完成报告,供 milestone 标记前置。摘要级(不引入 diff 正文)。
  6 +
  7 +---
  8 +
  9 +## ① 模块概述
  10 +
  11 +- **模块名称**:USR 用户管理(`com.xly.erp.modules.usr`)。
  12 +- **业务范围**:企业内部管理系统的用户账号全生命周期与登录认证,覆盖用户新增、修改、分页查询、登录认证 4 个后端 REQ。
  13 +- **依赖**:无(docs/08 § 二 标注「依赖: 无」),为整个 ERP 的基础模块。
  14 +- **路径作用域**:`backend/src/main/java/com/xly/erp/modules/usr/**` + 公共基础设施 `com/xly/erp/common/**`(统一响应 / 异常 / 安全 / JWT / BaseEntity,本模块首次落地,供后续模块复用)。
  15 +- **本阶段产出范围**:controller / service / repository(mapper) / DTO / VO / 校验 / REST 契约实现;不触 `frontend/`(UI 推迟到前端阶段);本模块未新增 SQL migration(复用 A4 生成的 `V1__initial_schema.sql`)。
  16 +
  17 +---
  18 +
  19 +## ② 需求覆盖(REQ 清单 + spec 摘要)
  20 +
  21 +本模块 4 个 REQ 全部完成并在 `docs/08-模块任务管理.md` § 二 勾选为 `[x]`:
  22 +
  23 +| REQ | 标题 | 端点 | spec 摘要 |
  24 +|---|---|---|---|
  25 +| REQ-USR-001 | 增加用户 | `POST /api/usr/users` | 管理员新建用户:用户名 3-20 位唯一、密码 BCrypt(默认 `666666`)、用户类型 / 语言枚举约束、可选关联职员 + 权限组授权(多对多);多表写入事务化;新建即生效(`iIsVoid=0`)。错误码 0/40001/40301/40901。 |
  26 +| REQ-USR-002 | 修改用户 | `PUT /api/usr/users/{id}` | 管理员改用户基础信息(用户号 / 关联职员 / 用户类型 / 语言 / 单据修改权限 / 作废标志 / 权限组);`sUserName` 与 `sPassword` 不可改;权限组**全量覆盖**语义;可选字段 null = 不更新(保守不清空)。错误码 0/40001/40301/40401。 |
  27 +| REQ-USR-003 | 查询用户 | `GET /api/usr/users` | 任意已认证用户的只读单条件分页查询(8 个查询字段 × 3 种匹配方式);跨表 LEFT JOIN `usr_employee` 取员工名 / 部门;文本模糊(LIKE 转义)/ 枚举 / 布尔 / 日期精确匹配;分页参数非法 → `42201`,数据越界返回最后一页;密码绝不返回。错误码 0/40001/42201(+401 未认证)。 |
  28 +| REQ-USR-004 | 登录用户 | `POST /api/usr/login`(+ 配套 `GET /api/usr/companies`) | 用户名 + 密码 + 版本(companyId) 认证:BCrypt 比对 → 签发带 exp 的无状态 JWT + 更新 `tLastLoginDate`;防账号枚举(不存在/密码错误同码同提示);禁用账号 `40302`;进程内登录限流 `42901`(默认 5 次/300 秒)。配套补齐只读公司列表端点支撑登录页「版本」下拉。错误码 0/40001/40101/40302/42901(+401)。 |
  29 +
  30 +> spec 全文:`docs/superpowers/specs/2026-06-01-REQ-USR-00{1,2,3,4}.md`。各 spec § 8 已逐条登记自主决策(见本报告 § ⑩)。
  31 +
  32 +---
  33 +
  34 +## ③ 文件变更摘要(git diff --stat,master...HEAD)
  35 +
  36 +- **提交数**:53 个 commit(`git log master..HEAD --oneline`)。
  37 +- **变更规模**:85 个文件,+8280 / -5 行。
  38 +- **新增生产代码**(`backend/src/main/java/com/xly/erp/`,A=新增):
  39 + - 公共基础设施 `common/`:`base/BaseEntity`、`config/{MybatisPlusConfig,SecurityConfig}`、`exception/{BusinessException,GlobalExceptionHandler}`、`response/{Result,ResultCode,PageResult}`、`security/{JwtUtil,JwtAuthenticationFilter,SecurityUtil}`、`ErpApplication`。
  40 + - USR 模块 `modules/usr/`:controller(`UsrUserController`、`UsrAuthController`)、service(`UsrUserService(+Impl)`、`UsrAuthService(+Impl)`)、mapper(`UsrUser/UsrCompany/UsrEmployee/UsrPermission/UsrUserPermission` Mapper)、entity(`UsrUser/UsrCompany/UsrEmployee/UsrPermission/UsrUserPermission`)、dto(`CreateUserDTO/UpdateUserDTO/UserQueryDTO/UserQueryCondition/LoginDTO`)、vo(`UserVO/LoginVO/CompanyOptionVO`)。
  41 + - 资源:`application.yml`、`application-test.yml`、`mapper/usr/UsrUserMapper.xml`(跨表分页查询)。
  42 + - 构建:`backend/pom.xml`(Spring Boot + MyBatis-Plus + Flyway 10.10.0 + JWT,`java.version=17`)、`backend/checkstyle.xml`。
  43 +- **新增测试代码**(`backend/src/test/java/`):25 个测试类(详见 § ⑤)。
  44 +- **流程 / 文档**:`scripts/test.mjs`(M,新增 `ensureJava17()`)、`docs/08-模块任务管理.md`(M,4 个 REQ 勾选)、`docs/superpowers/{specs,plans,reviews}/2026-06-01-REQ-USR-00{1..4}*.md`(A)、`docs/superpowers/module-reports/usr-test-gate-r1.md`(A)。
  45 +- **migration**:无新增(见 § ⑥)。
  46 +- **跨模块**:无(见 § ⑦)。
  47 +
  48 +---
  49 +
  50 +## ④ 读写的数据表
  51 +
  52 +本模块涉及 5 张表,全部由 `sql/migrations/V1__initial_schema.sql` 建好(A4 阶段从 docs/03 翻译),本模块**未做 schema 变更**:
  53 +
  54 +| 表 | 操作 | 涉及 REQ | 说明 |
  55 +|---|---|---|---|
  56 +| `usr_user` | 读 + 写 | 001(写) / 002(写) / 003(读) / 004(读+写 `tLastLoginDate`) | 用户主表,主键 `iIncrement`,唯一索引 `uk_usr_user_username`。 |
  57 +| `usr_user_permission` | 写 | 001(批量插入) / 002(全量覆盖) | 用户-权限多对多关联表,唯一索引 `uk_usr_user_permission(iUserId,iPermissionId)`。 |
  58 +| `usr_employee` | 读 | 001/002(存在性校验) / 003(LEFT JOIN 取员工名/部门) | 职员表;与 `usr_user` 外键 `fk_usr_user_employee` ON DELETE SET NULL。 |
  59 +| `usr_permission` | 读 | 001/002(权限 id 存在性校验) | 权限组表。 |
  60 +| `usr_company` | 读 | 004(版本下拉 + companyId 存在性校验) | 公司/版本支撑表,与 `usr_user` 无外键(仅登录时选择)。 |
  61 +
  62 +> 严格遵循 docs/04 § 3.4:仅经 Mapper 访问;查询不 SELECT `sPassword`;VO 不含密码列;SQL 参数化防注入,LIKE 通配符转义。
  63 +
  64 +---
  65 +
  66 +## ⑤ 测试与质量闸(test-gate)
  67 +
  68 +**flake 判定:无 flake。** test-gate attempt 序列仅 `r1`,且 r1 = **GREEN**(首跑即绿)。
  69 +
  70 +> 说明:历史上曾在 JDK25 默认工具链下有 5 次 RED 记录(旧 r1–r5),其根因为 Mockito/Byte Buddy 不支持 JDK25 的 class file 版本(69),导致 `UsrAuthServiceImplTest` 对 `JwtUtil` 整片 `Mockito cannot mock` 报 error(终态 88 跑 / 9 error)。该批旧证据因属过期工具链问题已在 commit `282a524` 移除,并非当前 attempt 序列的一部分;工具链修复在 `dbc3454`(`scripts/test.mjs` 新增 `ensureJava17()`,把后端测试 JVM 的 `JAVA_HOME` 固定到 Java 17)。本模块当前 attempt 序列从修复后重新起算,r1 首跑即绿,故不构成「red→green flake」。
  71 +
  72 +**本次 r1 证据**(`docs/superpowers/module-reports/usr-test-gate-r1.md`):
  73 +
  74 +- 执行命令:`node scripts/test.mjs`(内部 `ensureJava17()` → `/opt/homebrew/Cellar/openjdk@17/17.0.19/.../Home`)。
  75 +- 工具链确认:Spring Boot 测试日志 `Starting ErpApplicationTests using Java 17.0.19`;Maven 3.9.15 / Java 17.0.19。
  76 +- 5 级闸门:1/5 setup-db ✅、2/5 build(`mvn -q -B -DskipTests package`) ✅、3/5 lint(`mvn -q -B checkstyle:check`) ✅、4/5 unit+integration(`mvn -q -B test`) ✅、5/5 e2e(后端无 e2e,skip)✅。
  77 +- 退出码 0,终态 `[test.mjs] GREEN`。
  78 +- **测试统计(surefire-reports 汇总)**:`Tests run: 125, Failures: 0, Errors: 0, Skipped: 0`(25 个测试类)。曾整片报错的 `UsrAuthServiceImplTest`(含 `JwtUtil` mock)本次 9/9 全绿,证明根因消除。
  79 +
  80 +**测试类清单(25)**:
  81 +
  82 +- 公共:`ErpApplicationTests`、`SecurityConfigTest`、`GlobalExceptionHandlerTest`、`ResultTest`、`ResultCodeLoginTest`、`PageResultTest`、`JwtUtilTest`。
  83 +- DTO 校验:`CreateUserDTOValidationTest`、`UpdateUserDTOValidationTest`、`UserQueryDTOValidationTest`、`LoginDTOValidationTest`。
  84 +- VO 序列化:`UserVOJsonTest`、`LoginVOJsonTest`、`CompanyOptionVOJsonTest`。
  85 +- Mapper:`UsrUserMapperPageTest`、`UsrCompanyMapperTest`。
  86 +- Service 单测:`UsrUserServiceImplTest`(24)、`UsrAuthServiceImplTest`(9)。
  87 +- Controller 单测:`UsrUserControllerTest`(11)、`UsrAuthControllerTest`(6)。
  88 +- 端到端 IT:`UsrUserCreateIT`(5)、`UsrUserUpdateIT`(6)、`UsrUserQueryIT`(13)、`UsrLoginIT`(12)、`AuthLoginConfigIT`(1)。
  89 +
  90 +---
  91 +
  92 +## ⑥ 数据库 migration
  93 +
  94 +**本模块未新增 migration。**
  95 +
  96 +- `git diff --name-only --diff-filter=A master...HEAD -- 'sql/migrations/V*.sql'` 结果为空。
  97 +- 现有唯一 migration `sql/migrations/V1__initial_schema.sql` 由 A4 阶段 `db-init` 从 `docs/03-数据库设计文档.md`(schema SSoT)翻译生成,第一行:`-- Flyway migration V1 — initial schema for 小羚羊`。
  98 +- 4 个 REQ 的 spec § 8 均明确决策「复用 V1,无 schema 变更」(4 张依赖表 `usr_user/usr_employee/usr_permission/usr_user_permission/usr_company` 结构与 docs/03 一致)。REQ-USR-004 仅对 `usr_user.tLastLoginDate` 做 UPDATE(DML 非 DDL)。
  99 +- Flyway 依赖已在 `pom.xml` 声明(`flyway-core` + `flyway-mysql` 10.10.0),schema 由 Spring Boot / 测试启动时自动 apply(符合 CLAUDE.md Schema 演化规约)。
  100 +
  101 +---
  102 +
  103 +## ⑦ 跨模块改动
  104 +
  105 +**无跨模块改动。**
  106 +
  107 +- `docs/superpowers/module-reports/usr-cross-module.md` 不存在(cross-module-log 未生成 = 本模块未触碰非当前模块的业务代码)。
  108 +- 本模块新增的 `common/**` 公共基础设施(统一响应 / 异常 / 安全 / JWT / BaseEntity)属全局基础层首次落地,非「改动其他业务模块」,不计入跨模块改动。
  109 +
  110 +---
  111 +
  112 +## ⑧ 与规范 / 契约的偏离
  113 +
  114 +**实现层无偏离**——4 个 REQ 的实现端点、请求/响应字段、错误码、分层、命名、统一响应、异常处理、事务、安全均与 docs/04 技术规范及 docs/05 API 契约一致(详见各 review 报告四维核对结论)。
  115 +
  116 +仅记录 2 项**对 docs/05 契约的反向同步建议**(实现期已落地为代码,建议择机补入契约 SSoT,非阻塞、非违规):
  117 +
  118 +1. **新增端点 `GET /api/usr/companies`**(REQ-USR-004 spec § 8 D1):docs/05 仅定义 `POST /api/usr/login`,未单列公司列表端点。为使登录链路自洽(前端需先取 companyId),后端补齐该只读放行端点。建议补入 docs/05 § REQ-USR-004。
  119 +2. **新增限流错误码 `42901`**(REQ-USR-004 spec § 8 D7):docs/05 未列该码,系为落地卡片「连续失败锁定/限流」要求引入。建议补入 docs/05 错误码段。
  120 +
  121 +> 以上两项均已在 spec § 8 显式登记为「建议反向同步(非本 stage 强制)」,review 亦标为非阻塞建议。其余无任何偏离。
  122 +
  123 +---
  124 +
  125 +## ⑨ 评审与验证记录
  126 +
  127 +每个 REQ 均有 round-1 review(裁决 approve)+ verify(证据验证)报告,路径 `docs/superpowers/reviews/2026-06-01-REQ-USR-00{1..4}{,-verify}.md`:
  128 +
  129 +| REQ | review 裁决 | 关键核对结论 |
  130 +|---|---|---|
  131 +| REQ-USR-001 | **approve**(issues=[]) | 四维(plan-alignment / quality / architecture / docs)无 must-fix;用户名查重 + DuplicateKey 兜底并发安全;密码 BCrypt + `@JsonIgnore` 不外泄;多表写事务回滚验证;24/24 测试绿。 |
  132 +| REQ-USR-002 | **approve** | 全量覆盖授权、null=不更新语义、`sUserName/sPassword` 不可改、审计字段只读均落地;权限差量覆盖与禁用实时生效端到端验证。 |
  133 +| REQ-USR-003 | **approve** | 单条件 8 字段 × 3 匹配、跨表 LEFT JOIN、LIKE 转义防注入、参数非法 `42201` / 数据越界返回最后一页、密码不返回均验证。 |
  134 +| REQ-USR-004 | **approve** | 认证判定顺序(限流→查用户→验密码→判禁用→校 companyId→签发+更新时间)与 spec § 8 D3 一致;防账号枚举(同码同提示);JWT 含 exp;进程内限流 `42901`;安全放行 `/api/usr/companies`。 |
  135 +
  136 +- 各 review 均附非阻塞口头建议(如限流计数与事务非原子、契约反向同步、冗余去重代码简化),无任何 must-fix。
  137 +- verify 报告确认各 REQ 在通过工具链下测试全绿、验收标准(AC)逐条覆盖。
  138 +- 模块级 test-gate(本报告 § ⑤)在锁定 JDK17 下 125/125 全绿,作为合并默认分支前的硬闸。
  139 +
  140 +---
  141 +
  142 +## ⑩ 自主决策汇总(decisions)
  143 +
  144 +本报告渲染过程中的自主决策见文末 `decisions[]`(test-gate 重跑判定、flake 归类等)。各 REQ 实现期的自主决策已在对应 spec § 8 逐条登记,要点汇总:
  145 +
  146 +- **语言取值锁定**:`sLanguage` ∈ {中文,英文,繁体},不取 docs/03 带审阅占位的默认值(REQ-001 D1)。
  147 +- **管理员判定口径**:以 `sUserType=超级管理员` 视为有写权限(无独立角色表)(REQ-001 D2 / 002 D6)。
  148 +- **修改语义**:可选字段 null = 不更新(保守不清空);权限组全量覆盖(REQ-002 D3/D4)。
  149 +- **查询边界**:单条件查询;参数非法 `42201` vs 数据越界返回最后一页二分;LIKE 通配符转义(REQ-003 D1/D2/D3)。
  150 +- **登录链路自洽**:补 `GET /api/usr/companies` 端点;进程内限流 `42901`(5 次/300 秒);先验密码再判禁用防枚举;JWT 默认 2 小时(REQ-004 D1/D3/D7/D10)。
  151 +- **migration**:4 个 REQ 全部复用 V1,无新增(REQ-001~004 各 Dn)。
  152 +
  153 +---
  154 +
  155 +## ⑪ 已知限制 / 后续事项
  156 +
  157 +1. **登录限流为进程内 MVP**:当前按 `sUserName` 在进程内存计数(默认 5 次失败 / 锁定 300 秒),分布式部署下不共享、不随 `@Transactional` 回滚(极小窗口)。技术栈虽列 Redis 但当前无连接配置,留待后续平滑替换为 Redis 原子计数(REQ-004 spec § 8 D7、review 非阻塞建议)。
  158 +2. **契约反向同步待补**:`GET /api/usr/companies` 端点与 `42901` 错误码建议补入 `docs/05-API接口契约.md`(见 § ⑧)。
  159 +3. **多租户列兜底**:`sBrandsId/sSubsidiaryId` 由 DB 默认值 `1111111111` 兜底,未引入运行时多租户上下文解析(按 spec 设计,当前阶段足够)。
  160 +4. **冗余防御代码**:`UsrUserServiceImpl` 权限去重存在一处可简化的二次去重(review 口头建议,无功能影响)。
  161 +5. **前端未实现**:FE-01~FE-04(登录页 / 主页框架 / 用户列表 / 用户单据)属前端阶段,docs/08 § 三 待办,不在本后端模块范围。
  162 +
  163 +---
  164 +
  165 +## ⑫ 结论
  166 +
  167 +USR 用户管理后端模块 4 个 REQ(增 / 改 / 查 / 登录)全部实现并 approve,模块级硬测试闸在锁定 JDK17 工具链下 **125/125 全绿(r1,无 flake)**,工作树干净,无新增 migration、无跨模块改动、实现层无偏离(仅 2 项非阻塞契约反向同步建议)。满足里程碑 `milestone/usr` 标记的全部前置条件。
  168 +
  169 +> 证据:`docs/superpowers/module-reports/usr-test-gate-r1.md`(GREEN)。