Files
leaudit-platform-backend/docs/权限与地区隔离/模块级真实落地清单与下一步动作.md
T

21 KiB

模块级真实落地清单与下一步动作

适用范围:leaudit-platform 当前权限、地区、租户、多租户入口模块改造的真实工程进度
更新日期:2026-05-21
文档定位:按模块判断“已落地 / 半落地 / 未开始 / 风险点 / 下一步动作”,便于逐模块把控,不再只看大 Phase。


1. 使用说明

本文档不再按“方案章节”描述,而是按真实模块拆分。

每个模块统一给出 5 个结论:

  1. 当前状态
  2. 已落地内容
  3. 未完成内容
  4. 主要风险
  5. 下一步动作

状态分级说明:

  • 已落地
  • 半落地
  • 已触达但未验收
  • 基本未开始

2. 总体判断

当前系统最真实的现状不是“权限改造未开始”,而是:

  1. 租户底座和兼容层已经开始落地
  2. 部分业务模块已接入租户参数或租户解析
  3. 但很多模块仍在用旧 area/region 作为最终边界字段
  4. 统一权限执行器还没有成为公共主链
  5. RAG 等模块仍存在角色硬编码残留

也就是说,当前最需要防的不是“没设计”,而是“半改状态继续扩散”。


3. 模块清单

3.1 租户主数据模块

涉及文件:

当前状态:进行中

已落地内容:

  1. sys_tenants / sys_tenant_aliases / sys_tenant_feature_flags 已建表
  2. TenantResolver 已提供统一租户解析
  3. TenantServiceImpl 已支持主数据查询和 legacy fallback
  4. TenantController 已提供:
    • GET /api/v3/tenants
    • GET /api/v3/tenants/options
    • GET /api/v3/tenants/{tenantCode}
    • POST /api/v3/tenants
    • PUT /api/v3/tenants/{tenantCode}
    • PATCH /api/v3/tenants/{tenantCode}/status
  5. 前端已补齐租户 API 封装:
    • getTenants()
    • getTenantByCode()
    • createTenant()
    • updateTenant()
    • updateTenantStatus()
  6. 前端已新增独立 /tenants 租户管理页
  7. RBAC 已补 /tenants 菜单蓝图和 rbac:tenants:* 权限定义

未完成内容:

  1. 删除接口还没做
  2. 更复杂的租户树/批量维护能力还没做
  3. 下游业务引用检查仍可继续扩展到更多业务表

主要风险:

  1. 如果 RBAC 种子未被触发,老环境角色可能暂时还看不到新菜单
  2. 当前引用检查先覆盖了用户、入口模块、子租户,尚未扩展到所有业务表

下一步动作:

  1. 联调创建/更新/启停接口
  2. 扩展引用检查到更多业务表
  3. 进入 T9 收尾验收

3.2 登录 / 当前用户上下文

涉及文件:

当前状态:已落地

已落地内容:

  1. sso_users 动态列读取已兼容旧库缺失 tenant_code/tenant_name
  2. 登录后返回已接入 TenantResolver.ResolveUserContext()
  3. 当前用户接口已开始输出:
    • tenant_code
    • tenant_name
    • tenant_type
  4. OAuth 登录已明确禁止前端直接覆盖可信地区字段

未完成内容:

  1. 用户租户归属仍主要依赖 sso_users.area + tenant_code 混合状态
  2. 还没有后台用户租户维护闭环
  3. 还没有彻底把“用户归属租户”和“数据访问范围”解耦

主要风险:

  1. 用户返回有 tenant_code,并不代表所有业务查询都已经按它执行
  2. 仍可能出现“用户上下文是租户化的,业务 SQL 仍按旧地区字段比对”

下一步动作:

  1. 明确用户主归属字段只认 tenant_code
  2. 用户管理接口补齐租户设置/修改能力
  3. 审计所有下游是否仍直接只取 payload.area

3.3 首页入口模块

涉及文件:

当前状态:已完成 T8 收口

已落地内容:

  1. 首页入口读取已经接入用户租户解析
  2. 已优先读取 leaudit_entry_module_tenants
  3. 在关系表缺失时可回退旧 areas JSON
  4. 已支持 PUBLIC 与用户租户联合过滤
  5. super_admin 已有绕过租户逻辑
  6. 已确认后端 /api/home/entry-modules000 真实返回 5 个入口模块
  7. 已确认前端首页此前无入口的根因是兼容层漏识别 targetPath/routePath
  8. 前端兼容层修复后,/api/auth/session-data 已真实返回 entryModules=5
  9. 首页交叉评查入口判断已改为 tenants 优先;只要模块存在租户配置,前端不再回退按 areas 判定
  10. 首页后端租户过滤已收紧,去掉了 em.areas IS NULL / jsonb_typeof <> 'array' 这类会放宽边界的 fallback
  11. 首页前端标准化时已优先使用 tenants 反推兼容 areas,首页主消费链路不再依赖旧 areas 原始值

未完成内容:

  1. 首页接口仍保留 areas 兼容输出
  2. 旧 JSON 与关系表双写仍属于过渡态
  3. 后续若要彻底去兼容,需要配合历史数据清理再收最后一刀

主要风险:

  1. 新模块如果只配关系表、不配旧 areas,下游兼容没收干净时仍可能表现异常
  2. default 仍可能造成边界模糊

下一步动作:

  1. T8 可视为完成,后续不再把首页入口当作阻塞项
  2. 对现有入口模块逐条核对关系表数据
  3. 进入 T9 租户主数据维护能力开发

3.4 入口模块后台管理

涉及文件:

当前状态:已完成 T8 收口

已落地内容:

  1. 已引入 leaudit_entry_module_tenants
  2. 列表/详情已支持关系表读取
  3. 创建/更新已支持 tenants 入参标准化
  4. 关系表缺失时可降级到旧 areas
  5. 已实现旧 areas 与新 tenants 的兼容转换
  6. 已确认“后台配了入口但首页没显示”不是后台配置失败,而是首页前端兼容层问题
  7. 前端入口模块创建/更新请求已改成只以下发 tenants 为主,areas 不再作为主提交流程字段
  8. 入口模块列表页展示已改成只以 tenants 为主,areas 仅在编辑页做历史兼容回显
  9. 后端已新增“适用租户不能为空”校验,空 tenants 提交会被明确拒绝
  10. 入口模块管理端编辑页已不再读取 areas,管理端消费层已完全改为只消费 tenants
  11. 入口模块管理端列表/详情接口已不再对外返回 areas,管理端返回结构已收口为 tenants 主模型

未完成内容:

  1. 旧 JSON 与关系表仍处于双写兼容期
  2. 后续若要彻底删掉 areas 存储,需要单独安排数据清理窗口
  3. 权限控制还不是“入口模块 + 租户能力 + permission”闭环

主要风险:

  1. 后端写了兼容层,但前端如果还传旧字段,会继续固化旧模型
  2. 关系表与旧 JSON 双写期间,容易出现数据不一致

3.5 T5 评查点模块

涉及文件:

当前状态:首轮 tenant-first 收口已完成

已落地内容:

  1. 列表、详情、创建、更新已经改成 tenant_code 优先,老表没有 tenant_code/tenant_name 时才回退到 area
  2. 创建、更新写入链路已支持同步写 tenant_code/tenant_name
  3. 全局用户维护非公共评查点时,缺失标准 tenant_code 会被拒绝
  4. 控制器列表查询不再把当前用户租户误当成“显式筛选条件”硬塞回去
  5. T5-1 已完成:评查点列表读链路已拆开“当前用户租户上下文”和“显式筛选租户条件”,避免读范围判断漂移
  6. T5-1 已完成:清理了遗留的 visible_areas 无效 SQL 绑定残留
  7. T5-2 已完成第一轮:更新接口不再把原始 area 自由文本直接写成归属字段,统一改为从解析后的 writable_scope 推导
  8. T5-2 已完成第一轮:PUBLIC/PROVINCIAL公共/省级/default 共享域写入已统一归一化到标准租户编码
  9. T5-2 已完成第一轮:全局用户若未显式指定租户或共享域,创建/更新会直接拒绝,避免静默落到错误范围
  10. T5-3 已完成第一轮:列表/详情的共享域读范围已优先按 PUBLIC/PROVINCIAL 命中,旧 公共/default/空值/省局/省级 仅作为老数据 fallback
  11. T5-4 已完成第一轮:评查点模块主链路的全局/管理能力判定已改为 data_scope + evaluation_point:* 权限推断,不再直接写死角色名;仅保留查不到数据库上下文时的兼容兜底
  12. T5-5 已完成第一轮:查不到数据库用户上下文时,已移除 payload.user_role 角色名兜底;fallback 默认不再推断全局范围,只保留租户解析和权限服务判定

未完成内容:

  1. 物理表层面还没有彻底摆脱 area
  2. visible_areas -> visible_tenant_codes 的最终命名与统一执行器接入仍未完成
  3. 统一数据范围执行器与最终 area 兼容层下线还没接进来

主要风险:

  1. 容易误以为“接口看起来有 tenant_code”就等于模块已完全租户化
  2. 如果数据库没有执行补字段脚本,仍只能停留在兼容模式

下一步动作:

  1. 先补数据库字段和历史回填
  2. 再把评查点模块内共享域中文常量继续下沉到更薄的兼容层
  3. 最后配合数据库历史回填收掉 area 物理兼容层

3.6 合同模板模块

涉及文件:

当前状态:已完成首轮联调,未完成全量收口

已落地内容:

  1. controller 已接受 region + tenant_code
  2. service 已引入 TenantResolver
  3. 列表/搜索/详情查询开始考虑 region/tenant_code

未完成内容:

  1. SQL 结果里仍直接写:
    • ''::VARCHAR AS tenant_code
    • t.region AS tenant_name
  2. 也就是模板模块当前本质上还没有真实租户字段
  3. 仍属于“参数长得像租户化,存储与返回仍是旧 region 模型”

主要风险:

  1. 前端可能误以为该模块已经支持标准租户编码
  2. 实际上租户边界仍受 region 历史值影响

下一步动作:

  1. 合同模板表补 tenant_code
  2. 返回结构不再伪造空 tenant_code
  3. 分类、搜索、详情统一改为按租户编码过滤

3.7 RAG 知识库模块

涉及文件:

当前状态:第一轮高风险收口已完成,未完成最终验收

已落地内容:

  1. controller 已传入 TenantCode/TenantName
  2. service 已引入 TenantResolver
  3. 已支持请求的租户/地区标准化

未完成内容:

  1. 仍然存在显式角色白名单:
    • provincial_admin
    • admin
    • super_admin
  2. 管理权限仍不是纯 permission 驱动
  3. 数据集主字段仍大量使用 area
  4. 前端数据集管理目录仍明显保留 area-dataset 旧命名体系

主要风险:

  1. 这是当前角色去硬编码最明显的残留区
  2. 也是最容易出现“自定义角色有权限但不能用”的模块

下一步动作:

  1. 先移除 service 里的角色白名单
  2. 用 permission + tenant scope 替代
  3. area-dataset 命名体系升级成 tenant-dataset

3.8 文档模块

涉及文件:

当前状态:半落地

已落地内容:

  1. 上传接口已接受 TenantCode/TenantName
  2. 已通过 TenantResolver 解析上传侧地区/租户
  3. 返回侧已开始回写解析后的租户信息
  4. 用户上下文开始兼容租户字段

未完成内容:

  1. 存储主字段仍是 region
  2. 版本链、路径构建、重复判断等核心逻辑仍按 region
  3. 还没有看到统一 DocumentPolicy + PermissionDecision 完整闭环证据

主要风险:

  1. 文档模块是主数据域,若仍按 region 跑,后续所有统计/详情/附件都有边界不一致风险
  2. 新租户一旦不等于历史中文地区名,旧逻辑会直接出错

下一步动作:

  1. 文档主表补 tenant_code
  2. 列表/详情/状态/附件统一按租户边界过滤
  3. region 退化为展示兼容字段

3.9 内部公文模块

涉及文件:

当前状态:半落地

已落地内容:

  1. 上传/列表接口已接受 tenantCode
  2. 已引入 TenantResolver
  3. 上传前已解析租户请求
  4. 当前用户上下文已开始租户化

未完成内容:

  1. 最终写入和版本判断主字段仍是 resolvedRegion
  2. 也就是公文模块本质仍在用旧地区值做主边界
  3. 未见统一权限执行器完全接入

主要风险:

  1. 与文档模块同类,属于“参数租户化、底层 region 化”
  2. 真实多租户扩展时会先在这里出边界问题

下一步动作:

  1. 公文文档链路补 tenant_code
  2. 版本链判断、上传归属、列表过滤统一切租户编码
  3. region 仅保留兼容展示

3.10 系统使用统计模块

涉及文件:

当前状态:半落地

已落地内容:

  1. 登录事件记录已接入 TenantResolver.ResolveUserContext()
  2. 登录审计写入前已做租户标准化
  3. 服务已引入 SsoUserCompat + TenantResolver

未完成内容:

  1. 当前快照写入字段仍是 area_snapshot
  2. 未见标准 tenant_code_snapshot
  3. 统计查询是否完全按租户边界,还需要继续核验下半段 SQL

主要风险:

  1. 审计留痕如果不记标准 tenant_code,后续历史统计会很难稳定迁移
  2. 统计口径可能继续受历史中文地区值影响

下一步动作:

  1. 审计事件表补 tenant_code_snapshot
  2. 统计聚合统一按标准租户编码
  3. 地区维度改成“租户展示维度”

3.11 RBAC 管理域

涉及文件:

当前状态:已触达但未验收

已落地内容:

  1. 已引入 SsoUserCompat + TenantResolver
  2. 用户列表和上下文读取已开始兼容 tenant_code/tenant_name
  3. 部分列表/树结构已开始计算 tenant label
  4. 已新增用户租户设置 DTO/VO、service 能力与 controller 接口
  5. 已新增 PUT /api/v3/rbac/users/{UserId}/tenant
  6. 已完成前端“设置租户”弹窗与接口联调
  7. 已真实验证 000 用户可成功设置 tenant_code=MZ
  8. 用户列表、角色用户列表已按 tenant_code 优先过滤,旧 tenant_name/area 仅作无 tenant_code 兼容回退
  9. 组织树已改为 tenant_code 优先分组,节点主键从展示名切到稳定租户编码
  10. 用户角色分配、用户角色查询已补“目标用户必须在当前管理员租户范围内”校验

未完成内容:

  1. can_manage/is_global/is_super_admin 仍由角色名派生,尚未切到统一 permission + policy
  2. 组织树仍保留 tenant_name/area 兼容展示值,尚未完全接入租户主数据树
  3. 还没有形成“用户归属租户 + 管理范围 + 数据权限”的统一执行器模型

主要风险:

  1. RBAC 管理域如果长期继续用角色名派生管理能力,会拖住全项目统一权限执行器落地
  2. 当前属于“tenant-first 已收口,但 policy 未统一”,后续若新增接口仍可能绕回手写边界

下一步动作:

  1. can_manage/is_global 从角色名派生迁到后端统一权限/能力快照
  2. 组织树进一步过渡到租户主数据树,而不是仅基于用户表动态拼树
  3. 角色授权与租户边界分开建模,并纳入统一 RbacAdminPolicy

3.12 前端租户接入

涉及目录:

  • legal-platform-frontend/lib/api/legacy/tenants/tenants.ts
  • legal-platform-frontend/app/(audit)/entry-modules/*
  • legal-platform-frontend/components/dify-dataset-manager/*
  • legal-platform-frontend/hooks/use-area-dataset-config.ts

当前状态:已触达但未收口

已落地内容:

  1. 前端已有 /api/v3/tenants/options 调用封装
  2. 入口模块前端已有新页面改造痕迹
  3. RAG 前端有较多对应改造痕迹

未完成内容:

  1. 仍广泛保留 area-dataset 命名
  2. 仍需要核查是否存在按角色名显示按钮/菜单的逻辑
  3. 还未证明页面全部优先认 tenant_code

主要风险:

  1. 后端改了但前端仍传旧字段,会持续把旧模型写回系统
  2. 命名层长期保留 area,会误导后续开发继续写旧逻辑

下一步动作:

  1. 前端新表单统一只选租户,不再手输地区
  2. area-* 命名逐步迁到 tenant-*
  3. 清理按钮/guard 中的角色硬编码

4. 当前优先级排序

如果按“最容易继续出错 / 越权 / 落错数据”排序,当前建议这样推进:

  1. 入口模块后台 + 租户主数据写能力
    • 原因:这是后续新增租户和新增入口能否真正闭环的当前缺口
  2. 文档模块
    • 原因:主数据域,后续所有统计和评查都依赖它
  3. 内部公文模块
    • 原因:与文档链路类似,仍是 region 主模型
  4. 合同模板模块
    • 原因:已接参数但底层未真正租户化,且属于配置/检索域
  5. 统计模块
    • 原因:需要尽快固化标准租户审计快照
  6. RAG 模块
    • 原因:角色白名单残留明显,最容易出现自定义角色不可用
  7. 评查点模块
    • 原因:已经半租户化,但底层仍是 area 模型

5. 最关键的工程判断

现在不能再笼统说“项目已经租户化”。

更准确的说法是:

  1. 底座已租户化一部分
  2. 入口模块已开始关系化
  3. 用户上下文已开始输出租户信息
  4. 但多个核心业务模块仍以 area/region 作为最终执行边界

因此,后续改造主线必须从“传了 tenant 参数就算完成”升级为:

  1. 数据库存标准 tenant_code
  2. 查询边界按 tenant_code
  3. 返回结构带 tenant_code + tenant_name
  4. area/region/default/省级/省局 只保留兼容层

6. 建议配套阅读

  1. 权限与租户改造当前进度总览.md
  2. 权限改造实施任务拆解与排期.md
  3. 角色去硬编码迁移清单.md
  4. 地区到租户编码映射清洗清单.md