Files
baiyue-firstleg/docs/2026-08-05-Java单租户多客户设计审计汇总结论.md
T

69 lines
5.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.
# Java 单租户多客户设计审计汇总结论
## 结论
当前 Java 主体模型整体符合“业务单租户、平台管理多客户、客户严格隔离”:
- `iam_tenant` 的 `MERCHANT` 记录当前可以继续直接作为客户主档。
- Auth/JWT 和各业务表的 `tenant_id > 0` 当前承载客户 ID,是客户隔离键。
- 平台技术作用域和 RBAC 模板使用 `tenant_id = 0`。
- Order/Firstleg 中的 `customer_id` 多数承载往来单位或业务客户快照,不是 IAM 客户隔离 ID。
- 未发现可通过当前正常公开链路直接完成跨客户读写的 P0,不需要为上线重构全部主体模型。
## 已完成的上线前 P1
1. 公共仓库、往来单位、快递公司和部分种子数据使用 `tenant_id=10001`,而 IAM 又把 `10001` 建成普通 `MERCHANT` 演示客户。现已确认平台公共仓库、往来单位、快递公司、托盘、库位等公共资源统一归属平台技术作用域 `tenant_id=0`;必须同步新库种子、配置、消费者和可重复执行的存量迁移,客户订单、文件和费用等私有数据不得随之改为 `0`。
2. Warehouse 存量子表迁移新增 `tenant_id` 时直接默认填 `0`,却没有按父仓库或父记录回填,可能导致存量地址、能力、往来单位和快递公司丢失归属。
3. 统一迁移脚本在真正结束前已经输出 `PASS`,后面仍继续建表;成功标志和最终结构校验必须收敛到脚本末尾。
4. IAM/Auth 的部分内部 Controller 在内部令牌为空时可能把“空配置”和“缺失请求头”比较为相等,必须统一启动失败校验。
5. 平台身份只检查 `app_code=PLATFORM`,部分 Gateway/模块守卫没有再次断言登录主体 `tenant_id=0`;客户身份也应断言 `tenant_id>0`。
6. 平台代客业务审计当前可能记录平台主体 `tenant_id=0`,导致按目标客户查询审计日志漏记;应同时保留操作者作用域和目标客户归属。
7. Integration 内部令牌存在可预测默认值,必须改为环境显式注入并保持启动失败保护。
8. 模块级 `AGENTS.md`、README、分期文档和 OpenAPI 仍把兼容 `tenant_id` 描述成真实上级租户,国内货柜履约存在重新按三级租户开发的返工风险。
## P2 最小加固
- 删除或拒绝 Gateway 未分端域的 `/api/iam/**` 通用路由。
- Auth 校验 IAM 授权快照回显的 `userId/tenantId/membershipId/appCode` 与请求完全一致。
- IAM 商户资料读取和修改再次限定 `tenant_type=MERCHANT`。
- Order/Firstleg/Warehouse/File 的平台守卫统一校验平台主体为 `tenant_id=0`。
- 对少量 `updateById`、按裸主键删除、Partner 类型关联操作增加仓储层客户条件。
- Order Outbox 投递前核对事件行和 Payload 的客户、订单及聚合类型。
- Event Bridge 重复事件比较同时核对客户和信封身份字段。
- File 平台测量图片上传增加目标入库单客户归属校验,避免孤儿或错误归属文件。
- 公共 OpenAPI 不再把可信身份头描述成普通客户端请求头。
- 增加客户 A/B、异常平台 Token、内部 API 错误客户、Outbox 归属漂移和迁移结果的负向测试。
- 修正 Order 取消事件长期停留 `PENDING` 的非隔离功能问题,或明确当前不发布该事件的终态。
## 本轮不实施
- 不新增真实租户表、租户切换、租户级 RBAC 或租户级配置。
- 不批量重命名 `tenant`、`merchant`、`Tenant*`、`tenant_id`。
- 不把所有现有 `tenant_id` 统一成默认租户 ID。
- 往来单位与快递公司均由平台联系和统一维护,`wh_partner`、`wh_partner_type` 与其他公共仓储主数据一起迁移为 `0`;客户订单、文件、费用等私有数据保持客户 ID。迁移必须按明确的公共资源表和父子关系执行。
- 不触碰生产环境;测试环境已按用户明确授权执行统一增量 SQL,并完成迁移后断言。
## 测试环境迁移结果
- 统一增量 SQL 已在测试 MySQL 执行,最终输出 `migration_status = PASS`。
- `wh_partner` 4 行、`wh_partner_type` 8 行、`wh_express_company` 4 行均已归平台公共作用域 `0`,非平台作用域违规数均为 0。
- 公共仓库、地址、能力、托盘、库位、预占和占用的非平台作用域违规数均为 0。
- 订单、文件和费用等客户私有表的 `tenant_id = 0` 违规数均为 0。
## 验证结果
- `mvn test`:19 个 Reactor 模块全部 `SUCCESS`,共执行 634 项测试,0 失败、0 错误、1 项跳过。
- 重点业务模块:IAM 128 项、Order 67 项、Firstleg 112 项、Warehouse 102 项、File 81 项均通过。
- 其余服务:Print 35 项(1 项跳过)、Audit 15 项、Integration 11 项、Event Bridge 10 项均通过。
- `mvn -DskipTests validate` 与 `git diff --check` 均通过。
## 第二轮文件所有权
- 身份安全:`iam/`、`auth/`、`gateway/`、`common-security/` 的生产代码与测试。
- 订单履约:`order/`、`firstleg/` 的生产代码与测试,不修改 SQL、OpenAPI、README、AGENTS。
- 公共审计事件:`common-audit/`、`audit-service/`、`integration-service/`、`event-bridge-service/`、`common-openapi/` 的生产代码与测试。
- Warehouse/File/迁移:`warehouse/`、`file/` 生产代码与测试,以及各模块数据库脚本、`deploy/sql/`、`config/nacos/`;平台公共资源(含往来单位、快递公司)作用域迁移为 `0`,客户私有资源保持客户 ID。
- 文档契约:模块 `AGENTS.md`、README、OpenAPI 和订单与客户/入库测量与计费/国内货柜履约指导性文档;不修改 Java 或 SQL。
跨模块新接口、公共 DTO、事件结构和公共仓库作用域变更由主对话统一裁决,单个修改对话不得自行扩展范围。