liuyun 802851a69f chore(openspec): track close-phase-0 implementation
sysmgr-nest 收口:RBAC 权限落地 + 审计/登录日志 + seed 脚本。
openspec change close-phase-0 任务全部完成,待归档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-10 23:20:02 +08:00

45 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 1. Redis 接入与权限模型(auth 域)
- [x] 1.1 引入 ioredis 依赖,封装 RedisService(get/set/del/按前缀 SCAN 删除),连接用 env(REDIS_HOST/PORT/DB/PASSWORD、REDIS_KEY_PREFIX,默认 127.0.0.1:6379、`sysmgr:`)
- [x] 1.2 auth.service 登录/刷新时聚合权限码集(user_role → role_resource → resource,取 `type ∈ {button, api}` 的 code)与 `super` 标志(是否绑定 `code=super_admin`),写入 Redis `{prefix}perm:{tenantCode}:{userId}`(TTL 随会话,刷新续期);登出删除
- [x] 1.3 jwt-auth.guard 校验通过后将 userId/tenantCode/username 装入 `request.user`(JWT 不放权限集)
- [x] 1.4 permissions.guard 从 Redis 读 `{super, permissions}`:`super=true` 直接放行;否则校验权限集是否包含全部所需权限码,缺一返回 403
- [x] 1.5 data_scope 过滤对 `super=true` 按「全部」处理(resolveDataScope 或各列表查询入口统一短路)
- [x] 1.6 授权变更失效:roles 模块改 role_resource / user_role 后删除该租户权限缓存(SCAN `{prefix}perm:{tenantCode}:*`)
## 2. 权限码挂接口
- [x] 2.1 定义各域权限码常量清单(`domain:action`):tenant/user/role/resource/org/dict/config/audit/login-log 的 list/create/update/delete 等
- [x] 2.2 tenants、users、roles、resources、orgs、dicts、configs 各 controller 的全部受控接口挂 `@RequirePermissions(...)`(写操作强制;list 按 domain:list 挂)
- [x] 2.3 audit-logs、login-logs 查询接口挂 `audit:list` / `login-log:list`
- [x] 2.4 登录/刷新/登出及 `/docs` 保持 `@Public`,无需权限码
## 3. 审计日志落库
- [x] 3.1 新增 `@AuditLog(module, action)` 装饰器(SetMetadata 记录 module/action)
- [x] 3.2 新增 AuditLogInterceptor:请求进入时快照 tenantCode/userId/username/ip/userAgent/method/path/脱敏 body 与起始时间;完成后异步 fire-and-forget 写入;异常时记告警不阻塞
- [x] 3.3 新增 AuditLogService:写 sys_audit_log(显式传 tenantCode,复用 BodyLogging 脱敏)
- [x] 3.4 注册 AuditLogInterceptor(全局);给各写接口 controller 挂 `@AuditLog(domain, action)`
- [x] 3.5 登录成功/登出写 audit_log(module=auth,action=login/logout)
## 4. 登录日志落库
- [x] 4.1 新增 LoginLogService:写 sys_login_log(username/ip/user_agent/status/message)
- [x] 4.2 auth.service.login 成功分支写 status=success;失败分支写 status=fail + message(密码错误/账号停用/锁定/租户不存在),并附 IP/UA
## 5. seed 脚本
- [x] 5.1 新增 prisma/seed.ts:裸 PrismaClient,按唯一键 upsert,可重复执行
- [x] 5.2 生成租户 `touyun`、根组织、角色 `super_admin`(data_scope=all)、用户 `touyun`(bcryptjs 哈希 `Touyun@123`)并绑定 super_admin
- [x] 5.3 生成全量资源树:菜单(工作台 + 各域导航)、api(每个受控接口一个,code=`domain:action`,含 method/api_path)、button(纯前端按钮)
- [x] 5.4 `role_resource` 将 super_admin 关联全部资源 code
- [x] 5.5 package.json 增加 seed 脚本(prisma db seed 配置)并跑通
## 6. 验证
- [x] 6.1 跑 seed 后以 `touyun` / `Touyun@123` 登录成功,Redis 中生成 `{prefix}perm:touyun:{userId}` 缓存(含 permissions/super)
- [x] 6.2 超管访问受控接口放行、列表查询全量;新建一个无权限的普通用户访问受控接口返回 403
- [x] 6.3 修改某角色授权(role_resource)后,该租户权限缓存被删除,受影响用户下一次请求按新权限生效
- [x] 6.4 写操作后 sys_audit_log 有记录(status/params 脱敏);登录成功/失败后 sys_login_log 有记录(失败含原因)
- [x] 6.5 回归:登录/刷新/登出、现有 CRUD、日志输出均正常;测试后停止服务