feat: add tenant-scoped rule and permission management
This commit is contained in:
@@ -0,0 +1,335 @@
|
||||
# 地区到租户编码映射清洗清单
|
||||
|
||||
> 适用范围:当前系统中 `area / region / 省局 / 省级 / default / 空字符串 / tenant_name` 混合使用的历史数据治理
|
||||
> 文档定位:给后续数据库清洗、兼容脚本、接口兼容层和测试验收提供一份可执行的“历史值归一清单”。
|
||||
|
||||
---
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
当前系统如果直接上 `tenant_code`,但不先做历史值映射清洗,会立刻出现三类问题:
|
||||
|
||||
1. 同一租户在不同表里仍然无法匹配
|
||||
2. 首页入口、RAG、模板、文档等模块会出现“配置了但看不到”
|
||||
3. 统计和权限执行器会因为历史脏值继续分裂
|
||||
|
||||
所以租户化改造的第一前提不是写新表,而是先收口旧值。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前确认存在的历史值类型
|
||||
|
||||
按目前代码和 SQL 已确认的高风险值如下。
|
||||
|
||||
## 2.1 地方租户值
|
||||
|
||||
1. `梅州`
|
||||
2. `云浮`
|
||||
3. `揭阳`
|
||||
4. `潮州`
|
||||
|
||||
## 2.2 省级 / 公共语义值
|
||||
|
||||
1. `省局`
|
||||
2. `省级`
|
||||
3. `default`
|
||||
4. `''`
|
||||
|
||||
## 2.3 展示或组织补充字段
|
||||
|
||||
1. `tenant_name`
|
||||
2. `dep_name`
|
||||
3. `ou_name`
|
||||
|
||||
这些值目前在部分前端逻辑里被拿来反推地区。
|
||||
|
||||
---
|
||||
|
||||
## 3. 推荐标准租户编码
|
||||
|
||||
建议先建立一套稳定编码:
|
||||
|
||||
| 现展示值 | 推荐 tenant_code | tenant_type | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| 梅州 | `MZ` | `LOCAL` | 地市租户 |
|
||||
| 云浮 | `YF` | `LOCAL` | 地市租户 |
|
||||
| 揭阳 | `JY` | `LOCAL` | 地市租户 |
|
||||
| 潮州 | `CZ` | `LOCAL` | 地市租户 |
|
||||
| 省局 | `PROVINCIAL` | `HEADQUARTER` | 省局管理租户 |
|
||||
| 公共资源域 | `PUBLIC` | `PUBLIC` | 跨租户公共资源,不建议继续用中文值 |
|
||||
|
||||
说明:
|
||||
|
||||
1. `PROVINCIAL` 表示省局这个租户主体
|
||||
2. `PUBLIC` 表示真正公共资源域
|
||||
3. 以后不要再让 `省局` 既表示租户又表示公共范围
|
||||
|
||||
---
|
||||
|
||||
## 4. 历史值映射规则
|
||||
|
||||
## 4.1 推荐映射表
|
||||
|
||||
建议如下:
|
||||
|
||||
| 历史值 | 归一 tenant_code | 处理说明 |
|
||||
| --- | --- | --- |
|
||||
| `梅州` | `MZ` | 直接映射 |
|
||||
| `云浮` | `YF` | 直接映射 |
|
||||
| `揭阳` | `JY` | 直接映射 |
|
||||
| `潮州` | `CZ` | 直接映射 |
|
||||
| `省局` | `PROVINCIAL` | 表示省局租户主体 |
|
||||
| `省级` | `PUBLIC` 或 `PROVINCIAL` | 需按业务字段判定,不能一刀切 |
|
||||
| `default` | `PUBLIC` | 仅限公共兜底语义,不应映射成省局主体 |
|
||||
| `''` | `PUBLIC` 或 `UNKNOWN` | 需分场景处理 |
|
||||
| `NULL` | `PUBLIC` 或 `UNKNOWN` | 需分场景处理 |
|
||||
|
||||
## 4.2 为什么 `省级` 不能一刀切
|
||||
|
||||
`省级` 在当前系统至少有两种含义:
|
||||
|
||||
1. 省局主体租户
|
||||
2. 全省公共资源
|
||||
|
||||
例如:
|
||||
|
||||
1. 合同模板里的 `省级` 更接近公共模板域
|
||||
2. 某些角色或用户语义里的“省级管理员”更接近省局主体
|
||||
|
||||
所以 `省级` 必须结合表和业务语义判断,不能直接全量更新成一个值。
|
||||
|
||||
---
|
||||
|
||||
## 5. 按表清洗策略
|
||||
|
||||
## 5.1 `sso_users`
|
||||
|
||||
重点字段:
|
||||
|
||||
1. `area`
|
||||
2. `tenant_name`
|
||||
|
||||
建议:
|
||||
|
||||
1. 新增 `tenant_code`
|
||||
2. 先根据 `area` 映射
|
||||
3. `area` 为空时再尝试依据 `tenant_name`
|
||||
4. 仍无法识别的写入 `UNKNOWN` 或留空待人工处理
|
||||
|
||||
人工复核重点:
|
||||
|
||||
1. `area` 为空但 `tenant_name` 不为空
|
||||
2. `area` 和 `tenant_name` 语义冲突
|
||||
3. 一个 `tenant_name` 对应多个 `area`
|
||||
|
||||
## 5.2 `leaudit_documents`
|
||||
|
||||
重点字段:
|
||||
|
||||
1. `region`
|
||||
|
||||
建议:
|
||||
|
||||
1. `default` 先归到 `PUBLIC`
|
||||
2. 地方地区名直接归到对应 `tenant_code`
|
||||
3. 不可识别值进入人工复核表
|
||||
|
||||
## 5.3 `contract_templates`
|
||||
|
||||
重点字段:
|
||||
|
||||
1. `region`
|
||||
|
||||
建议:
|
||||
|
||||
1. `省级` 默认优先解释为 `PUBLIC`
|
||||
2. 如果后续明确部分模板实际是省局内部专属,再单独调整为 `PROVINCIAL`
|
||||
|
||||
原因:
|
||||
|
||||
合同模板当前更接近“公共模板库”模型。
|
||||
|
||||
## 5.4 `rag_dataset` / `rag_chat_app`
|
||||
|
||||
重点字段:
|
||||
|
||||
1. `area`
|
||||
2. `is_public`
|
||||
3. `is_default`
|
||||
|
||||
建议:
|
||||
|
||||
1. 地方地区名直接映射
|
||||
2. `area=''` 且 `is_public=true` 的,映射到 `PUBLIC`
|
||||
3. `area='省级'` 的记录,默认映射到 `PUBLIC`
|
||||
4. `is_default=true` 不代表公共,只代表默认应用/默认知识库
|
||||
|
||||
## 5.5 `leaudit_entry_modules`
|
||||
|
||||
重点字段:
|
||||
|
||||
1. `areas JSONB`
|
||||
|
||||
建议:
|
||||
|
||||
1. 逐个 `area` 元素映射到标准 `tenant_code`
|
||||
2. 保留原始 JSON 快照供审计
|
||||
3. 后续写入迁移到关系表,不再长期依赖原 JSON
|
||||
|
||||
---
|
||||
|
||||
## 6. 代码级归一规则
|
||||
|
||||
## 6.1 所有输入都必须先归一
|
||||
|
||||
后续后端收到以下字段时,都必须先走统一归一函数:
|
||||
|
||||
1. `area`
|
||||
2. `region`
|
||||
3. `tenant_name`
|
||||
4. 前端传入的入口模块租户列表
|
||||
5. RAG/模板筛选条件
|
||||
|
||||
建议统一函数签名:
|
||||
|
||||
```python
|
||||
resolve_tenant_code(raw_value: str | None, context: str) -> str | None
|
||||
```
|
||||
|
||||
其中 `context` 用于区分:
|
||||
|
||||
1. `user_area`
|
||||
2. `document_region`
|
||||
3. `template_region`
|
||||
4. `entry_module_area`
|
||||
5. `rag_area`
|
||||
|
||||
## 6.2 严禁前端继续做别名猜测
|
||||
|
||||
当前前端 `cross-checking-access.ts` 会用:
|
||||
|
||||
1. `includes("梅州")`
|
||||
2. `includes("省")`
|
||||
3. `provincial_admin => 省局`
|
||||
|
||||
这种逻辑必须下线,原因是:
|
||||
|
||||
1. 新租户名字不一定包含旧关键字
|
||||
2. 展示名称变化会导致功能失效
|
||||
3. 前端无法承担主数据归一责任
|
||||
|
||||
---
|
||||
|
||||
## 7. 推荐清洗脚本步骤
|
||||
|
||||
## 7.1 第一步:盘点唯一值
|
||||
|
||||
先导出下列字段的唯一值和数量:
|
||||
|
||||
1. `sso_users.area`
|
||||
2. `sso_users.tenant_name`
|
||||
3. `leaudit_documents.region`
|
||||
4. `contract_templates.region`
|
||||
5. `rag_dataset.area`
|
||||
6. `rag_chat_app.area`
|
||||
7. `leaudit_entry_modules.areas[].area`
|
||||
|
||||
## 7.2 第二步:生成映射表
|
||||
|
||||
生成一张临时对照表:
|
||||
|
||||
1. `raw_value`
|
||||
2. `source_table`
|
||||
3. `sample_count`
|
||||
4. `proposed_tenant_code`
|
||||
5. `review_status`
|
||||
6. `review_comment`
|
||||
|
||||
## 7.3 第三步:区分自动映射和人工复核
|
||||
|
||||
自动映射:
|
||||
|
||||
1. `梅州`
|
||||
2. `云浮`
|
||||
3. `揭阳`
|
||||
4. `潮州`
|
||||
5. `省局`
|
||||
6. `default`
|
||||
|
||||
人工复核:
|
||||
|
||||
1. `省级`
|
||||
2. 空值
|
||||
3. 复合字符串
|
||||
4. 未知中文别名
|
||||
5. 组织名称形式的 `tenant_name`
|
||||
|
||||
## 7.4 第四步:回写标准字段
|
||||
|
||||
为业务表新增 `tenant_code` 后,按映射结果批量回写。
|
||||
|
||||
## 7.5 第五步:保留审计痕迹
|
||||
|
||||
必须保留:
|
||||
|
||||
1. 原始字段值
|
||||
2. 映射规则版本
|
||||
3. 清洗时间
|
||||
4. 执行人
|
||||
5. 人工修正记录
|
||||
|
||||
---
|
||||
|
||||
## 8. 重点风险清单
|
||||
|
||||
## 8.1 `default` 不能全量等于 `PROVINCIAL`
|
||||
|
||||
当前 `default` 更多是“兜底公共范围”,不是“省局租户”。
|
||||
|
||||
如果错误映射为 `PROVINCIAL`,会造成:
|
||||
|
||||
1. 公共资源被省局独占
|
||||
2. 非省局租户看不到原本可见的内容
|
||||
|
||||
## 8.2 `省级` 不能在所有表中同义
|
||||
|
||||
因为它在不同业务里承担的不是同一个概念。
|
||||
|
||||
## 8.3 `tenant_name` 不能直接等于 `tenant_code`
|
||||
|
||||
`tenant_name` 是展示或组织分组名称,数据质量不一定可控。
|
||||
|
||||
## 8.4 入口模块 JSON 最容易残留旧值
|
||||
|
||||
因为它不是结构化关系表,清洗后仍可能被旧接口再次写入脏数据。
|
||||
|
||||
---
|
||||
|
||||
## 9. 推荐验收清单
|
||||
|
||||
清洗完成后至少要验证:
|
||||
|
||||
1. 每个用户都有可解析的 `tenant_code`
|
||||
2. 每个入口模块的租户分配都能映射到有效主数据
|
||||
3. RAG 数据集不会再出现 `''`、`省级`、`default` 混杂
|
||||
4. 合同模板的公共模板不会因为映射错误被隐藏
|
||||
5. 首页入口可见性在旧租户和新租户下都正确
|
||||
6. 统计地区维度不会同时出现 `梅州` 和 `MZ` 两套口径
|
||||
|
||||
---
|
||||
|
||||
## 10. 本文档解决什么问题
|
||||
|
||||
本文档主要解决:
|
||||
|
||||
1. 历史地区值具体怎么映射到租户编码
|
||||
2. 哪些字段必须清洗
|
||||
3. 哪些旧值可以自动处理
|
||||
4. 哪些旧值必须人工复核
|
||||
5. 为什么租户主数据改造前必须先做这一步
|
||||
|
||||
建议联动阅读:
|
||||
|
||||
1. [租户主数据模型设计.md](/home/wren-dev/Porject/leaudit-platform/docs/权限与地区隔离/租户主数据模型设计.md)
|
||||
2. [地区租户化与自定义租户扩展改造方案.md](/home/wren-dev/Porject/leaudit-platform/docs/权限与地区隔离/地区租户化与自定义租户扩展改造方案.md)
|
||||
3. [自定义租户功能连带影响深度补充.md](/home/wren-dev/Porject/leaudit-platform/docs/权限与地区隔离/自定义租户功能连带影响深度补充.md)
|
||||
Reference in New Issue
Block a user