Files
leaudit-platform-backend/docs/权限与地区隔离/地区到租户编码映射清洗清单.md
T

336 lines
7.9 KiB
Markdown

# 地区到租户编码映射清洗清单
> 适用范围:当前系统中 `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)