module_id: module_usr date: 2026-05-15
git_range: 76218f38 (bootstrap spring boot 后端骨架) ↔ 4d58768c (test-gate evidence)
模块完成报告 — module_usr 用户管理
① 模块信息
- 模块 ID: module_usr
- 模块名: 用户管理
- 开发区间: 2026-05-15 单日(REQ-USR-001 → 002 → 003 → 004)
- 分支: module-module_usr
② REQ 完成清单
- REQ-USR-001 — 用户登录
- spec: docs/superpowers/specs/2026-05-15-REQ-USR-001.md
- plan: docs/superpowers/plans/2026-05-15-REQ-USR-001.md
- review: docs/superpowers/reviews/2026-05-15-REQ-USR-001.md
- REQ-USR-002 — 新增用户
- spec: docs/superpowers/specs/2026-05-15-REQ-USR-002.md
- plan: docs/superpowers/plans/2026-05-15-REQ-USR-002.md
- review: docs/superpowers/reviews/2026-05-15-REQ-USR-002.md
- REQ-USR-003 — 修改用户(含 GET 详情)
- spec: docs/superpowers/specs/2026-05-15-REQ-USR-003.md
- plan: docs/superpowers/plans/2026-05-15-REQ-USR-003.md
- review: docs/superpowers/reviews/2026-05-15-REQ-USR-003.md
- REQ-USR-004 — 查询用户
- spec: docs/superpowers/specs/2026-05-15-REQ-USR-004.md
- plan: docs/superpowers/plans/2026-05-15-REQ-USR-004.md
- review: docs/superpowers/reviews/2026-05-15-REQ-USR-004.md
③ 文件变更表
| 文件 | 操作 | 说明 |
|---|---|---|
backend/pom.xml |
Create | Spring Boot 3.3 + MyBatis-Plus + Flyway + JJWT + BCrypt 依赖 |
backend/src/main/java/com/xly/erp/Application.java |
Create | 启动类 + @MapperScan |
backend/src/main/resources/application.yml / application-test.yml
|
Create | DB / JWT 配置 + Jackson 严格反序列化 + MyBatis mapper-locations |
backend/src/main/resources/logback-spring.xml |
Create | Logback 基础配置 |
backend/src/main/resources/mapper/usr/SysUserMapper.xml |
Create | REQ-004 动态 SQL JOIN + WHERE |
backend/src/main/java/com/xly/erp/common/response/{Result,ErrorCode,PageResult}.java |
Create | 统一响应包装 + 错误码(含 40001/40003/40004/40101/40103/40301/40302/40401/40901/40902/42301)+ 通用分页 VO |
backend/src/main/java/com/xly/erp/common/exception/{BizException,GlobalExceptionHandler}.java |
Create | 业务异常 + 全局 @RestControllerAdvice |
backend/src/main/java/com/xly/erp/common/security/{JwtUtil,LoginContext,RequireSuperAdmin,JwtHandlerInterceptor}.java |
Create | JWT 工具 + ThreadLocal + 角色守卫注解 + 鉴权拦截器 |
backend/src/main/java/com/xly/erp/common/config/{PasswordEncoderConfig,WebMvcConfig}.java |
Create | BCrypt Bean + interceptor 注册 |
backend/src/main/java/com/xly/erp/module/usr/entity/Sys*.java |
Create | SysUser / SysCompany / SysEmployee / SysPermissionCategory / SysUserPermissionCategory 5 张表实体 |
backend/src/main/java/com/xly/erp/module/usr/mapper/Sys*Mapper.java + UserQueryParams.java
|
Create | 5 个 mapper + REQ-004 查询参数 DTO |
backend/src/main/java/com/xly/erp/module/usr/dto/{LoginReq,CreateUserReq,UpdateUserReq,UserQueryReq}.java |
Create | 4 个请求 DTO |
backend/src/main/java/com/xly/erp/module/usr/vo/{LoginVo,UserInfoVo,CreateUserVo,UserDetailVo,UserListItemVo}.java |
Create | 5 个响应 VO |
backend/src/main/java/com/xly/erp/module/usr/service/*Service.java + impl/*ServiceImpl.java
|
Create | LoginService / UserCreateService / UserDetailService / UserUpdateService / UserListService |
backend/src/main/java/com/xly/erp/module/usr/controller/{AuthController,UserController}.java |
Create | 5 个 HTTP 端点(POST /auth/login,POST/GET/PUT /users,GET /users/{id}) |
backend/src/test/... |
Create | 14 个测试类,201 个测试方法 |
scripts/test.sh |
Modify | 把 ./mvnw 改为系统 mvn(与 docs/07 § 一 Maven 3.9.x 依赖对齐;backend 未带 wrapper) |
docs/05-API接口契约.md |
Modify | REQ-002 去 password 字段 / 40002;REQ-003 补 GET 详情段;REQ-004 错误码列表补 sortField + 40101 |
文件总数:59 个新建(44 个 main + 14 个 test),1 个修改(scripts/test.sh + docs/05);约 5118 行 backend/ 净增。
④ 数据库使用表
- 读:
sys_user,sys_company,sys_employee,sys_department,sys_permission_category,sys_user_permission_category - 写:
sys_user(新增 / 部分字段更新 / 登录追踪字段 / 失败计数原子 UPDATE),sys_user_permission_category(增删差集)
sys_company/sys_employee/sys_department本模块全程只读使用;新增 / 编辑这三张表的接口推迟到后续运营 / HR 模块。
⑤ 测试结果
-
scripts/test.sh最终:GREEN(详见docs/superpowers/module-reports/module_usr-test-gate.md) - 通过: 201 / 失败: 0 / 跳过: 0
- 覆盖率: 未配置覆盖率插件;REQ 级 spec 验收覆盖:
- REQ-USR-001:12/12(含 BizException 单测、JWT 单测、并发原子累加回归)
- REQ-USR-002:15/15(spec § 15 唯一索引兜底未单测,依赖文本匹配;记入 ⑩)
- REQ-USR-003:22/22(spec § 23 作废用户登录路径属 REQ-USR-001 既有,不重复)
- REQ-USR-004:26/26(含 spec § 业务规则 3 isDeleted/lastLoginDate 强制 equals 回归)
⑥ 本模块新增 Migration
—(本模块无 schema 改动;V1__initial_schema.sql 已在 A 阶段建好 6 张表,本模块全程复用)
⑦ 跨模块改动清单(软规则 S2)
—(本模块未触碰其他模块代码;scripts/test.sh 改动属于项目级基础设施修复,不构成跨模块改动。docs/05 修订属于本模块自己的 API 契约同步。)
⑧ 偏离 spec 清单
- REQ-USR-001: docs/04 § 1.6 描述了 access + refresh token 双 token 模型,本 REQ 只签发 access token;refresh 推迟到后续 REQ。spec 已显式声明此偏离。
- REQ-USR-001: docs/04 § 1.6 提及"签发后写 Redis",本 REQ 不实现 Redis 黑名单,JWT 自包含验证。spec 已声明。
- REQ-USR-002: REQ 卡片表 1 与 docs/05 在密码字段处理上原本冲突;spec 锁定为"系统生成初始密码 666666"(以 REQ 卡为准),docs/05 同步删除 password 字段与 40002 错误码。
- 跨 REQ 文档冲突: docs/04 § 1.3 错误码段位(10xxx/20xxx/.../60xxx)与 docs/05 + 代码实际使用的 HTTP-aligned 段位(40001/40101/40301/40901/...)不一致。本模块沿用 docs/05 + HTTP-aligned 方案;建议后续单独 PR 修订 docs/04 § 1.3 表述以拉齐 SSoT。
⑨ AI reviewer 报告汇总
- REQ-USR-001: round 1 — request-changes(4 high + 7 medium,已落地 5 项修复);round 2 — approve(4 nice-to-have)
- REQ-USR-002: round 1 — approve(13 nice-to-have,0 must-fix)
- REQ-USR-003: round 1 — approve(6 nice-to-have,0 must-fix;归档时顺手补 docs/05 PUT § 40101)
- REQ-USR-004: round 1 — request-changes(2 medium);round 2 — approve(4 nice-to-have)
⑩ 已知问题
-
spec § 15 唯一索引兜底(REQ-USR-002)未单测: UserCreateServiceImpl 在 DataIntegrityViolationException 时通过 message 文本匹配
uk_sys_user_username/uk_sys_user_code转 40901/40902;与 MySQL 驱动版本/locale 强耦合,缺 @SpyBean 模拟回归测试。建议后续用SQLState='23000' + 错误号 1062解析 + 单测覆盖。 -
权限分类批量插入未走 batchInsert: REQ-USR-002 / 003 用 for + 单条 insert(N 次 IO)。当前 N < 20 可接受,建议未来补
insertBatch。 -
permissionCategoryIds 差集无乐观锁: REQ-USR-003 并发 PUT 同一用户可能产生交叉写入。建议未来引入
sys_user.iVersion做乐观锁。 - ErrorCode.COMPANY_NOT_FOUND 复用语义错位: REQ-USR-002 / 003 用 40004 抛"权限分类不存在",常量名 COMPANY_NOT_FOUND 与 message 字面冲突。建议重命名为 RELATED_ENTITY_NOT_FOUND 或拆专用 code。
- entity Lombok 字段沿用 SQL 列名匈牙利前缀: 偏离 docs/04 § 1.2 Java 字段小驼峰约定。当前为了让 MyBatis-Plus 零配置映射;建议未来 refactor 用 @TableField 显式映射。
- 跨文档错误码段位冲突: docs/04 § 1.3 vs docs/05 + 代码(见 ⑧ 偏离)。
- mapper XML ORDER BY 硬编码 u.* 前缀: REQ-USR-004 sortField 白名单当前仅 sys_user 表列;未来扩展到 e.* / d.* 列需更新前缀逻辑。
- JwtHandlerInterceptor 每请求重查 DB: 无缓存;后续容量评估后可加 Caffeine 短期缓存。
- scripts/test.sh 之前调用不存在的 ./mvnw: 本模块期间发现并修复(改用系统 mvn);首次 test-gate 失败已记录在 test-gate evidence。
⑪ 下一模块预览
后端阶段仅本一个模块(module_usr),全部 REQ 已完成。
下一步:本 MR 合并到 master 后,重跑 /erp-workflow:coding-start,会自动检测 backend_done=true && frontend_done=false,派发 frontend-start 进入前端阶段。前端阶段会以 prototype/ 的 HTML mockup 为权威推导 FE 业务功能清单,按 FE 循环(fe-feature-brainstorm → plan → tdd → verify → review)完成。
前端预期工作量:基于已实现的 6 个端点(auth/login、users CRUD + 列表 + 详情),FE 至少需要:登录页、用户列表 + 筛选页、用户新增 / 编辑 Modal 表单。prototype/ 目前为空,进入前端阶段时 frontend-start 会通过 AskUserQuestion 引导补齐 mockup。
⑫ MR 链接
—(由 mr-create 在推送 + 创建 MR 后回写此处)