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