69 lines
5.6 KiB
Markdown
69 lines
5.6 KiB
Markdown
# 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、事件结构和公共仓库作用域变更由主对话统一裁决,单个修改对话不得自行扩展范围。
|