Files
baiyue-firstleg/docs/two-repository-split.md
T

401 lines
19 KiB
Markdown
Raw Normal View History

2026-07-30 18:01:36 +08:00
# 头程与尾程双仓拆分审核方案
## 一、拆分结论
项目拆分为两个完全独立的 Git 仓库:
- 头程仓负责国内业务、统一登录、租户、用户、角色、菜单、按钮权限、订单主数据和头程履约。
- 尾程仓负责海外尾程履约以及海外本地仓储、文件、打印、审计、外部渠道适配。
- 登录和权限数据只有头程仓可以写入,尾程仓不得包含 `auth`、`iam`、`order`、`firstleg` 源码。
- 两仓不得通过源码依赖、跨库查询或跨区域 Feign 调用协作,只能通过版本化事件契约交换业务事实。
- 公共组件由头程仓维护并发布到 Maven 私有仓库,尾程仓只引用明确版本的制品。
当前目录是待审核的拆分暂存稿,审核通过后再分别落到正式仓库目录并初始化独立 Git 仓库。
## 二、拆分后的目录树
```text
baiyue-firstleg
├─ pom.xml
├─ platform-bom
├─ common-core
├─ common-web
├─ common-security
├─ common-openapi
├─ common-audit
├─ common-event-contract
├─ gateway
├─ auth
├─ iam
├─ order
├─ firstleg
├─ warehouse
├─ file
├─ print
├─ audit-service
├─ integration-service
├─ event-bridge-service
├─ config
│ └─ nacos
│ └─ cn
├─ docs
├─ scripts
└─ docker-compose-infra.yml
baiyue-lastleg
├─ pom.xml
├─ gateway
├─ lastleg
├─ warehouse
├─ file
├─ print
├─ audit-service
├─ integration-service
├─ event-bridge-service
├─ config
│ └─ nacos
├─ docs
├─ scripts
└─ env.example
```
## 三、模块归属和职责
### 3.1 头程仓
| 模块 | 职责 | 数据归属 |
|---|---|---|
| `gateway` | 国内统一入口、鉴权、路由和接口文档聚合 | 不保存业务数据 |
| `auth` | 统一登录、令牌签发、刷新、注销和登录会话 | 国内认证库和国内 Redis |
| `iam` | 租户、用户、成员、角色、菜单、按钮权限和数据范围 | 国内权限库 |
| `order` | 订单主数据、状态编排和跨区订单事实发布 | 国内订单库 |
| `firstleg` | 揽收、入仓、装载、发运和跨区交接 | 国内头程库 |
| `warehouse` | 国内仓库、库位和出入库能力 | 国内仓储库 |
| `file` | 国内文件元数据和对象存储适配 | 国内文件库和国内对象存储 |
| `print` | 国内标签、单据和打印任务 | 国内打印库 |
| `audit-service` | 国内审计记录 | 国内审计库 |
| `integration-service` | 国内外部渠道适配 | 配置和必要的本地状态 |
| `event-bridge-service` | 国内跨区事件发送、接收、重试和幂等 | 国内事件桥库 |
| `common-*` | 公共基础能力 | 发布为 Maven 制品 |
| `common-event-contract` | 跨区事件信封、事件类型和校验规则 | 发布为 Maven 制品 |
| `platform-bom` | 统一公共制品版本 | 发布为 Maven 物料清单 |
### 3.2 尾程仓
| 模块 | 职责 | 数据归属 |
|---|---|---|
| `gateway` | 海外统一入口、本地验签、路由和访问控制 | 不保存业务数据 |
| `lastleg` | 到港、清关、拆柜、海外仓入库、派送和签收 | 海外尾程库 |
| `warehouse` | 海外仓库、库位和出入库作业 | 海外仓储库 |
| `file` | 海外业务文件、面单和签收证明 | 海外文件库和海外对象存储 |
| `print` | 海外标签、面单和打印任务 | 海外打印库 |
| `audit-service` | 海外本地操作审计 | 海外审计库 |
| `integration-service` | 海外仓、承运商、清关和平台渠道适配 | 配置和必要的本地状态 |
| `event-bridge-service` | 海外跨区事件接收、发送、重试和幂等 | 海外事件桥库 |
尾程仓明确禁止出现以下源码目录和服务制品依赖:
```text
auth
iam
order
firstleg
common-core
common-web
common-security
common-openapi
common-audit
common-event-contract
```
其中公共组件不是禁止使用,而是禁止复制源码;尾程仓必须通过 Maven 私有仓库引用。
## 四、登录和权限边界
1. 账号、密码、租户、用户、角色、菜单、按钮权限和数据范围只允许由头程仓的 `auth` 与 `iam` 写入。
2. 用户通过国内统一入口登录,由 `auth` 使用非对称算法签发短时效令牌。
3. 海外网关只缓存公开密钥并在本地验签,不保存签名私钥,不跨区读取国内 Redis 登录会话。
4. 令牌携带用户、租户、应用端、权限快照版本和必要的授权声明;海外服务仍需校验租户边界。
5. 用户停用、租户冻结、权限版本变化和高风险封禁通过事件同步为海外本地投影。
6. 正式迁往海外前,公共安全组件必须完成公开密钥验签和本地权限投影校验改造;当前基于共享密钥和 Redis 会话的实现不能直接作为跨区域生产方案。
## 五、公共制品发布清单
头程仓发布以下公共制品,尾程仓只消费,不得再次发布同一坐标:
| 制品坐标 | 类型 | 用途 |
|---|---|---|
| `com.baiyue.shared:baiyue-platform-bom:1.0.0-SNAPSHOT` | `pom` | 统一公共组件版本 |
| `com.baiyue.shared:baiyue-common-core:1.0.0-SNAPSHOT` | `jar` | 返回结构、异常、基础实体和数据库公共配置 |
| `com.baiyue.shared:baiyue-common-web:1.0.0-SNAPSHOT` | `jar` | 统一异常、链路标识和网络层公共能力 |
| `com.baiyue.shared:baiyue-common-security:1.0.0-SNAPSHOT` | `jar` | 认证信息解析和接口权限校验 |
| `com.baiyue.shared:baiyue-common-openapi:1.0.0-SNAPSHOT` | `jar` | 接口文档公共配置 |
| `com.baiyue.shared:baiyue-common-audit:1.0.0-SNAPSHOT` | `jar` | 业务审计切面和审计发送能力 |
| `com.baiyue.shared:common-event-contract:1.0.0-SNAPSHOT` | `jar` | 跨区事件信封、类型、摘要和校验规则 |
两个聚合父工程使用不同坐标:
```text
com.baiyue.firstleg:baiyue-firstleg-platform:1.0.0-SNAPSHOT
com.baiyue.lastleg:baiyue-lastleg-platform:1.0.0-SNAPSHOT
```
正式环境不得长期引用快照版本。审核和联调阶段可以使用快照版本,上线时应发布不可覆盖的正式版本,例如 `1.0.0`,并保留制品校验值和变更记录。
## 六、构建和发布顺序
### 6.1 本地构建
第一次构建或公共版本发生变化时,必须先构建头程仓:
```powershell
cd D:\baiyue-firstleg
mvn clean install
```
确认公共制品已经安装到本地 Maven 仓库后,再构建尾程仓:
```powershell
cd D:\baiyue-lastleg
.\scripts\check-boundary.ps1
mvn clean verify
```
### 6.2 私有仓库发布
用于团队开发、流水线或服务器构建时,头程仓先发布公共制品:
```powershell
cd D:\baiyue-firstleg
mvn clean deploy
```
尾程流水线确认指定的 `baiyue.shared.version` 已经存在且校验通过,然后执行自身构建。尾程仓不得通过相对路径访问头程仓,也不得依赖开发人员本地残留的公共源码。
### 6.3 正确的拓扑顺序
```text
头程父工程
→ 公共核心
→ 公共网络层
→ 公共安全
→ 公共接口文档
→ 公共审计
→ 公共事件契约
→ 公共版本清单发布
→ 头程业务服务构建
→ 尾程边界检查
→ 尾程业务服务构建
```
## 七、跨仓业务协作
### 7.1 强制规则
- 跨仓只传递业务事件,不共享源码模型。
- 不通过公网 Feign 直接调用对方内部服务。
- 不跨区域查询对方数据库、Redis、Nacos 或对象存储。
- 事件发送采用本地事务与发件箱,接收采用收件箱幂等。
- 同一事件重复到达只能产生一次业务效果。
- 失败事件必须支持指数退避、死信、告警和人工补投。
### 7.2 推荐事件链路
```text
业务服务本地事务
→ 本地发件箱
→ 本区域事件桥
→ 加密的跨区传输
→ 对方区域事件桥
→ 本地收件箱去重
→ 本地业务消费者
→ 本地投影或状态机更新
```
### 7.3 首批事件
| 方向 | 事件 | 用途 |
|---|---|---|
| 国内到海外 | 订单已创建 | 建立尾程订单投影 |
| 国内到海外 | 订单已取消 | 阻止未开始的尾程履约 |
| 国内到海外 | 头程已交接 | 建立尾程接货任务 |
| 国内到海外 | 货物已发运 | 提供预计到港和装载信息 |
| 国内到海外 | 权限版本已变化 | 刷新海外授权投影 |
| 国内到海外 | 租户已冻结 | 海外本地立即拒绝访问 |
| 海外到国内 | 尾程已接货 | 更新国内订单轨迹 |
| 海外到国内 | 已到港或已清关 | 更新节点并触发通知 |
| 海外到国内 | 已派送 | 更新订单状态和客户通知 |
| 海外到国内 | 已签收 | 完成尾程并回传签收证明引用 |
| 海外到国内 | 尾程异常 | 触发国内客服和订单异常流程 |
文件二进制不放入事件,只传文件标识、校验值、区域和受控下载引用。
## 八、数据库、Nacos 和 Redis 边界
### 8.1 数据库
- 每个微服务拥有独立数据库账号和独立逻辑库。
- 国内数据库只允许国内服务网络访问,海外数据库只允许海外服务网络访问。
- 同名逻辑库也必须部署在不同实例或不同区域资源中,不能把同一个 MySQL 实例暴露给两区。
- 服务之间不建立跨库外键,不使用跨库联表,不复制对方业务表。
- 跨区所需数据建立最小化本地投影,并记录来源事件、聚合版本和最后更新时间。
- 订单主数据归国内,尾程状态主数据归海外;国内只保存用于查询和通知的尾程轨迹投影。
### 8.2 Nacos
```text
国内命名空间:prod-cn
海外命名空间:prod-overseas
```
- 两区使用独立 Nacos 集群、独立地址和独立凭据。
- 服务发现仅在本区域内生效。
- 配置项可以使用相同的数据标识,但配置内容、密钥和资源地址必须按区域隔离。
- 网关关闭自动服务路由,只开放区域清单中明确声明的服务。
### 8.3 Redis
- 国内 Redis 保存国内登录会话、限流和国内业务缓存。
- 海外 Redis 只保存海外缓存、幂等辅助状态和本地权限投影,不保存或远程读取国内登录会话。
- 两区 Redis 不做公网主从复制,不复用密码和数据库编号作为隔离手段。
- 需要跨区同步的冻结或撤销事实通过事件传递,并在海外形成可过期的本地拒绝投影。
## 九、持续集成和发布流程
### 9.1 头程仓流水线
1. 检查仓库边界、敏感信息和禁止文件。
2. 校验全部 POM、代码格式、单元测试和契约测试。
3. 构建公共制品和头程业务服务。
4. 公共组件变更时先发布候选版本到 Maven 私有仓库。
5. 使用候选公共版本触发尾程兼容流水线。
6. 两仓都通过后,将公共候选版本提升为不可覆盖的正式版本。
7. 构建带提交号和版本号的国内服务镜像。
8. 部署国内测试环境,完成数据库迁移、健康检查和一期验收。
9. 通过审批后灰度发布国内生产环境。
### 9.2 尾程仓流水线
1. 执行仓库边界脚本,禁止头程业务源码和公共组件源码进入仓库。
2. 从私有仓库解析锁定的公共版本,不使用动态版本范围。
3. 在干净 Maven 缓存中执行编译、单元测试、契约测试和集成测试。
4. 校验海外配置中不存在国内数据库、Redis、Nacos 和内部服务地址。
5. 构建带提交号、尾程版本和公共组件版本标签的镜像。
6. 部署海外测试环境并执行事件往返、幂等、重试和断网恢复测试。
7. 通过审批后按租户或新订单灰度,不迁移在途订单的写入归属。
公共制品发布失败或尾程兼容流水线失败时,禁止头程公共版本进入正式仓库。
## 十、版本兼容规则
1. 公共制品和事件契约使用语义化版本。
2. 补丁版本只允许缺陷修复;次版本允许向后兼容的字段和能力增加;主版本用于不兼容变更。
3. 事件必须携带事件类型、事件标识、契约版本、生产区域、目标区域、聚合标识、聚合版本、时间和负载摘要。
4. 新增字段必须可选或具有默认语义,消费者必须忽略不认识的附加字段。
5. 不允许在同一主版本中删除字段、改变字段含义或复用旧事件类型表达新语义。
6. 生产者至少兼容当前和上一版消费者;消费者至少支持当前和上一版事件契约。
7. 公共版本升级必须同时通过头程与尾程测试,尾程仓在自己的父 POM 中明确锁定版本。
8. 每个服务镜像记录业务版本、公共制品版本、契约版本和源代码提交号,便于回滚和审计。
## 十一、迁移步骤
1. 审核并冻结本方案中的模块归属、数据主权和首批事件清单。
2. 在原仓库冻结结构性新增,只允许必要缺陷修复,避免拆分期间双向漂移。
3. 完成暂存仓的中文乱码检查、父 POM、模块坐标和区域配置校验。
4. 建立 Maven 私有仓库的正式版、候选版和快照版发布策略。
5. 先发布头程公共物料清单、公共组件和事件契约。
6. 在干净环境构建尾程仓,证明其不依赖原单体目录和本地源码。
7. 分别创建 `D:\baiyue-firstleg` 与 `D:\baiyue-lastleg`,各自初始化独立 Git 仓库和远程仓库。
8. 先在国内部署头程仓全部一期服务,尾程一期仍可在国内独立环境运行,但使用尾程仓代码和独立资源。
9. 完成发件箱、事件桥、收件箱、业务消费者和轨迹通知闭环。
10. 事件链路先影子运行,对比原链路结果,不立即切换业务主写。
11. 海外基础设施准备完成后,仅将新创建、未履约的尾程聚合灰度到海外。
12. 已在途订单保持原区域完成,不在履约过程中迁移数据库写入权。
13. 灰度稳定后扩大流量,保留事件回放、数据核对和版本回滚能力。
14. 双仓稳定运行并完成审计后,再归档原 `D:\baiyue`,不得提前删除。
## 十二、验收清单
### 12.1 仓库和构建
- [ ] 两个目录分别存在且各自只有一个独立 `.git`。
- [ ] 尾程仓不存在 `auth`、`iam`、`order`、`firstleg` 和公共组件源码目录。
- [ ] 两个聚合父工程及重复区域服务不存在相同可发布坐标冲突。
- [ ] 头程仓可执行 `mvn clean verify`。
- [ ] 头程公共制品可执行 `mvn deploy` 并从私有仓库重新下载。
- [ ] 清空本地相关制品后,尾程仓仍可独立执行 `mvn clean verify`。
- [ ] 两仓均未提交 `target`、密钥、密码、日志和开发工具缓存。
### 12.2 登录权限
- [ ] 登录、租户、用户、角色、菜单、按钮权限只有国内写入口。
- [ ] 海外网关使用公开密钥本地验签,不保存国内签名私钥。
- [ ] 海外服务不连接国内 Redis 会话。
- [ ] 租户冻结、用户停用和权限版本变化可在规定时间内同步到海外。
- [ ] 平台端与商户端权限、按钮权限和租户数据边界均有自动化测试。
### 12.3 跨区事件
- [ ] 订单、头程交接、尾程节点和异常事件均有明确契约版本。
- [ ] 发件箱与业务写入属于同一本地事务。
- [ ] 收件箱按事件标识幂等,重复事件不重复推进状态。
- [ ] 乱序、延迟、重复、摘要冲突和非法目标区域均有测试。
- [ ] 断网恢复、指数退避、死信告警和人工补投可用。
- [ ] 跨区链路启用传输加密、双向认证或等效的服务身份校验。
- [ ] 两仓不存在跨区 Feign 地址和对方内部数据库连接。
### 12.4 数据和基础设施
- [ ] 国内与海外 MySQL、Redis、Nacos、消息系统和对象存储物理隔离。
- [ ] 每个服务使用独立数据库账号且权限最小化。
- [ ] 没有跨库查询、跨库外键和公网数据库访问。
- [ ] 国内与海外网关仅暴露本区域允许的路由。
- [ ] 备份、恢复、数据保留、审计和敏感信息脱敏策略按区域验证。
### 12.5 发布迁移
- [ ] 镜像可追溯到代码提交、业务版本、公共版本和契约版本。
- [ ] 数据库脚本支持升级校验和回滚预案。
- [ ] 新订单灰度、在途订单保持原区域和失败回切规则已演练。
- [ ] 国内订单轨迹与海外尾程事实完成自动核对。
- [ ] 原仓库只在双仓稳定验收后归档,归档前保留只读备份。
## 十三、当前完成情况
### 13.1 已完成
- 已在可写暂存目录形成头程和尾程两个独立 Maven 聚合工程草案。
- 已将 `auth`、`iam`、`order`、`firstleg` 和全部公共组件源码仅放入头程草案。
- 已确认尾程草案不包含上述头程业务源码目录和编译期业务包引用。
- 已为两个父工程使用不同的组织坐标,降低聚合制品冲突风险。
- 已建立公共物料清单,尾程通过 `com.baiyue.shared` 公共制品引用公共能力。
- 已按国内和海外分别整理 Gateway 与 Nacos 配置草案。
- 已为尾程草案提供仓库边界检查脚本和构建脚本。
- 已从尾程文件服务草案中移除同步调用国内权限服务的资格上传链路。
- 已保留跨区事件桥和公共事件契约骨架。
### 13.2 待完成
- 待用户审核本方案后,才创建两个正式 Git 仓库;当前暂存目录不是最终交付仓库。
- 待修复暂存文件中已有的中文编码显示问题,并统一以无字节顺序标记的 UTF-8 保存。
- 待配置 Maven 私有仓库地址、凭据、发布权限和不可覆盖的正式版本策略。
- 待检查并消除两个仓中重复区域服务的最终发布坐标冲突。
- 待将公共安全组件从共享密钥与国内 Redis 会话校验改造为公开密钥验签和海外本地授权投影。
- 待实现真实的发件箱扫描、跨区发送、收件箱消费、重试、死信和人工补投。
- 待为订单、头程、尾程、权限冻结和轨迹通知接入真实事件生产者与消费者。
- 待补齐尾程业务表、仓储作业、文件对象存储、打印和渠道适配的实际业务能力。
- 待在干净 Maven 仓库中验证“头程发布公共制品后,尾程完全独立构建”。
- 待执行两仓全部单元测试、契约测试、集成测试、安全测试和区域故障演练。
- 待初始化独立 Git 历史、远程仓库保护规则和双仓持续集成流水线。
## 十四、审核决策点
本次审核需要确认以下内容:
1. 登录、租户、用户、角色、菜单和按钮权限永久归头程仓唯一写入。
2. 订单主数据归头程,尾程只维护事件投影和尾程状态主数据。
3. 公共组件由头程仓发布,尾程不复制公共源码。
4. 两仓跨区只使用事件,不开放跨区内部 Feign 和数据库访问。
5. 一期先在国内完成独立双仓部署验证,后期只迁移新尾程聚合到海外。
6. 当前 `D:\baiyue` 保留为拆分来源和回滚备份,双仓验收前不删除。