3 Commits

Author SHA1 Message Date
lovife 1f3c485ceb feat(role,scope)!: 角色与授权可配 + 需求收敛(4 角色 / 10 菜单 / 删两模块)
角色与授权(交接摘要 §一·三十五):
- 权限判定合并两个来源:内置角色按代码(BuiltinRole)、自定义角色按库
  (sys_role_permission)。实现放 module 层的 DbRoleGrantSource,security 只依赖
  接口 RoleGrantSource —— 否则角色服务要调 permissionChecker,两个包迟早成环
- 权限判定必须加缓存:此前是零 IO,而压测基线是"SQL 条数恒定"。缓存放 Redis,
  空结果也缓存(否则已删角色的 token 会把库打穿)、Redis 挂了退化成直读库、TTL 只兜底
- V18 建 sys_role.user_type(账号的 user_type 一直从角色反推,自定义角色不在代码映射里)
  与 sys_role_menu;8 个接口 + 错误码 40045;契约 119 -> 129
- 内置角色只读(权限码是前后端契约,做成可改 = 一次误操作就能把管理员锁在系统外);
  平台级能力两道防线(界面禁用 + 服务端 40301);防自锁;改完立即生效(写授权清缓存)
- RoleProvisioner 从"已存在就 continue"改成幂等回填 + 每日 03:20 定时任务 ——
  修的是"代码改了权限、已开通租户永远停在发放那一刻",这种漂移不报错也没测试会红
- scripts/e2e-m10-role.py 77/77

需求收敛(交接摘要 §一·三十六,本节的数字为准):
- 删副班主任 / 审核员两个内置角色(6 -> 4)、历史整理器(module/cleanup)、
  加入申请(module/join + 学生端 pages/join)、collect_task_org.deputy_user_ids 整列;
  审核范围三级回退 -> 两级,连带 6 个 mapper 的 LIKE '%,id,%' 分支
- V19 迁移处理存量:先解 sys_user_role 绑定再软删角色;账号只在"除这两个角色外没有
  别的角色"时才软删。必须迁而不能只删代码 —— 角色码删掉后 mergePermissions 返回空集,
  存量账号会"能登录、处处 40301",不抛异常不打日志
- 契约 129 -> 119、错误码 59 -> 54、权限码 30 -> 28、PC 菜单 12 -> 10、
  小程序页 10 -> 9、原型 32 -> 29 屏、E2E 39 -> 37 个(断言 1695 条)
- UserService.list 对不认识的角色码由"静默丢掉过滤条件"改成失败关闭
  (之前传个不存在的 roleCode 会返回全校账号,且看起来完全正常)
- 品牌元信息同步改名「深学在线」:pom 名称、/doc.html 标题、配置与启动类注释、
  存储自检探针内容;学生端 app 名与全局导航栏标题
2026-10-10 16:48:54 +08:00
lovife db8aecc30a chore(e2e,docs): 新脚本的清理只删自己建的模板行(不碰演示态)+ docs/09 §8 补接线检查 2026-10-08 14:47:11 +08:00
lovife 9e78e1d239 feat(notify): 通知接线检查 + 修 F-101~F-111(模板对自动通知生效 / 催报真的会发 / 该发的通知都发了)
起点:F-1/F-31/F-50/F-52 是同一个形状 —— 每处单看都对,编译/lint/review 全不红,只有从入口走一遍才暴露。先把这一类固化成命令,再按输出逐条修。

新增 scripts/check-wiring.py:权限码有没有地方校验、错误码有没有被引用、站内信模板有没有发送点、bizType 有没有被用过、菜单键 ↔ PC 端 XtMenu 双向核对。有意不接线的写进脚本上方例外表(带理由)。进 verify-all(第 5 项)与 CI 的 check 阶段。检查器自身修了三次假阳性:只数 @RequirePerm 漏掉服务层校验、按标识符数引用被同名常量骗过、注释里的提及被当成接线(改为先去 Java 注释再数)。

F-101 自动通知改走可配置模板(FR-1002 原来只兑现了手工发送那一半):新增 NotifyTextResolver(单向依赖避开循环注入),库里改过的 > 内置;模板停用 = 这类通知不发且如实回 notifySent=false。F-102 加入申请三处通知(提交→审批人、通过/驳回→学生)。F-103 导出完成/失败通知发起人,正文不放签名 URL(模板里原本写着 {下载链接},一并改掉)。F-104 自动催报从来没发出过任何一条(end_time = date::date 与库里的 23:59:59 永不相等,测试夹具用 SQL 摆的日期型恰好能匹配)+ 补 FR-1003 的「截止当日」。F-105 驳回达上限通知管理员(契约与注释都写了,代码只有一行日志)。F-106 字典/通知记录两个菜单没有任何角色持有(手册还写着去那里办)。F-107 6 个权限码挂到自己的接口。F-109 Map.of 不接受 null → 通知被吞成一行 warn。F-110/F-111 测试自身的两个坑。

验证:新增 e2e-m5-notify-wiring.py 43 条(改模板→真驳回→断言学生收到改过的那句、停用→一条不发、申请/审批/导出/催报/升级/菜单/权限各一节);verify-all --with-e2e → 9 项全过 0 跳过,38 个脚本 / 1620 条断言 / 0 失败。
2026-10-08 14:46:11 +08:00