Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
407abd634c | ||
|
|
606abeb2c6 | ||
|
|
16ecfae84d | ||
|
|
19943112c0 |
@@ -1,6 +1,9 @@
|
|||||||
# 虫虫出海文档索引
|
# 虫虫出海文档索引
|
||||||
|
|
||||||
项目交付文档按业务域组织。当前开发环境以端到端全流程为统一范围;历史规划、确认和验收记录保留在对应业务域目录,仅用于追溯决策,不构成功能边界。
|
项目交付文档按业务域组织。当前只有测试环境,以端到端全流程为统一范围;历史规划、确认和验收记录保留在对应业务域目录,仅用于追溯决策,不构成功能边界。
|
||||||
|
|
||||||
|
- [测试环境单机部署与配置契约](测试环境单机部署与配置契约.md):唯一环境、部署配置、整体切换与验收。
|
||||||
|
- [统一认证与服务通信契约](统一认证与服务通信契约.md):统一入口、权限撤销、逐事件投递与幂等。
|
||||||
|
|
||||||
## 业务域文档
|
## 业务域文档
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
本文件按需检索,不作为启动必读文档。以下路径均按工作区根目录或表内注明的应用源码根目录起算,不相对于 docs/。
|
本文件按需检索,不作为启动必读文档。以下路径均按工作区根目录或表内注明的应用源码根目录起算,不相对于 docs/。
|
||||||
|
|
||||||
|
架构/环境/部署查[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md);网关/Token/会话撤销/事件通信查[统一认证与服务通信契约](统一认证与服务通信契约.md)。下文旧区域服务路径用于定位现有实现,目标规则以这两份主契约为准。
|
||||||
|
|
||||||
## 常用说法与歧义分流
|
## 常用说法与歧义分流
|
||||||
|
|
||||||
仓储转运审核、转运驳回:Admin 尾程订单 `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue` → `apps/admin-web/src/modules/overseas-warehouse/components/WarehouseTransferReviewDialog.vue`;权限、状态及 API 见该模块 `AGENTS.md` 的“仓储转运审核、通过与驳回”。不要把该入口当作头程订单审单,也不要按“转运”误入排车转派送。
|
仓储转运审核、转运驳回:Admin 尾程订单 `apps/admin-web/src/modules/overseas-warehouse/pages/LastMileOrdersView.vue` → `apps/admin-web/src/modules/overseas-warehouse/components/WarehouseTransferReviewDialog.vue`;权限、状态及 API 见该模块 `AGENTS.md` 的“仓储转运审核、通过与驳回”。不要把该入口当作头程订单审单,也不要按“转运”误入排车转派送。
|
||||||
|
|||||||
+3
-164
@@ -1,166 +1,5 @@
|
|||||||
# 双区域部署与 Nacos 规划
|
# 双区域部署与 Nacos 规划(已替代)
|
||||||
|
|
||||||
## 1. 适用范围与结论
|
自 2026-09-29 起,不再规划开发/测试/生产与 CN/OVERSEAS 双区域。当前唯一目标为单一测试环境、所有服务同机部署。唯一部署主契约见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md),认证通信见[统一认证与服务通信契约](统一认证与服务通信契约.md)。
|
||||||
|
|
||||||
本文冻结国内头程与海外仓服务在开发、测试和生产环境中的部署拓扑、Nacos、数据库及 Event Bridge 边界。账号、Token、API 路由和事件语义继续以《跨区域认证与服务通信契约》为准。
|
此文件仅保留旧链接入口,不再定义有效规则。运行配置切换仍待实施与验证。
|
||||||
|
|
||||||
当前结论:
|
|
||||||
|
|
||||||
- 开发、测试采用单宿主机共置:同一环境内同时部署国内 Compose 与海外 Compose,通过独立容器、网络、端口、Nacos Namespace 和数据库 Schema 隔离。
|
|
||||||
- 生产采用国内、海外两套独立区域控制面:各自使用本区域 Nacos 集群、数据库和 Redis,不允许海外服务跨境依赖国内 Nacos、MySQL 或 Redis。
|
|
||||||
- 跨区域只开放双区域 API、JWKS 公钥和 Event Bridge 接收入口,不使用跨区域服务发现。
|
|
||||||
|
|
||||||
## 2. 环境拓扑
|
|
||||||
|
|
||||||
| 环境 | 宿主与网络 | Nacos | 数据库 | 适用目的 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| development | 单宿主机共置国内/海外 Compose | 一套开发 Nacos,国内/海外独立 Namespace | 可共用一个开发 MySQL 实例,但必须使用独立 Schema | 日常开发联调 |
|
|
||||||
| test | 单宿主机共置国内/海外 Compose | 一套测试 Nacos,国内/海外独立 Namespace | 可共用一个测试 MySQL 实例,但必须使用独立 Schema | 集成测试和验收 |
|
|
||||||
| production-cn | 国内独立部署单元 | 国内高可用 Nacos 集群 | 国内独立 MySQL/Redis | Auth、IAM、头程、国内仓和 Finance |
|
|
||||||
| production-overseas | 海外独立部署单元 | 海外高可用 Nacos 集群 | 海外独立 MySQL/Redis | 海外 Gateway、Lastleg 和海外 Warehouse |
|
|
||||||
|
|
||||||
如果开发与测试实际共用同一套 Nacos 实例,必须创建四个 Namespace,不得复用:
|
|
||||||
|
|
||||||
```text
|
|
||||||
development-cn
|
|
||||||
development-overseas
|
|
||||||
test-cn
|
|
||||||
test-overseas
|
|
||||||
```
|
|
||||||
|
|
||||||
Namespace 名称不是服务名。环境变量必须填写 Nacos 实际 Namespace ID;控制台自动生成 UUID 时使用 UUID,不使用展示名称代替。
|
|
||||||
|
|
||||||
## 3. 服务归属
|
|
||||||
|
|
||||||
### 3.1 国内区域
|
|
||||||
|
|
||||||
- `gateway`、`auth-service`、`iam-service`
|
|
||||||
- `firstleg-service`、`order-service`、`finance-service`
|
|
||||||
- 国内 `warehouse-service`、`file-service`、`audit-service` 等公共服务
|
|
||||||
- 国内 Event Bridge,用于接收目标区域为 `CN` 的事件并投递本地 Firstleg
|
|
||||||
|
|
||||||
### 3.2 海外区域
|
|
||||||
|
|
||||||
- `gateway-overseas`
|
|
||||||
- `lastleg-service`,同时持有 `baiyue_lastleg` 内的 IAM 安全事件 Inbox/投影,并开放内部事件接收和实时校验端点
|
|
||||||
- `warehouse-overseas-service`
|
|
||||||
- 海外 `file-service`,独占海外 RDS 中的 `baiyue_file`,只访问海外本区域私有 OSS Bucket;详细边界见《[阿里云 OSS 文件中心接入设计与评审](阿里云OSS文件中心接入设计与评审.md)》
|
|
||||||
- 海外 Event Bridge,用于接收目标区域为 `OVERSEAS` 的事件;业务事件和三类 IAM 安全事件按事件类型投递 Lastleg 的不同内部入口
|
|
||||||
|
|
||||||
海外浏览器请求直接进入海外 Gateway,不经过国内 Gateway。Auth 仍只部署在国内;海外服务通过受控 JWKS 地址验证 Auth 签发的短时海外 Token,不访问国内 Redis。
|
|
||||||
|
|
||||||
## 4. Nacos 规划
|
|
||||||
|
|
||||||
### 4.1 开发与测试
|
|
||||||
|
|
||||||
非生产环境允许一套 Nacos 实例承载多个 Namespace。国内配置发布自 `baiyue-firstleg/config/nacos/cn/`,海外配置发布自 `baiyue-firstleg/config/nacos/overseas/`,相同 Data ID 依靠 Namespace 隔离。
|
|
||||||
|
|
||||||
国内环境变量:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
NACOS_SERVER_ADDR=<当前环境Nacos地址>
|
|
||||||
NACOS_NAMESPACE=<当前环境国内Namespace ID>
|
|
||||||
REGION_CODE=CN
|
|
||||||
DEPLOYMENT_CELL=<environment>-cn
|
|
||||||
DATA_RESIDENCY=CN
|
|
||||||
```
|
|
||||||
|
|
||||||
海外环境变量:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
OVERSEAS_NACOS_SERVER_ADDR=<当前环境Nacos地址>
|
|
||||||
OVERSEAS_NACOS_NAMESPACE=<当前环境海外Namespace ID>
|
|
||||||
OVERSEAS_DEPLOYMENT_CELL=<environment>-overseas
|
|
||||||
```
|
|
||||||
|
|
||||||
海外 Compose 必须强制传入 `REGION_CODE=OVERSEAS` 和 `DATA_RESIDENCY=OVERSEAS`,不得继承共享文件中的国内默认值。
|
|
||||||
|
|
||||||
### 4.2 生产
|
|
||||||
|
|
||||||
生产国内、海外分别部署本区域 Nacos 集群。服务只注册到本区域,不同步或复制临时服务注册表,也不通过公网访问另一地区 Nacos。
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
# 国内生产凭据
|
|
||||||
NACOS_SERVER_ADDR=<国内Nacos内网地址>
|
|
||||||
NACOS_NAMESPACE=<production-cn Namespace ID>
|
|
||||||
|
|
||||||
# 海外生产凭据
|
|
||||||
OVERSEAS_NACOS_SERVER_ADDR=<海外Nacos内网地址>
|
|
||||||
OVERSEAS_NACOS_NAMESPACE=<production-overseas Namespace ID>
|
|
||||||
```
|
|
||||||
|
|
||||||
生产 Nacos 必须启用认证、网络 ACL 和持久化;不暴露公网管理端口。数据库密码、JWT 私钥、内部服务 Token 和第三方密钥不得写入 Nacos 明文,继续由 Jenkins Credentials 或生产密钥管理系统注入。
|
|
||||||
|
|
||||||
## 5. 数据库隔离
|
|
||||||
|
|
||||||
开发、测试即使共用一个 MySQL 实例,也必须保持以下 Schema 独立:
|
|
||||||
|
|
||||||
| 区域 | 服务 | Schema |
|
|
||||||
|---|---|---|
|
|
||||||
| 国内 | Event Bridge | `baiyue_event_bridge` |
|
|
||||||
| 海外 | Event Bridge | `baiyue_event_bridge_overseas` |
|
|
||||||
| 海外 | Lastleg | `baiyue_lastleg` |
|
|
||||||
| 海外 | Warehouse | `baiyue_lastlag_warehouse` |
|
|
||||||
|
|
||||||
生产必须进一步使用区域内独立数据库实例或集群。国内服务不得查询海外 Schema,海外服务不得查询国内 Schema;跨区域事实只通过版本化事件或已确认的受保护内部接口传递。
|
|
||||||
|
|
||||||
## 6. Event Bridge 双实例
|
|
||||||
|
|
||||||
每个区域部署一个相同制品、独立数据库的 Event Bridge:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Firstleg Outbox
|
|
||||||
-> 海外 Event Bridge Inbox
|
|
||||||
-> Lastleg 本地消费者
|
|
||||||
|
|
||||||
Lastleg Outbox
|
|
||||||
-> 国内 Event Bridge Inbox
|
|
||||||
-> Firstleg 本地消费者
|
|
||||||
```
|
|
||||||
|
|
||||||
国内 Firstleg 配置海外 Bridge 基础地址,Feign 自动追加接收路径:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
LASTLEG_EVENT_BRIDGE_URL=<海外Event Bridge基础地址>
|
|
||||||
```
|
|
||||||
|
|
||||||
海外 Lastleg 配置国内 Bridge 基础地址:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
FIRSTLEG_EVENT_BRIDGE_URL=<国内Event Bridge基础地址>
|
|
||||||
```
|
|
||||||
|
|
||||||
区域内消费者使用本地服务地址:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
# 海外 Bridge
|
|
||||||
EVENT_CONSUMER_URL=http://lastleg-service:9303/internal/lastleg/events
|
|
||||||
|
|
||||||
# 国内 Bridge
|
|
||||||
FIRSTLEG_CONTAINER_EVENT_CONSUMER_URL=http://firstleg:9202/internal/firstleg/v1/container-events
|
|
||||||
```
|
|
||||||
|
|
||||||
跨区域 Bridge 接收入口使用 TLS、内部服务身份、网络白名单和幂等校验;不得暴露数据库或消费者内部接口。
|
|
||||||
|
|
||||||
## 7. Jenkins 与环境文件
|
|
||||||
|
|
||||||
开发、测试可以各用一份 Secret File,同时包含国内和海外非敏感路由变量;Compose 负责选择本区域变量。生产必须拆分凭据:
|
|
||||||
|
|
||||||
```text
|
|
||||||
firstleg-production-cn-env
|
|
||||||
firstleg-production-overseas-env
|
|
||||||
```
|
|
||||||
|
|
||||||
生产海外部署不得读取国内数据库、Redis 或 Nacos 地址。Event Bridge 同一制品需要按 `CN`、`OVERSEAS` 两个部署单元分别发布,使用不同 Compose Project、容器名、端口和数据库。
|
|
||||||
|
|
||||||
## 8. 当前仓库实施差距
|
|
||||||
|
|
||||||
目标架构已冻结,但当前部署代码仍需完成以下收敛:
|
|
||||||
|
|
||||||
1. `docker-compose.overseas.yml` 当前仍从 `NACOS_SERVER_ADDR` 取值,应改为显式使用 `OVERSEAS_NACOS_SERVER_ADDR`。
|
|
||||||
2. `deploy/scripts/deploy-built-service.sh` 与 `deploy-services.sh` 的海外服务门禁应校验 `OVERSEAS_NACOS_SERVER_ADDR`。
|
|
||||||
3. Jenkins 生产配置需要拆分国内/海外 Secret File,并为 Event Bridge 提供明确区域部署参数或独立 Job。
|
|
||||||
4. 海外 Nacos Namespace 创建、配置发布、JWKS 可达性和双向 Event Bridge 真实投递必须分别验收,不能以容器健康检查代替。
|
|
||||||
5. 海外 Gateway 和 Nacos 已存在 File Service 入口,但海外统一 SQL 与部署清单尚未包含海外 `file-service`、`baiyue_file`;OSS 接入实施前必须补齐并完成区域内真实上传、下载和双实例读取验收。
|
|
||||||
|
|
||||||
这些差距未完成前,不得声称生产双区域部署已就绪。
|
|
||||||
|
|||||||
+32
-17
@@ -1,6 +1,6 @@
|
|||||||
# 报关资料与船期价格接入梳理
|
# 报关资料与船期价格接入梳理
|
||||||
|
|
||||||
> **当前用途:报关与船期价格专题参考。** 报关流程已经确认,代码已进入第一批开发;开发交接看[报关代码开发交接清单](../头程到尾程/报关代码开发交接清单.md)。主流程和节点关系以[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准;本文保留资料字段、回执轮次、价格口径和接口查找信息。
|
> **当前用途:报关与船期价格专题参考。** 报关流程已经确认,第一批代码和页面已经接入测试环境;开发交接看[报关代码开发交接清单](../头程到尾程/报关代码开发交接清单.md)。主流程和节点关系以[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准;本文保留资料字段、回执轮次、价格口径和接口查找信息。
|
||||||
>
|
>
|
||||||
> 文中“目标、实施顺序、进入条件、待确认事项”等段落属于原评审记录。开发已经完成后,不再据此重新拆开发任务;若与当前确认不一致,以总览和最新业务确认修正对应专题段落。
|
> 文中“目标、实施顺序、进入条件、待确认事项”等段落属于原评审记录。开发已经完成后,不再据此重新拆开发任务;若与当前确认不一致,以总览和最新业务确认修正对应专题段落。
|
||||||
|
|
||||||
@@ -8,7 +8,22 @@
|
|||||||
|
|
||||||
**当前基线**:以最新用户确认和[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准。旧版需求表、README、开发规划和本文件中的历史建议若发生冲突,先在当前入口记录收尾变更,再决定是否需要修改专题细节。
|
**当前基线**:以最新用户确认和[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准。旧版需求表、README、开发规划和本文件中的历史建议若发生冲突,先在当前入口记录收尾变更,再决定是否需要修改专题细节。
|
||||||
|
|
||||||
**当前实现快照(2026-09-26)**:两份文件链路已经落到平台、客户和 Firstleg 报关接口:客户资料、报关行回执、客户整份回执确认/打回、平台发送报关行执行、真实报关完税文件分别保存并受版本门禁控制。回执发送给报关行后不可再替换;只有包含退税货物的柜才允许走发送执行接口;全买单柜仍走平台直接完成。`brokerSubmittedAt` 只表示发送执行时间,不表示报关完成。PDA 只负责产生 `LOADED` 前置事实,报关验收不创建或操作 PDA 任务;船期、甩柜和改配只修改原柜运输信息,不重置报关资料和确认结果。
|
**当前实现快照(2026-09-29)**:两份文件链路已经落到平台、客户和 Firstleg 报关接口,客户端“报关资料”和“船期价格”也已经作为独立模块接入导航和路由。客户资料、报关行回执、客户整份回执确认/打回、平台发送报关行执行、真实报关完税文件分别保存并受版本门禁控制。回执发送给报关行后不可再替换;只有包含退税货物的柜才允许走发送执行接口;全买单柜仍走平台直接完成。`brokerSubmittedAt` 只表示发送执行时间,不表示报关完成。PDA 只负责产生 `LOADED` 前置事实,报关验收不创建或操作 PDA 任务;船期、甩柜和改配只修改原柜运输信息,不重置报关资料和确认结果。
|
||||||
|
|
||||||
|
## 当前差异与下一步
|
||||||
|
|
||||||
|
当前主流程和代码的关系已经收敛:F01-F24(国内头程、报关、待发区、送港、进港、甩柜和实际开航)有最新真实 HTTP 证据;F25-F40(目的港、海外入库、库存、出库、派送和最终回写)已有综合真实 HTTP 证据和页面实现。客户端两个独立模块、订单快捷入口、平台整柜报关工作台和船期价格查询均已接入,不需要再按“新增页面”拆任务。
|
||||||
|
|
||||||
|
2026-09-29 的最新综合 F01-F40 验收报告为 `baiyue-firstleg/reports/fba-full-current-20260929.json`。报告前段业务链大量通过,但尾程和海外 PDA 产生了环境型阻断:`test-api-overseas.buggoglobal.com` 当时 DNS 不可解析,后续请求均为 `fetch failed`,因此这份报告不能作为全流程全绿结论,也不能据此判断报关或船期代码失败。此前报关专项 `customs-current-20260928.json`(543/543)和运输专项 `transport-current-20260929.json`(1036/1036)仍是当前可复用的绿色证据。
|
||||||
|
|
||||||
|
当前状态分为三类任务:
|
||||||
|
|
||||||
|
1. **规则已简化并确认**:不维护资料类型清单,也不区分逐项责任人;客户或平台只要在资料包上传文件即可。查验、扣货、补资料均由平台人工标记异常,选择预设理由;选择“其他”时填写备注即可,不要求接入短信或自动海关系统。
|
||||||
|
2. **环境/外部验收**:恢复海外测试域名解析后重新跑 F25-F40;COSCO 官方接口凭据、COSCO 动态页面和 ZIM hCaptcha 仍是外部非阻断项;Android/HBuilderX 真机扫码、弱网和在线草稿仍需现场设备验收。
|
||||||
|
3. **后续增强**:报关行接收回执/回执轮次和下载凭证仍可增强,但不影响当前两份文件闭环、客户确认、正式申报和报关完成后进入待发区。
|
||||||
|
4. **费用默认确认**:业务规则已经确认,但代码仍主要完成费用发布/客户确认;`LOADED` 时按已装范围写入 `SYSTEM_AUTO_AT_LOADED`、费用版本、柜次/入仓码和幂等审计的落地实现,仍需单独补齐,不能把 `SENT` 直接当成默认确认。
|
||||||
|
|
||||||
|
你当前不需要先操作系统或确认代码。资料上传和异常人工处理规则已经足够继续开发;其余技术修复和重新验收由开发侧继续处理。
|
||||||
|
|
||||||
## 先锁定的范围
|
## 先锁定的范围
|
||||||
|
|
||||||
@@ -21,28 +36,28 @@
|
|||||||
|
|
||||||
费用确认是并行事实,不阻断排柜、预装、PDA 或装柜。装柜完成后,对应已实装范围若客户仍未确认当前有效且已发布费用版本,系统记录“系统默认确认(装柜完成)”;不伪造客户点击,保留 `SYSTEM_AUTO_AT_LOADED` 来源、费用版本、柜次/入仓码、时间和幂等标识。没有有效费用版本时不得生成零额或伪造确认,须保留费用异常待办。
|
费用确认是并行事实,不阻断排柜、预装、PDA 或装柜。装柜完成后,对应已实装范围若客户仍未确认当前有效且已发布费用版本,系统记录“系统默认确认(装柜完成)”;不伪造客户点击,保留 `SYSTEM_AUTO_AT_LOADED` 来源、费用版本、柜次/入仓码、时间和幂等标识。没有有效费用版本时不得生成零额或伪造确认,须保留费用异常待办。
|
||||||
|
|
||||||
出仓后的实际装船、提单、舱单、结关、退税正式资料和船公司节点查询属于后续或海外仓业务事实,不作为本期国内货柜履约页面、接口和验收范围。若国内页面需要展示,只能消费已确认的跨服务只读快照,并单独定义事件、来源、更新时间和责任边界。
|
实际装船、提单、舱单、结关、退税正式资料和船公司节点查询仍属于跨服务或外部业务事实;当前国内货柜链已实现本柜船期编辑、送港、进港和实际开航节点,外部船公司自动查询以及更复杂的提单/舱单凭证继续按独立来源和只读快照接入。若国内页面需要展示,只能消费已确认的跨服务只读快照,并单独定义事件、来源、更新时间和责任边界。
|
||||||
|
|
||||||
## 入口与权威数据
|
## 入口与权威数据
|
||||||
|
|
||||||
| 入口 | 本期职责 | 权威数据 | 当前状态 |
|
| 入口 | 本期职责 | 权威数据 | 当前状态 |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 客户端“报关资料” | `LOADED` 后查看本企业资料包,上传/替换/补件,查看报关行回执并确认或打回 | Firstleg 报关协同;文件由 File 服务保存 | **目标新增独立入口** |
|
| 客户端“报关资料” | `LOADED` 后查看本企业资料包,上传/替换/补件,查看报关行回执并确认或打回 | Firstleg 报关协同;文件由 File 服务保存 | **已实现:独立入口 + 订单快捷入口** |
|
||||||
| 订单中的“上传资料” | 带订单和入仓码上下文进入同一资料包 | 与独立入口共用 packageId 和接口 | **现有快捷入口** |
|
| 订单中的“上传资料” | 带订单和入仓码上下文进入同一资料包 | 与独立入口共用 packageId 和接口 | **现有快捷入口** |
|
||||||
| 平台整柜报关工作台 | 按实际装柜清单通知报关行,管理客户资料、回执轮次、全部确认、整柜正式提交和海关结果 | Firstleg 柜级报关与提交批次 | **已有四态,需收敛新投影** |
|
| 平台整柜报关工作台 | 按实际装柜清单通知报关行,管理客户资料、回执轮次、全部确认、整柜正式提交和海关结果 | Firstleg 柜级报关、提交批次和结果事实 | **已实现:四态 + 独立正式申报/海关结果投影** |
|
||||||
| 客户端“船期价格” | 查询当前企业可见的有效渠道、参考船期、最晚进仓、参考时效和估价 | 生效价格簿及服务端估价 | **建议新增独立入口** |
|
| 客户端“船期价格” | 查询当前企业可见的有效渠道、参考船期、最晚进仓、参考时效和估价 | 生效价格簿及服务端估价 | **已实现:独立入口** |
|
||||||
| 平台“船期价格表” | 上传、解析、核对、发布公共或客户专属价格簿 | Firstleg 价格簿版本 | **已有平台能力** |
|
| 平台“船期价格表” | 上传、解析、核对、发布公共或客户专属价格簿 | Firstleg 价格簿版本 | **已有平台能力** |
|
||||||
|
|
||||||
平台端应写“按申报组整理并线下提交”。在跨客户合并规则确认前,默认禁止把不同客户放入同一正式报关单;不得在结论表中把待决规则写成既定能力。
|
平台端应写“按申报组整理并线下提交”。在跨客户合并规则确认前,默认禁止把不同客户放入同一正式报关单;不得在结论表中把待决规则写成既定能力。
|
||||||
|
|
||||||
## 当前实现事实
|
## 当前实现事实
|
||||||
|
|
||||||
1. 客户端当前通过订单接口查询报关资料,现状主要只对服务端确认已完成装柜的退税订单开放;本目标稿调整为 `LOADED` 后启动本柜报关批次,按客户/入仓码收集资料、接收报关行回执、提交客户确认并支持打回重做。资料可上传、替换、改关联、删除并保留版本;每轮发送和回执都要留痕,客户确认后才进入该客户的 `CUSTOMER_CONFIRMED`。对应接口和权限见 [customs-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/customs-v1.yaml#L48)。
|
1. 客户端现在同时提供独立“报关资料”入口和订单快捷入口,二者共用同一资料包和版本历史;仅对 `LOADED` 后的退税订单开放,按客户/入仓码收集资料、接收报关行回执、提交客户确认并支持打回重做。资料可上传、替换、改关联、删除并保留版本;每轮发送和回执都留痕,客户确认后才进入该客户的 `CUSTOMER_CONFIRMED`。对应接口和权限见 [customs-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/customs-v1.yaml#L48)。
|
||||||
2. 当前柜级状态为 WAITING_CUSTOMER_DOCUMENTS → READY_TO_START → DECLARING → COMPLETED;目标需要增加客户确认轮次、整柜正式提交、查验/放行和送港子状态。资料关联以 loadingPlanId、柜级聚合、客户报关案例和整票入仓码为根。
|
2. 当前柜级状态为 WAITING_CUSTOMER_DOCUMENTS → READY_TO_START → DECLARING → COMPLETED;客户确认轮次、首次发送批次、整柜正式提交、查验/放行和送港子状态通过独立事实和只读投影承载。资料关联以 loadingPlanId、柜级聚合、客户报关案例和整票入仓码为根。
|
||||||
3. 当前 COMPLETED 会发布报关完成事件并参与待发区门禁。契约将“客户资料确认轮次”“整柜正式提交”“海关查验/放行”分开;报关完成后才允许进入待发区,船期事实独立维护。
|
3. 当前 COMPLETED 会发布报关完成事件并参与待发区门禁。契约将“客户资料确认轮次”“整柜正式提交”“海关查验/放行”分开;报关完成后才允许进入待发区,船期事实独立维护。
|
||||||
4. 全买单柜已有独立的二次确认接口和导出契约,本期继续保留;需要补齐其在客户确认轮次、整柜正式申报、海关结果和送港/开船状态中的位置。
|
4. 全买单柜已有独立的二次确认接口和导出契约;它不创建退税客户资料、回执和确认案例,运输节点仍按装柜、待发区、送港和开船事实推进。
|
||||||
5. 客户端现有价格接口为按起运仓查询渠道,以及按指定渠道估算参考费用。/estimate 只返回基础参考费用,不含复杂附加费和最终结算调整;pricingTaxMode 不等同于订单 taxMode。见 [fba-pricing-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/fba-pricing-v1.yaml#L130)。
|
5. 客户端现有价格接口为按起运仓查询渠道,以及按指定渠道估算参考费用。/estimate 只返回基础参考费用,不含复杂附加费和最终结算调整;pricingTaxMode 不等同于订单 taxMode。见 [fba-pricing-v1.yaml](../../baiyue-firstleg/firstleg/src/main/resources/openapi/fba-pricing-v1.yaml#L130)。
|
||||||
6. 仓库内原型与页面索引仍将报关上传、回执下载和出仓前船期资料列为待原型或部分参考;页面范围需同步 [国内货柜履约页面与原型清单.md](国内货柜履约页面与原型清单.md#L30)。
|
6. 原型文档仍有“待原型/部分参考”的历史表述,但当前页面已按现行契约接入;页面范围以客户端路由、平台报关工作台和当前 OpenAPI 为准,不再把原型中的待建入口当作开发缺口。
|
||||||
|
|
||||||
7. **费用默认确认目前是目标变更,不是现有实现。** 当前装柜完成逻辑只会自动发送/发布费用,不能把 `SENT` 直接当成客户确认;现有费用锁定也主要依赖客户确认时间。实现本轮目标时必须增加确认来源和幂等审计,并改为“客户确认或装柜默认确认 + 已装柜完成后才最终锁定”。部分装载只能确认本次已装范围,余量不能被顺手确认。
|
7. **费用默认确认目前是目标变更,不是现有实现。** 当前装柜完成逻辑只会自动发送/发布费用,不能把 `SENT` 直接当成客户确认;现有费用锁定也主要依赖客户确认时间。实现本轮目标时必须增加确认来源和幂等审计,并改为“客户确认或装柜默认确认 + 已装柜完成后才最终锁定”。部分装载只能确认本次已装范围,余量不能被顺手确认。
|
||||||
|
|
||||||
@@ -63,7 +78,7 @@
|
|||||||
|
|
||||||
### 1. 客户报关案例与资料包
|
### 1. 客户报关案例与资料包
|
||||||
|
|
||||||
报关资料主流程在 `LOADED` 后启动。每个客户/入仓码在本柜建立一个 `customerCustomsCase`,再挂载稳定的 `packageId` 和文件版本。案例至少记录:订单/子订单、入仓码或入仓明细、实际装箱数展示、资料清单版本、每个清单项的文件版本、报关行发送时间、回执文件版本、客户确认/打回人和时间、打回原因、当前 `roundNo`、客户可见范围和审计记录。
|
报关资料主流程在 `LOADED` 后启动。每个客户/入仓码在本柜建立一个 `customerCustomsCase`,再挂载稳定的 `packageId` 和文件版本。首期不定义文件类型清单和逐项责任人;资料包只需支持文件上传、替换、版本、报关行发送时间、回执文件版本、客户确认/打回人和时间、打回原因、当前 `roundNo`、客户可见范围和审计记录。
|
||||||
|
|
||||||
资料包不能只关联整票入仓码。已确认支持一单多柜、拆批和父订单—子订单关系,因此每个关联项保存客户、订单、入仓码和装柜明细引用;部分装柜只展示本柜实际箱数并标记线下处理,不在系统内自动做数量分摊。柜次一旦装柜完成不因甩柜改船而变化,受影响案例不能静默重置回执轮次。
|
资料包不能只关联整票入仓码。已确认支持一单多柜、拆批和父订单—子订单关系,因此每个关联项保存客户、订单、入仓码和装柜明细引用;部分装柜只展示本柜实际箱数并标记线下处理,不在系统内自动做数量分摊。柜次一旦装柜完成不因甩柜改船而变化,受影响案例不能静默重置回执轮次。
|
||||||
|
|
||||||
@@ -100,7 +115,7 @@
|
|||||||
| 送港/船期事实 | PORT_DELIVERY_PENDING、DEPARTED_WAREHOUSE、IN_TRANSIT_TO_PORT、PORT_RECEIVED、ROLLED_OVER、VESSEL_DEPARTED | 与报关案例独立;进港和甩柜不等于海运中,只有真实开船才进入海运节点 |
|
| 送港/船期事实 | PORT_DELIVERY_PENDING、DEPARTED_WAREHOUSE、IN_TRANSIT_TO_PORT、PORT_RECEIVED、ROLLED_OVER、VESSEL_DEPARTED | 与报关案例独立;进港和甩柜不等于海运中,只有真实开船才进入海运节点 |
|
||||||
| 装柜门禁 | PASS/BLOCKED | 只判断是否满足 LOADED 的已确认前置 |
|
| 装柜门禁 | PASS/BLOCKED | 只判断是否满足 LOADED 的已确认前置 |
|
||||||
|
|
||||||
上述是首期状态投影。回执首期以文件为主、客户确认整份回执;正式申报由平台授权人员人工提交并回填结果;实际开航首期人工录入,甩柜/改配人工修改原柜船信息并保留原报关事实,不重新评估申报批次。其余稳定编码、退回/重开规则和责任人仍需在开发前确认。当前四态不能直接承担新流程;收敛时应明确旧状态的映射和删除时点,不保留双协议。
|
上述是首期状态投影。回执首期以文件为主、客户确认整份回执;正式申报由平台授权人员人工提交并回填结果;查验、扣货、补资料和其他情况均由平台人工点击标记异常、选择理由,选择“其他”时填写备注;异常解除也由平台人工点击处理。实际开航首期人工录入,甩柜/改配人工修改原柜船信息并保留原报关事实,不重新评估申报批次。当前四态不能直接承担新流程;收敛时应明确旧状态的映射和删除时点,不保留双协议。
|
||||||
|
|
||||||
物理 `LOADED` 门禁必须明确校验以下事实:
|
物理 `LOADED` 门禁必须明确校验以下事实:
|
||||||
|
|
||||||
@@ -142,19 +157,19 @@
|
|||||||
|
|
||||||
## 实施顺序与进入条件
|
## 实施顺序与进入条件
|
||||||
|
|
||||||
1. **冻结业务规则**:确认客户资料清单、回执轮次、打回重做、所有客户确认、整柜正式申报、查验/放行、甩柜/改配和跨客户合并;已确认规则以[需求确认表](国内货柜履约需求确认表.md#L24)为准。
|
1. **冻结业务规则**:确认文件可上传即可、回执轮次、打回重做、所有客户确认、整柜正式申报、异常理由/备注、甩柜/改配和跨客户合并;已确认规则以[需求确认表](国内货柜履约需求确认表.md#L24)为准。
|
||||||
2. **先做服务端契约**:完成 customerCustomsCase、资料版本、报关行回执轮次、客户确认、整柜申报批次、送港/进港/甩柜/开船事实、状态投影、权限、幂等、审计、File 类别和初始化 SQL;同步更新 OpenAPI、Gateway、IAM 和相关消费者。
|
2. **先做服务端契约**:完成 customerCustomsCase、资料版本、报关行回执轮次、客户确认、整柜申报批次、送港/进港/甩柜/开船事实、状态投影、权限、幂等、审计、File 类别和初始化 SQL;同步更新 OpenAPI、Gateway、IAM 和相关消费者。
|
||||||
3. **接入客户入口**:独立列表/详情与订单快捷入口共用 packageId;仅在 `LOADED` 后进入本柜报关案例,覆盖资料上传、报关行回执查看、确认、打回、重新上传和新回执版本。
|
3. **接入客户入口**:独立列表/详情与订单快捷入口共用 packageId;仅在 `LOADED` 后进入本柜报关案例,覆盖资料上传、报关行回执查看、确认、打回、重新上传和新回执版本。
|
||||||
4. **接入平台协同**:`LOADED` 后按最终实装快照通知报关行,逐客户处理资料和回执,全部客户确认后提交整柜资料;人工记录正式申报、查验、不查验放行和其他结果。送港线独立接入拖车、进港、甩柜和实际开船。
|
4. **接入平台协同**:`LOADED` 后按最终实装快照通知报关行,逐客户处理资料和回执,全部客户确认后提交整柜资料;平台人工记录正式申报,并通过异常节点选择查验、扣货、补资料或其他理由,必要时填写备注和处理结果。送港线独立接入拖车、进港、甩柜和实际开船。
|
||||||
5. **接入船期价格**:先复用有效价格簿和单渠道参考估价,再实现批量估价;批量列表、排序和导出必须先通过接口和价格可比性评审。
|
5. **接入船期价格**:先复用有效价格簿和单渠道参考估价,再实现批量估价;批量列表、排序和导出必须先通过接口和价格可比性评审。
|
||||||
|
|
||||||
## 待确认事项
|
## 已确认的简化规则
|
||||||
|
|
||||||
| 问题 | 阻断范围 | 需要形成的结论 |
|
| 问题 | 阻断范围 | 需要形成的结论 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 资料清单具体项目、条件规则和版本生效方式 | 清单、审核、补件 | 首版人工维护清单及版本负责人 |
|
| 报关资料上传 | 客户案例、整柜提交 | 不区分文件类型;有文件即可上传、替换和保留版本 |
|
||||||
| 客户确认/打回原因和回执轮次 | 客户案例、整柜提交 | 回执版本、roundNo、确认人、打回重做规则 |
|
| 客户确认/打回原因和回执轮次 | 客户案例、整柜提交 | 回执版本、roundNo、确认人、打回重做规则 |
|
||||||
| 海关查验、不查验放行、扣货/补件等正式结果 | 整柜申报批次、客户展示 | 结果类型、凭证、来源、客户可见范围和责任人 |
|
| 海关查验、扣货、补资料和其他异常 | 整柜申报批次、客户展示 | 平台人工标记异常并选择理由;选择“其他”时填写备注,不接短信或自动海关系统 |
|
||||||
| 送港、进港、甩柜、改配船次和实际开船事件 | 待发区、送港线、海运节点 | 事实字段、重试规则、客户通知和船次历史;首期人工录入实际开航,改配人工修改原柜船信息但不改变已完成报关事实 |
|
| 送港、进港、甩柜、改配船次和实际开船事件 | 待发区、送港线、海运节点 | 事实字段、重试规则、客户通知和船次历史;首期人工录入实际开航,改配人工修改原柜船信息但不改变已完成报关事实 |
|
||||||
| 价格比较、导出、报价有效期和金额变化提示 | 客户报价页、下单 | 统一币种/税模式/附加费和失效处理 |
|
| 价格比较、导出、报价有效期和金额变化提示 | 客户报价页、下单 | 统一币种/税模式/附加费和失效处理 |
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
# 头程到尾程当前维护入口
|
# 头程到尾程当前维护入口
|
||||||
|
|
||||||
这里集中列出后续流程变更需要查找和修改的文档。整体流程基线已确认,除报关协同代码外进入收尾;日常只从本目录进入,历史开发材料统一放在[文档归档](../归档/README.md)。
|
这里集中列出 F01-F40 全流程变更需要查找和修改的文档。报关协同代码已接入并通过真实 HTTP 验收,当前进入全流程状态与页面证据收尾;日常只从本目录进入,历史开发材料统一放在[文档归档](../归档/README.md)。
|
||||||
|
|
||||||
## 当前流程文档
|
## 当前流程文档
|
||||||
|
|
||||||
@@ -10,9 +10,9 @@
|
|||||||
| 分段流程 | [头程到尾程分阶段流程](../头程到尾程分阶段流程/README.md) | 六个阶段的字段、页面操作、权限、状态和异常 |
|
| 分段流程 | [头程到尾程分阶段流程](../头程到尾程分阶段流程/README.md) | 六个阶段的字段、页面操作、权限、状态和异常 |
|
||||||
| 货柜入口 | [国内货柜履约 README](../国内货柜履约/README.md) | 分柜、装柜、报关协同、送港和进港的货柜范围 |
|
| 货柜入口 | [国内货柜履约 README](../国内货柜履约/README.md) | 分柜、装柜、报关协同、送港和进港的货柜范围 |
|
||||||
| 报关与船期专题 | [报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md) | 客户资料、报关行回执、客户确认/打回、正式申报、海关结果和船期价格 |
|
| 报关与船期专题 | [报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md) | 客户资料、报关行回执、客户确认/打回、正式申报、海关结果和船期价格 |
|
||||||
| 报关开发交接 | [报关代码开发交接清单](报关代码开发交接清单.md) | 当前未完成的报关代码范围、完成条件和开发入口 |
|
| 报关开发交接 | [报关代码开发交接清单](报关代码开发交接清单.md) | 报关代码完成条件、已验收范围和后续增强项 |
|
||||||
| 头程与报关交互矩阵 | [头程节点与报关清关交互矩阵](头程节点与报关清关交互矩阵.md) | F01-F24 各节点的客户、平台、PDA、报关行和船期交互 |
|
| 头程与报关交互矩阵 | [头程节点与报关清关交互矩阵](头程节点与报关清关交互矩阵.md) | F01-F24 各节点的客户、平台、PDA、报关行和船期交互 |
|
||||||
| 第一阶段冻结矩阵 | [头程至实际开船节点冻结矩阵与缺口清单](头程至实际开船节点冻结矩阵与缺口清单.md) | F01-F24 节点、报关完成进入待发区、当前实现缺口和开发前确认项 |
|
| 全流程实现对照 | [全流程节点矩阵与缺口清单](头程至实际开船节点冻结矩阵与缺口清单.md) | F01-F40 节点、现行规则、实现差异和验证边界;保留原文件路径 |
|
||||||
| 正式申报与海关结果 | [正式申报与海关结果接入设计](正式申报与海关结果接入设计.md) | F22.7 正式申报批次、报关单号、F22.8 查验/补资料/放行/扣货/其他结果及三端边界 |
|
| 正式申报与海关结果 | [正式申报与海关结果接入设计](正式申报与海关结果接入设计.md) | F22.7 正式申报批次、报关单号、F22.8 查验/补资料/放行/扣货/其他结果及三端边界 |
|
||||||
| 甩柜改配接入设计 | [甩柜改配接入设计](甩柜改配接入设计.md) | F23.3 原柜人工修改船信息并保留修改历史 |
|
| 甩柜改配接入设计 | [甩柜改配接入设计](甩柜改配接入设计.md) | F23.3 原柜人工修改船信息并保留修改历史 |
|
||||||
|
|
||||||
|
|||||||
+72
-28
@@ -1,12 +1,12 @@
|
|||||||
# 头程至实际开船节点冻结矩阵与缺口清单
|
# 全流程节点矩阵与缺口清单
|
||||||
|
|
||||||
本文按当前确认结果冻结第一阶段范围:从头程下单开始,完成国内履约、报关协同、送港运输,并记录承运船舶实际开航。尾程入库、派送和签收不在本阶段实现。流程基线同时采用《报关代码开发交接清单》和《头程到尾程流程节点梳理》;原型只用于页面字段和承载方式参考。
|
本文按当前确认结果冻结 F01-F40 全流程范围:从头程下单开始,完成国内履约、报关协同、送港运输、实际开航、海外入库、出库和最终回写。F01-F24 是国内头程至实际开航的前段,F25-F40 是海运目的港及尾程履约。流程基线同时采用《报关代码开发交接清单》和《头程到尾程流程节点梳理》;原型只用于页面字段和承载方式参考。
|
||||||
|
|
||||||
## 一、阶段边界
|
## 一、阶段边界
|
||||||
|
|
||||||
```text
|
```text
|
||||||
头程下单
|
头程下单
|
||||||
F01-F13:下单、审核、到仓、测量、计费、费用确认、组托、待分柜
|
F01-F13:下单、审核、到仓、测量、计费、费用确认、国内扣货/解除、组托、待分柜
|
||||||
国内货柜履约
|
国内货柜履约
|
||||||
F14-F21:分柜、订舱、拖车、拣货、装柜、LOADED
|
F14-F21:分柜、订舱、拖车、拣货、装柜、LOADED
|
||||||
报关完成后进入待发区
|
报关完成后进入待发区
|
||||||
@@ -14,38 +14,82 @@
|
|||||||
F23:待发区、送港、进港、甩柜、改配
|
F23:待发区、送港、进港、甩柜、改配
|
||||||
海运起点
|
海运起点
|
||||||
F24:承运船舶实际开航
|
F24:承运船舶实际开航
|
||||||
|
目的港与海外入库
|
||||||
|
F25-F30:目的港处理、尾程订单、入仓计划、接柜、收货、库存入账
|
||||||
|
海外库存与出库
|
||||||
|
F31-F37:库内操作、暂扣、库内服务、排车、生成出库/派送单、拣货发车、出库
|
||||||
|
派送与完成
|
||||||
|
F38-F40:签收、异常退回、回访和完成回写
|
||||||
```
|
```
|
||||||
|
|
||||||
本阶段的终点是实际开航事实,不是“报关完成”、国内离仓、目的港清关或海外入仓。`LOADED` 只表示物理装柜完成;报关完成是进入待发区的前置条件,待发区和船期节点分别保存,不能把其中一条线的结果写成另一条线的结果。
|
国内前段 F01-F24 的终点是实际开航,全流程继续至 F40;其中 F37 为海外出库。`LOADED` 只表示物理装柜完成;报关完成是进入待发区的前置条件,待发区和船期节点分别保存,不能把其中一条线的结果写成另一条线的结果。
|
||||||
|
|
||||||
## 二、F01-F24 节点冻结矩阵
|
### 实现与验证口径
|
||||||
|
|
||||||
|
“已有实现”不等于最新版本已完成验收。下表的既有 HTTP 证据只证明对应报告范围与版本;历史通过不能替代当前完整链路、页面或 PDA 现场验证。报关和运输专项的通过也不能外推为 F01-F40 全部通过。后续增强项不作为首期主流程缺失处理。
|
||||||
|
|
||||||
|
2026-09-29 修复后的默认全量真实 HTTP 回归已通过:Admin 11,627 项检查、120 个模块、7,429 次请求,0 失败、0 跳过模块;Client 195 项检查全部通过。F31 换托同库位比较、A0 共享溢出位移库、F33 无贴标转仓查询及跨服务错误处理已修复并部署测试环境;验收脚本补齐直接贴标审核、返工重新领取及禁止回移虚拟收货位的边界。离线合同 128 个文件、773 项断言全部通过。
|
||||||
|
|
||||||
|
同票普通 FBA 主链证据为入仓码 `NYEXX2609290171`、柜次 `D1063`、柜号 `TSTU3425326`、排车单 `DS-WH-20260929-067073`、出库单 `OB-WH-20260929-158402`;两张目的仓派送单签收后,已核对来源入仓单 `DELIVERED` 和来源订单 `COMPLETED`。随后故意执行的退回异常测试会改变留存单据状态,不能把最终留存状态误读成未曾完成。退税报关分支另由同一全量报告中的混合柜检查覆盖,不冒充同一票退税至签收证据。
|
||||||
|
|
||||||
|
对应证据:`baiyue-firstleg/reports/admin-full-current-20260929-r7.json`、`reports/client-full-current-20260929-r3/client-test-env-20260929063613-e54d44dd.json`、`reports/fba-main-chain-evidence-20260929.json`(后两个路径同属后端仓库)。Admin/Client 报关详情已按 1920×1080 页面核对;船期日历网络恢复后重载正常。未离仓测试柜 `TSTU7897110` 已实际验证首次发送、普通文本回执上传、客户确认后的平台执行、正式申报、其他理由必填备注、异常保存与人工处理;客户确认通过该客户自己的 HTTP 接口完成。异常处理后回执确认保留,未上传完税文件仍保持报关中并阻断离仓。
|
||||||
|
|
||||||
|
页面复验发现并修复异常发生时间早 8 小时的问题:国内 `LocalDateTime` 接口改为接收上海业务时间。Admin 提交 `4ead51a5feedf65be9443ddfe3dd45da7ca49e64` 已通过测试环境 Jenkins #482 部署;262 个测试文件、2,121 项测试和构建通过。部署后真实页面新增查验记录的发生时间与服务器记录时间相差 0.879 秒。详见后端仓库 `reports/customs-time-postdeploy-20260929.json` 和 `reports/customs-other-resolved-1920-20260929.jpg`。Android 真机、弱网和外部船司正式凭据仍属于单列验证边界,不纳入本次内置浏览器与 HTTP 通过结论。
|
||||||
|
|
||||||
|
## 二、F01-F40 节点冻结矩阵
|
||||||
|
|
||||||
| 节点 | 客户可见进度 | 后台业务对象 | 必须形成的真实事实 | 当前状态 | 本阶段缺口 |
|
| 节点 | 客户可见进度 | 后台业务对象 | 必须形成的真实事实 | 当前状态 | 本阶段缺口 |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| F01-F07 | 待下单、审核中、已审核 | 企业、订单、审核任务 | 提交、补件、审核、入仓单生成 | 已有主链 | 按现有订单契约回归,不在本轮重做 |
|
| F01-F07 | 待下单、审核中、已审核 | 企业、订单、审核任务 | 提交、补件、审核、入仓单生成 | 已有主链 | 按现有订单契约回归,不在本轮重做 |
|
||||||
| F08-F10 | 待到仓、测量中、待确认 | 入仓单、测量记录 | 收货、扫码、称重、测量、审核 | 已有主链 | 只核对是否能稳定产出排柜事实 |
|
| F08-F10 | 待到仓、测量中、待确认 | 入仓单、测量记录 | 收货、扫码、称重、测量、审核 | 已有主链 | 只核对是否能稳定产出排柜事实 |
|
||||||
| F11-F13 | 费用待确认、待组托、待分柜 | 费用版本、确认记录、托盘 | 计费推送、客户确认、组托/封托 | 已确认并行规则 | 保证费用默认确认不能冒充报关确认 |
|
| F11 | 费用待确认 | 费用版本、客户确认记录 | 计费推送、客户主动确认、版本留痕 | 已有实现;旧总览的默认确认表述与阶段二及服务指引冲突 | 按现行规则,装柜可自动发布费用,但不能代替客户确认;不将缺少 `SYSTEM_AUTO_AT_LOADED` 列为必修代码缺陷 |
|
||||||
|
| F12 | 国内扣货中、已解除 | 国内入仓单 HOLD 记录 | 扣货、解除、原因和后续作业门禁 | 已实现;最新全量 inbound-hold 模块通过 | 与报关海关异常、海外库存暂扣分别维护,不能混为同一节点 |
|
||||||
|
| F13 | 待组托、待分柜 | 一件代发清点、托盘和封托记录 | 逐箱清点、归托、封托 | 已有主链 | 结合一件代发路径验证;不要求普通散货重复执行一件代发清点流程 |
|
||||||
| F14-F20 | 待分柜、订舱中、装柜中 | 柜次、装柜计划、拖车、PDA 任务 | 分柜、订舱、排车、拣货、照片、铅封、数量核对 | 主链已有 | 核对真实柜号、订舱和装柜快照能否冻结 |
|
| F14-F20 | 待分柜、订舱中、装柜中 | 柜次、装柜计划、拖车、PDA 任务 | 分柜、订舱、排车、拣货、照片、铅封、数量核对 | 主链已有 | 核对真实柜号、订舱和装柜快照能否冻结 |
|
||||||
| F21 | 国内已装柜 | 装柜计划、物理货柜、装柜证据 | 实际柜号、实装箱数、装柜证据、`LOADED` | 已有 | 报关案例按最终实装范围建立;部分装柜只显示已装箱数并标记线下处理,不在系统内自动分摊 |
|
| F21 | 国内已装柜 | 装柜计划、物理货柜、装柜证据 | 实际柜号、实装箱数、装柜证据、`LOADED` | 已有 | 报关案例按最终实装范围建立;部分装柜只显示已装箱数并标记线下处理,不在系统内自动分摊 |
|
||||||
| F22.1 | 报关确认中 | 柜级报关聚合内的客户资料范围 | 每客户范围、入仓码范围、混合柜隔离、实装范围回显 | 已实现并通过真实 HTTP 验收 | 独立“案例”对象仍可在正式批次设计时补充;部分装柜仍线下处理 |
|
| F22.1 | 报关确认中 | 柜级报关聚合内的客户资料范围 | 每客户范围、入仓码范围、混合柜隔离、实装范围回显 | 已实现并通过真实 HTTP 验收 | 独立“案例”对象仍可在正式批次设计时补充;部分装柜仍线下处理 |
|
||||||
| F22.2 | 待提交资料、待补资料 | 客户资料包 | 上传、替换、关联范围、版本、冻结 | 已实现并通过真实 HTTP 验收 | 资料类型化清单和补件原因待补 |
|
| F22.2 | 待提交资料、待补资料 | 客户资料包 | 上传、替换、关联范围、版本、冻结 | 已实现并通过真实 HTTP 验收 | 首期不维护资料类型清单;有文件即可上传,补件通过人工异常理由和备注说明 |
|
||||||
| F22.3 | 已发送报关行 | 独立首次发送批次 `brokerSubmission` | 业务批次号、发送人、发送时间、冻结版本、资料快照、幂等历史 | 已实现并通过定向测试与测试环境部署 | 报关行接收确认和回执轮次对象待补 |
|
| F22.3 | 已发送报关行 | 独立首次发送批次 `brokerSubmission` | 业务批次号、发送人、发送时间、冻结版本、资料快照、幂等历史 | 已实现并通过定向测试与测试环境部署 | 报关行接收确认和回执轮次对象待补 |
|
||||||
| F22.4 | 待客户确认 | 回执/完成文件版本 | 文件版本、关联客户范围、客户可下载 | 已实现;回执历史和确认动作历史均只读投影 | 独立回执返回时间/下载凭证仍待补 |
|
| F22.4 | 待客户确认 | 回执/完成文件版本 | 文件版本、关联客户范围、客户可下载 | 已实现;回执历史和确认动作历史均只读投影 | 独立回执返回时间/下载凭证仍待补 |
|
||||||
| F22.5 | 客户确认中、已打回 | 客户确认记录与动作历史 | 确认/打回、回执版本、操作人、时间、原因 | 已实现并通过定向测试与测试环境部署 | 通知聚合和报关行回执轮次待补 |
|
| F22.5 | 客户确认中、已打回 | 客户确认记录与动作历史 | 确认/打回、回执版本、操作人、时间、原因 | 已实现并通过定向测试与测试环境部署 | 通知聚合和报关行回执轮次待补 |
|
||||||
| F22.6 | 等待整柜确认 | 完税文件齐全门禁 | 所有退税客户确认、发送执行、真实完税文件齐全 | 已实现并通过专项真实 HTTP 验收 | 复杂结果凭证和补资料专项门禁待补 |
|
| F22.6 | 等待整柜确认 | 完税文件齐全门禁 | 所有退税客户确认、发送执行、真实完税文件齐全 | 已实现并通过专项真实 HTTP 验收 | 查验、扣货、补资料作为平台人工异常节点处理,不新增自动凭证门禁 |
|
||||||
| F22.7 | 已提交正式申报 | 正式申报批次 | 报关行确认、正式申报时间、操作人、批次、报关单号 | 已实现并通过真实 HTTP 7 步联调 | 后续补更复杂的结果凭证类型 |
|
| F22.7 | 已提交正式申报 | 正式申报批次 | 报关行确认、正式申报时间、操作人、批次、报关单号 | 已实现并通过真实 HTTP 7 步联调 | 后续可补报关行接收时间和下载凭证 |
|
||||||
| F22.8 | 查验中、待补资料、已放行、扣货/其他 | 海关结果事实 | 报关单号、结果类型、时间、凭证、处理结果 | 已实现并通过真实 HTTP 7 步联调 | 后续补查验/扣货/补资料专项场景的更细验收 |
|
| F22.8 | 查验中、待补资料、已放行、扣货/其他 | 海关结果事实 | 报关单号、结果类型、时间、人工理由、备注和处理结果 | 已实现;真实 HTTP 与人工异常页面保存/处理通过,发生时间偏差已修复并部署复验 | 不接短信或自动海关系统;真机及外部系统不在页面验证范围 |
|
||||||
| F23.1 | 待发区、送港中、已离仓 | 待发区与送港/出仓任务 | 报关完成时间、待发区门禁、离仓时间、车辆/任务、操作人、证据 | 已实现并通过真实 HTTP 验收 | 继续补待发区客户/平台投影展示 |
|
| F23.1 | 待发区、送港中、已离仓 | 待发区与送港/出仓任务 | 报关完成时间、待发区门禁、离仓时间、车辆/任务、操作人、证据 | 已实现并通过真实 HTTP 验收 | 继续补待发区客户/平台投影展示 |
|
||||||
| F23.2 | 已送港、已进港 | 运输和港口事实 | 送港时间、进港时间、来源和凭证 | 部分已有 | 与订舱、拖车和船次事实统一读写 |
|
| F23.2 | 已送港、已进港 | 运输和港口事实 | 送港时间、进港时间、来源和凭证 | 已实现;已有真实 HTTP 证据 | 继续补充最新页面证据,并保持与订舱、拖车和船次事实统一读写 |
|
||||||
| F23.3 | 已甩柜、等待改船后承运 | 船期记录修改历史 | 甩柜原因、发生时间、修改前后船名/航次/船期、处理人 | 已实现并通过测试环境真实 HTTP;平台与客户端最新船期投影一致 | 继续补页面截图和更复杂异常分支;柜次、订舱关联和报关事实不变 |
|
| F23.3 | 已甩柜、等待改船后承运 | 船期记录修改历史 | 甩柜原因、发生时间、修改前后船名/航次/船期、处理人 | 已实现并通过测试环境真实 HTTP;平台与客户端最新船期投影一致 | 继续补页面截图和更复杂异常分支;柜次、订舱关联和报关事实不变 |
|
||||||
| F24 | 海运中 | 船次实际节点 | 承运船舶、航次、实际开航时间、来源/凭证 | 基础已有 | 只允许实际开航事实推进海运节点 |
|
| F24 | 海运中 | 船次实际节点 | 承运船舶、航次、实际开航时间、来源/凭证 | 已实现;实际节点与查询任务已有真实 HTTP 证据 | 继续补充最新一轮页面证据;只允许实际开航事实推进海运节点 |
|
||||||
|
| F25 | 目的港处理中、待海外接柜 | 船节点、目的港清关/提柜、尾程订单 | 到港、卸船、清关、提柜和可接柜事实 | 已实现并有综合真实 HTTP 证据 | 外部码头/车队差异继续按异常分支补充 |
|
||||||
|
| F26 | 尾程订单待建计划 | 跨区事件、尾程订单 | 装柜完成、船节点和来源入仓单快照可靠投递与消费 | 已实现并有综合真实 HTTP 证据 | 继续观察跨区事件延迟和补偿告警 |
|
||||||
|
| F27 | 待建立海外入仓计划 | 入仓计划、计划托盘和资源锁 | 按柜内每票生成计划、预计到仓和托盘资源冻结 | 已实现并有综合真实 HTTP 证据 | 继续补齐异常重试页面证据 |
|
||||||
|
| F28 | 待接柜、接柜中 | 海外 PDA 接柜会话 | 柜号认领、三类签收照片和签收确认 | 已实现并有综合真实 HTTP 证据 | Android 真机验收仍是独立非阻塞项 |
|
||||||
|
| F29 | 入库中 | 海外 PDA 收货任务 | FBA 散货、海外仓逐箱、一件代发整托等实收事实 | 已实现并有综合真实 HTTP 证据 | 继续补充现场设备和弱网证据 |
|
||||||
|
| F30 | 入库完成 | 入库任务、库存和跨区回写事件 | 全柜核平、库存同事务入账、卸柜完成事件 | 已实现并有综合真实 HTTP 证据 | 保持事件幂等和库存数量守恒 |
|
||||||
|
| F31 | 库存可用、库内服务中 | 库存、库位、托盘、盘点 | 上架、移库、合托/拆托、盘点和库存流水 | 已实现并有综合真实 HTTP 证据 | 继续补充大批量库存性能验收 |
|
||||||
|
| F32 | 暂扣中、已解除 | 暂扣记录和库存锁 | 暂扣原因、解除原因、操作人和库存可用性变化 | 已实现并有综合真实 HTTP 证据 | 暂扣与出库并发场景继续补充 |
|
||||||
|
| F33 | 换标/转运/废弃处理中 | 换标、转运、废弃子单 | 客户确认、箱唛/托盘变更、库存锁和实际扣减事实 | 已实现并有综合真实 HTTP 证据 | 继续补充复杂返工和跨仓异常 |
|
||||||
|
| F34 | 待派送、排车中 | 智能预排、排车单 | 候选、草稿锁、正式排车和目的仓分配 | 已实现并有综合真实 HTTP 证据 | 继续补充多车多目的仓页面证据 |
|
||||||
|
| F35 | 待转派送、待出库 | 排车转派送、出库单、派送单 | 出库/派送单生成、目的仓拆分、费用只发布一次 | 已实现并有综合真实 HTTP 证据 | 保持转派送前不可发车 |
|
||||||
|
| F36 | 拣货中、待发车 | 海外 PDA 排车任务 | 托盘扫描、数量核平、车辆资料和发车门禁 | 已实现并有综合真实 HTTP 证据 | Android 真机和弱网恢复仍需专项验证 |
|
||||||
|
| F37 | 已出库、派送中 | 出库单、派送单 | 出库完成、库存扣减和派送任务关联 | 已实现并有综合真实 HTTP 证据 | 继续补跨目的仓汇总展示 |
|
||||||
|
| F38 | 派送中、已签收 | 派送单、签收凭证 | 签收文件、签收时间和每个目的仓派送完成 | 已实现并有综合真实 HTTP 证据 | 继续补异常签收凭证类型 |
|
||||||
|
| F39 | 异常退回处理中 | 异常单、退回入仓和库存恢复 | 拒收/部分拒收、退回、库存恢复和原因历史 | 已实现并有综合真实 HTTP 证据 | 继续补多次退回和部分恢复组合场景 |
|
||||||
|
| F40 | 已完成、待回访 | 客户回访、跨区完成事件、订单回写 | 回访记录、`DELIVERED` 回写及订单 `COMPLETED` 收口 | 已实现并有综合真实 HTTP 证据 | 继续补跨区延迟时的客服投影 |
|
||||||
|
|
||||||
## 三、当前实现与目标的主要断点
|
## 三、当前实现与目标的主要断点
|
||||||
|
|
||||||
### 1. 报关数据模型已支持客户范围,发送批次仍需独立建模
|
### 1. 客户范围和首次发送批次已落地,回执轮次属于后续增强
|
||||||
|
|
||||||
当前 `fl_customs_container` 仍是柜级状态聚合,但客户资料通过客户和入仓码范围隔离,真实验收已覆盖同柜多客户和混合柜。正式申报批次、海关结果事实、首次发送报关行批次和客户确认动作历史已经独立落地;尚未独立建模的是报关行接收回执、回执轮次和更细的客户案例聚合。
|
当前 `fl_customs_container` 仍是柜级状态聚合,但客户资料通过客户和入仓码范围隔离,真实验收已覆盖同柜多客户和混合柜。正式申报批次、海关结果事实、首次发送报关行批次和客户确认动作历史已经独立落地;尚未独立建模的是报关行接收回执、回执轮次和更细的客户案例聚合。
|
||||||
|
|
||||||
|
### 1.1 费用自动发布与客户确认必须区分
|
||||||
|
|
||||||
|
阶段二“费用计费与确认”和 `baiyue-firstleg/firstleg/AGENTS.md` 明确规定:费用不阻断排柜和装柜,装柜完成不得代替客户自动确认,客户确认与本票装柜完成共同构成最终冻结条件。`FbaPricingService.autoSendAfterLoadingCompleted` 执行平台费用确认与发送,`confirmByCustomer` 才记录客户确认人和时间;`SENT` 不等于客户确认。旧总览要求 `SYSTEM_AUTO_AT_LOADED` 的表述与现行规则冲突,不能据此直接新增自动代客确认。若未来明确改变该规则,再同步费用版本、确认来源和冻结边界。
|
||||||
|
|
||||||
|
### 1.2 海关异常按人工节点处理
|
||||||
|
|
||||||
|
海关短信由平台人员人工查看和操作,系统不接短信、不自动判断查验或扣货。平台在正式申报批次上人工标记异常,选择“查验”“扣货”“补资料”或“其他”等理由;选择“其他”时填写备注,后续由平台人员人工解除或录入处理结果。异常是申报批次上的附加事实,不改变已上传资料、回执和客户确认历史。
|
||||||
|
|
||||||
目标至少需要以下关系:
|
目标至少需要以下关系:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -86,14 +130,14 @@
|
|||||||
|
|
||||||
- 按客户查看案例和实际装柜覆盖;
|
- 按客户查看案例和实际装柜覆盖;
|
||||||
- 报关行接收回执和回执轮次管理;
|
- 报关行接收回执和回执轮次管理;
|
||||||
- 更细的查验、扣货、补资料和其他结果凭证历史。
|
- 报关行接收回执时间和下载凭证等更细历史。
|
||||||
|
|
||||||
## 四、接口、权限、审计和测试缺口
|
## 四、接口、权限、审计和测试缺口
|
||||||
|
|
||||||
### 接口与数据库
|
### 接口与数据库
|
||||||
|
|
||||||
- OpenAPI 不能继续只暴露旧的四态 `ContainerView`。
|
- OpenAPI 不能继续只暴露旧的四态 `ContainerView`。
|
||||||
- 需要继续补充报关行接收回执、回执轮次、下载凭证及更复杂结果凭证的查询/命令契约;资料包、首次发送批次、回执版本和确认动作只读历史、整柜申报和海关结果基础契约已落地。
|
- 需要继续补充报关行接收回执、回执轮次和下载凭证的查询/命令契约;资料包、首次发送批次、回执版本和确认动作只读历史、整柜申报和海关结果基础契约已落地。
|
||||||
- 文件仍由 File 服务保存,但每个文件必须绑定业务类型、客户案例/申报批次、版本和覆盖范围。
|
- 文件仍由 File 服务保存,但每个文件必须绑定业务类型、客户案例/申报批次、版本和覆盖范围。
|
||||||
- 每个写命令都要带版本和幂等键;重放同参数返回原结果,不同参数返回冲突。
|
- 每个写命令都要带版本和幂等键;重放同参数返回原结果,不同参数返回冲突。
|
||||||
- 换柜时需要保留新旧柜关联;部分装柜只记录已装箱数和线下处理标记,不在系统内自动做数量分摊或覆盖旧资料。
|
- 换柜时需要保留新旧柜关联;部分装柜只记录已装箱数和线下处理标记,不在系统内自动做数量分摊或覆盖旧资料。
|
||||||
@@ -110,7 +154,7 @@
|
|||||||
|
|
||||||
### 审计
|
### 审计
|
||||||
|
|
||||||
需要保留客户范围、资料版本、回执轮次、确认人、打回原因、提交批次、报关单号、结果凭证和操作时间。客户 A 的动作不能出现在客户 B 的案例中;柜级汇总可以看到客户名和业务编号,但客户端只能看到自身范围。
|
需要保留客户范围、资料版本、回执轮次、确认人、打回原因、提交批次、报关单号、异常理由、备注和操作时间。客户 A 的动作不能出现在客户 B 的案例中;柜级汇总可以看到客户名和业务编号,但客户端只能看到自身范围。
|
||||||
|
|
||||||
### 测试
|
### 测试
|
||||||
|
|
||||||
@@ -127,9 +171,9 @@
|
|||||||
9. 客户越权读取同柜其他客户资料被拒绝。
|
9. 客户越权读取同柜其他客户资料被拒绝。
|
||||||
10. 部分装柜能显示实际箱数并留下线下处理标记;换柜不能直接覆盖原案例和历史回执。
|
10. 部分装柜能显示实际箱数并留下线下处理标记;换柜不能直接覆盖原案例和历史回执。
|
||||||
|
|
||||||
## 五、开发前仍需业务确认
|
## 五、后续增强(无需当前业务确认)
|
||||||
|
|
||||||
以下问题中,前四项已经由《报关代码开发交接清单》和《头程到尾程流程节点梳理》冻结,本轮又补充冻结了文件形态、部分装柜展示、回执确认、首期申报和实际开航/改配处理方式;表格后的内容仍需业务补充,不能由代码现状推断。
|
以下内容不阻断当前开发:回执接收时间、回执轮次和下载凭证可以后续增强;海关短信、查验、扣货、补资料和其他异常按平台人工标记、选择理由和填写备注处理。
|
||||||
|
|
||||||
### 已冻结的业务规则
|
### 已冻结的业务规则
|
||||||
|
|
||||||
@@ -151,14 +195,14 @@
|
|||||||
| 资料继承 | 报关完成后资料、平台回执和客户确认与船期独立;甩柜/改配不触发重新上传或重新确认。 |
|
| 资料继承 | 报关完成后资料、平台回执和客户确认与船期独立;甩柜/改配不触发重新上传或重新确认。 |
|
||||||
| 航次任务 | 平台人工修改原柜船信息,继续使用原任务;保留修改历史和已有节点。 |
|
| 航次任务 | 平台人工修改原柜船信息,继续使用原任务;保留修改历史和已有节点。 |
|
||||||
|
|
||||||
### 仍需补充的字段和操作规则
|
### 已确认的字段和操作规则
|
||||||
|
|
||||||
1. 首版资料清单具体项目、条件规则、版本生效方式和责任人是什么?
|
1. (已确认)首期不维护资料类型清单和逐项责任人;资料包只要有文件即可上传、替换和留版本。
|
||||||
2. (已确认)第一版由平台人员直接修改原柜船名、航次和船期,填写原因并保留修改历史。
|
2. (已确认)查验、扣货、补资料和其他结果由平台人员人工标记异常、选择理由;选择“其他”时填写备注,异常解除也由平台人工点击。
|
||||||
3. (已确认)平台人工修改原柜船名、航次和船期;柜子与原任务不变。
|
3. (已确认)第一版由平台人员直接修改原柜船名、航次和船期,填写原因并保留修改历史。
|
||||||
4. (已确认)原航次退税资料、回执和客户确认与船期独立,甩柜/改配不触发重新确认。
|
4. (已确认)平台人工修改原柜船名、航次和船期;柜子与原任务不变。
|
||||||
5. (已确认)甩柜/改配与报关资料无关,不重新生成报关批次,不要求客户重新确认。
|
5. (已确认)原航次退税资料、回执和客户确认与船期独立,甩柜/改配不触发重新确认。
|
||||||
6. 修改船信息不生成实际开航事实;只有本柜实际随船开航后才记录 `DEPARTED_ORIGIN_PORT`。
|
6. (已确认)修改船信息不生成实际开航事实;只有本柜实际随船开航后才记录 `DEPARTED_ORIGIN_PORT`。
|
||||||
|
|
||||||
### 代码接入前置缺口
|
### 代码接入前置缺口
|
||||||
|
|
||||||
@@ -166,8 +210,8 @@
|
|||||||
|
|
||||||
## 六、冻结结论
|
## 六、冻结结论
|
||||||
|
|
||||||
- 第一阶段覆盖 F01-F24,终点为实际开航。
|
- 全流程基线覆盖 F01-F40;F01-F24 终点为实际开航,F25-F40 继续完成目的港、海外入库、出库、派送和最终回写。
|
||||||
- F22 报关完成后货柜进入 F23 待发区;甩柜/改配只改变运输航次,不改变报关事实。
|
- F22 报关完成后货柜进入 F23 待发区;甩柜/改配只改变运输航次,不改变报关事实。
|
||||||
- 客户确认、报关行回执、整柜正式申报、海关放行、离仓、进港、甩柜和实际开航都是独立事实。
|
- 客户确认、报关行回执、整柜正式申报、海关放行、离仓、进港、甩柜和实际开航都是独立事实。
|
||||||
- 先完成节点矩阵、对象关系、状态投影、门禁和验收缺口确认,再进入代码设计。
|
- 节点清单覆盖完整范围;各节点实现与验证程度以表内状态为准,不将整张矩阵标为全部验收完成。
|
||||||
- 尾程 F25-F40 暂不纳入本阶段实现,但必须保留 F24 到目的港清关的接口衔接点。
|
- F25-F40 已有实现,最新默认全量 HTTP 回归已通过,并核对同票签收后的国内完成回写;本轮报关可写异常页面操作已完成,设备和外部船司边界继续单列,不能用 HTTP 全绿替代这些证据。
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 头程节点与报关清关交互矩阵
|
# 头程节点与报关清关交互矩阵
|
||||||
|
|
||||||
> 本文把头程下单 F01-F24 与报关清关的客户、平台、报关行交互放在同一张图里。当前产品先覆盖国内头程到实际开航;尾程不在本轮。报关资料只适用于包含退税货物的柜,买单货物不创建客户资料协同。
|
> 本文把 F01-F40 全流程中的头程、海运与报关清关交互放在同一张图里;其中 F01-F24 是国内头程到实际开航,F25-F40 由阶段四至阶段六继续承接。报关资料只适用于包含退税货物的柜,买单货物不创建客户资料协同。
|
||||||
|
|
||||||
## 一、总链路
|
## 一、总链路
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
仍需补齐:
|
仍需补齐:
|
||||||
|
|
||||||
1. 报关行接收确认、回执轮次和回执下载凭证的独立对象及更细历史投影。
|
1. 报关行接收确认、回执轮次和回执下载凭证的独立对象及更细历史投影。
|
||||||
2. 待发区客户/平台投影的更细页面展示和截图证据;`LOADED → 报关 → 待发区` 已在既有混合柜报告中通过,平台与客户改船后的当前船期双端回读已验收。
|
2. 待发区客户/平台投影的更细页面展示和截图证据;`LOADED → 报关 → 待发区` 已在混合柜报告中通过,平台与客户改船后的当前船期双端回读已验收。F25-F40 的海运目的港、海外入库、库存、出库、派送和最终回写由阶段四至阶段六维护,综合证据见 `baiyue-firstleg/reports/admin-overseas-chain-final-fixture-20260924.json`。
|
||||||
|
|
||||||
正式申报批次和海关结果已在本轮实现并通过真实 HTTP:平台创建/提交批次、录入查验、查询并处理结果,客户按自身订单查询结果;证据见 `baiyue-firstleg/reports/formal-customs-declaration-and-clearance-result-20260927.json`。
|
正式申报批次和海关结果已在本轮实现并通过真实 HTTP:平台创建/提交批次、录入查验、查询并处理结果,客户按自身订单查询结果;证据见 `baiyue-firstleg/reports/formal-customs-declaration-and-clearance-result-20260927.json`。
|
||||||
|
|
||||||
|
|||||||
+14
-6
@@ -1,10 +1,10 @@
|
|||||||
# 报关代码开发交接清单
|
# 报关代码开发交接清单
|
||||||
|
|
||||||
> **当前状态:第一阶段报关协同已接入测试环境。** 客户资料、首次发送报关行批次、回执、客户确认历史和真实完税文件已形成独立链路;报关行确认回执和更复杂结果凭证仍是后续补充项。第一阶段冻结范围和缺口以[头程至实际开船节点冻结矩阵与缺口清单](头程至实际开船节点冻结矩阵与缺口清单.md)为准;流程规则以[报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md)为准,节点关系以[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准。
|
> **当前状态:报关协同已接入测试环境。** 客户资料、首次发送报关行批次、回执、客户确认历史和真实完税文件已形成独立链路;海关查验、扣货、补资料和其他结果由平台人员人工标记异常、选择理由并填写备注,不接短信或自动海关系统。报关行接收回执和下载凭证仍可后续增强。头程至尾程的全流程范围和缺口以[头程至实际开船节点冻结矩阵与缺口清单](头程至实际开船节点冻结矩阵与缺口清单.md)为准;流程规则以[报关资料与船期价格接入梳理](../国内货柜履约/报关资料与船期价格接入梳理.md)为准,节点关系以[头程到尾程流程节点梳理](../头程到尾程流程节点梳理.md)为准。
|
||||||
|
|
||||||
> **本轮补充确认:** 首期报关行回执以文件为主,客户确认整份回执;正式申报由平台授权人员人工提交并回填结果;报关完成后货柜进入待发区;实际开航首期人工录入,甩柜/改配只变更船期,不重新处理已完成报关资料。
|
> **本轮补充确认:** 首期报关行回执以文件为主,客户确认整份回执;正式申报由平台授权人员人工提交并回填结果;报关完成后货柜进入待发区;实际开航首期人工录入,甩柜/改配只变更船期,不重新处理已完成报关资料。
|
||||||
|
|
||||||
> **验收证据:** 既有全链路报告保留旧版 526/526、混合柜 532/532 记录;本轮新增代码、数据库和三端已部署,已用现有完成柜做接口烟测并核对首次发送门禁。完整造数到报关回归仍需要测试环境提供 PDA 作业员账号,当前 `test-acceptance.env` 缺少该变量,脚本按契约在装柜前置处停止。
|
> **验收证据:** 既有全链路报告保留旧版 526/526、混合柜 532/532 记录;本轮新增代码、数据库和三端已部署,已用现有完成柜做接口烟测并核对首次发送门禁。完整造数到报关回归已补齐测试环境专用国内 PDA 作业员并通过;当前报关主链报告为 543/543,运输节点报告为 1036/1036。
|
||||||
|
|
||||||
## 一、必须实现的报关流程
|
## 一、必须实现的报关流程
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
6. 报关行执行完成后,平台上传真实报关完税文件;全部退税资料对应的完税文件齐全后,整柜报关完成。
|
6. 报关行执行完成后,平台上传真实报关完税文件;全部退税资料对应的完税文件齐全后,整柜报关完成。
|
||||||
7. 分别记录海关查验、不查验放行、扣货或其他正式结果。
|
7. 分别记录海关查验、不查验放行、扣货或其他正式结果。
|
||||||
|
|
||||||
报关行回执、客户确认、整柜正式申报和海关放行是不同节点。客户确认不能自动完成,费用的系统默认确认也不能代替报关资料确认。
|
报关行回执、客户确认、整柜正式申报和海关放行是不同节点。客户确认不能自动完成,平台费用确认与发布也不能代替报关资料确认。
|
||||||
|
|
||||||
## 二、报关完成与待发区关系
|
## 二、报关完成与待发区关系
|
||||||
|
|
||||||
@@ -70,11 +70,16 @@
|
|||||||
- 甩柜改配投影提交 `ac3acfce`、`f1218cef`,平台容器读模型修复提交 `2c4f1ea3`;当前分支的船期展示修复已由 `backend-java #649`、`baiyue-firstleg-firstleg #452` 和 `client-web-test #351` 成功部署。真实验证确认改船只更新原柜船期,平台与客户端同步最新船期,柜号和报关资料/回执/完成文件保持不变,证据见 `baiyue-firstleg/reports/platform-and-client-transport-projection-20260927.json`。
|
- 甩柜改配投影提交 `ac3acfce`、`f1218cef`,平台容器读模型修复提交 `2c4f1ea3`;当前分支的船期展示修复已由 `backend-java #649`、`baiyue-firstleg-firstleg #452` 和 `client-web-test #351` 成功部署。真实验证确认改船只更新原柜船期,平台与客户端同步最新船期,柜号和报关资料/回执/完成文件保持不变,证据见 `baiyue-firstleg/reports/platform-and-client-transport-projection-20260927.json`。
|
||||||
- 回执历史投影提交 Firstleg `f6e70ea5`、Admin `ffe91a1`、Client `3e28478` 已成功部署:`backend-java #650`、`baiyue-firstleg-firstleg #453`、`admin-web-test #471`、`client-web-test #353`。健康检查为 `UP`,平台和客户真实接口均返回 `receiptHistory`;证据见 `baiyue-firstleg/reports/customs-receipt-history-20260928.json`。
|
- 回执历史投影提交 Firstleg `f6e70ea5`、Admin `ffe91a1`、Client `3e28478` 已成功部署:`backend-java #650`、`baiyue-firstleg-firstleg #453`、`admin-web-test #471`、`client-web-test #353`。健康检查为 `UP`,平台和客户真实接口均返回 `receiptHistory`;证据见 `baiyue-firstleg/reports/customs-receipt-history-20260928.json`。
|
||||||
- 本轮首次发送批次与确认动作历史提交为 Firstleg `e63cb2b2`、Admin `730defa`、Client `8fd4063`;数据库已核对 `fl_customs_broker_submission` 与 `fl_customs_completion_action_history`。现有完成柜烟测返回 `A0409 当前柜不在报关中`,确认新首次发送接口的状态门禁;证据见 `baiyue-firstleg/reports/customs-send-batch-confirmation-history-20260928.json`。
|
- 本轮首次发送批次与确认动作历史提交为 Firstleg `e63cb2b2`、Admin `730defa`、Client `8fd4063`;数据库已核对 `fl_customs_broker_submission` 与 `fl_customs_completion_action_history`。现有完成柜烟测返回 `A0409 当前柜不在报关中`,确认新首次发送接口的状态门禁;证据见 `baiyue-firstleg/reports/customs-send-batch-confirmation-history-20260928.json`。
|
||||||
|
- 本轮页面回归又修复了一个实际问题:Client 订单列表契约此前没有保留 `taxMode`,导致真实退税订单在“报关资料”页被过滤为 0 个资料包;Client `214fe4f` 已补齐退税字段映射,测试部署 `client-web-test #357` 成功。随后发现船期价格页首次加载重复请求渠道列表,`32c5241` 已收敛初始化监听,`client-web-test #358` 成功。
|
||||||
|
- 后续回归又修复两个页面事实问题:未知海外仓不再把内部仓库 ID当作客户可见名称;报关完成详情改为明确提示“真实报关完税文件已齐全”。同时同步了现有实现对应的离线合同断言,客户端全量 `npm test` 已通过 `398/398`,生产构建通过,提交 `ffbe348`,测试部署 `client-web-test #359` 成功。
|
||||||
|
- 测试环境内置浏览器已按 1920×1080 复验 Admin 与 Client:最新 Admin 柜次详情展示 `LOADED`、8 条仓内节点、PDA 作业摘要 100%、报关“已完成”、国内离仓“已自动离仓”和 7/7 门禁通过;最新 Client 报关资料页展示退税资料包“报关完成”,详情可见回执版本、客户确认状态、真实完税文件和下载入口。Client 船期价格查询以 100 KG/1.2 CBM 真实调用 15 个估价接口并返回 4 个匹配渠道;同一页面初始化只保留 1 次渠道列表请求。
|
||||||
|
- 页面请求量抽样:Admin 货柜详情 13 个 API 请求且无重复;Client 报关资料列表 10 个不同 API 请求,打开两个资料详情各刷新一次资料接口;Client 船期价格初始化 1 次渠道请求,查询阶段 15 次并行估价请求,符合当前“每渠道估价”契约。完整新造数 HTTP 链已解除 PDA 前置阻塞并通过;报告 `baiyue-firstleg/reports/customs-current-20260928.json` 共 543/543 项通过,包含订单、测量、PDA 装柜、混合柜报关资料、回执、客户确认、报关行执行、完税文件、自动离仓和客户端下载。
|
||||||
|
- 2026-09-28 再次复核:测试 API 健康检查、Admin 货柜列表/详情和 Client 报关资料页均返回 HTTP 200;Admin 与 Client 均在 1920×1080 下重新打开验证。已完成柜调用首次发送接口并携带确认参数,服务端返回 `A0409 当前柜不在报关中`,证明已完成柜不会重复创建报关批次;当前无新增数据库记录。客户端全量测试保持 `398/398` 通过,`client-web-test #359` 成功。
|
||||||
|
|
||||||
当前仍需继续补齐的不是客户资料协同、正式申报和海关结果基础链路,而是:
|
当前仍需继续补齐的不是客户资料协同、正式申报和海关结果基础链路,而是:
|
||||||
|
|
||||||
- 报关行回执的外部确认/接收回执、下载凭证和回执轮次的更细对象;首次发送批次与客户确认动作历史已经落地;
|
- 报关行回执的外部确认/接收回执、下载凭证和回执轮次的更细对象;首次发送批次与客户确认动作历史已经落地;
|
||||||
- 更复杂的结果凭证上传和补资料专项门禁;
|
- 更细的报关行接收回执和下载凭证;海关异常继续按人工理由和备注处理,不新增自动结果凭证门禁;
|
||||||
- 将正式申报/海关结果继续扩展到待发区、送港、进港和实际开航的只读投影,保持运输线独立;F23.3 的船期投影已完成真实 HTTP 核验。
|
- 将正式申报/海关结果继续扩展到待发区、送港、进港和实际开航的只读投影,保持运输线独立;F23.3 的船期投影已完成真实 HTTP 核验。
|
||||||
|
|
||||||
开发时不要只增加页面节点文案,也不要把旧的 `COMPLETED` 直接当成客户确认、正式申报或海关放行。
|
开发时不要只增加页面节点文案,也不要把旧的 `COMPLETED` 直接当成客户确认、正式申报或海关放行。
|
||||||
@@ -96,7 +101,10 @@
|
|||||||
- 每个客户都能完成“资料上传 → 报关行回执 → 客户确认/打回”,资料和完成文件保留版本,客户范围严格隔离。
|
- 每个客户都能完成“资料上传 → 报关行回执 → 客户确认/打回”,资料和完成文件保留版本,客户范围严格隔离。
|
||||||
- 首次发送报关行必须生成独立业务批次;客户每次确认或打回都保留对应回执版本、操作人、时间和原因。
|
- 首次发送报关行必须生成独立业务批次;客户每次确认或打回都保留对应回执版本、操作人、时间和原因。
|
||||||
- 未全部客户确认时不能完成整柜报关;正式申报批次、海关回填结果和报关单号已独立建模,不能把客户确认或完税文件上传直接当作海关放行事实。
|
- 未全部客户确认时不能完成整柜报关;正式申报批次、海关回填结果和报关单号已独立建模,不能把客户确认或完税文件上传直接当作海关放行事实。
|
||||||
- 海关查验、不查验放行、扣货和其他结果已落地为批次下独立事实;后续只需补更复杂的凭证上传和补资料专项验收。
|
- 海关查验、不查验放行、扣货、补资料和其他结果已落地为批次下独立事实;平台人员人工选择理由,选择“其他”时填写备注并人工处理异常。
|
||||||
- 报关完成后才能进入待发区;进入待发区后才推进送港/进港。甩柜/改配只修改原柜船名、航次和船期并保留历史,不能伪造或覆盖报关资料、回执和客户确认。
|
- 报关完成后才能进入待发区;进入待发区后才推进送港/进港。甩柜/改配只修改原柜船名、航次和船期并保留历史,不能伪造或覆盖报关资料、回执和客户确认。
|
||||||
- 重复请求、版本冲突、换柜、部分装柜箱数展示和权限越界都有明确结果和审计记录;部分装柜的后续处理在线下完成。
|
- 重复请求、版本冲突、换柜、部分装柜箱数展示和权限越界都有明确结果和审计记录;部分装柜的后续处理在线下完成。
|
||||||
- 完成代码联调后,再回写 F22 和阶段三的实现状态;当前真实 HTTP 已通过,后续仍按 `COMPLETED`、海关放行和运输节点分别验收。
|
- F22 和阶段三的实现状态已按当前代码和真实 HTTP 结果回写;后续继续按 `COMPLETED`、海关放行和运输节点分别验收,不把报关完成合并成海运或尾程完成。
|
||||||
|
|
||||||
|
- 2026-09-29:补齐测试环境专用 `CN_FIRSTLEG_PDA_OPERATOR` 账号并验证登录,重新执行 `phase3-container-customs` 正式 HTTP 造数链;订单、测量、PDA 领取/扫码/提交、`LOADED` 硬门禁、混合柜 BUY/TAX 隔离、首次发送批次、回执幂等、客户确认、报关行执行、完税文件、`COMPLETED`、自动离仓和 Client 完税文件下载共 543/543 通过,348 个唯一 HTTP 请求,0 个 coverage gap。报告:`baiyue-firstleg/reports/customs-current-20260928.json`。
|
||||||
|
- 2026-09-29:继续执行头程运输节点造数链;订舱、港务船期、甩柜改船、拖车预约、报关完成后的待发区、国内离仓门禁和船司查询策略共 1036/1036 通过,641 个唯一 HTTP 请求,0 个阻塞缺口。甩柜只更新原柜船期,柜次及报关事实不变。报告:`baiyue-firstleg/reports/transport-current-20260929.json`;剩余 4 个缺口均为非阻塞的 COSCO/ZIM 外部接入或 Android 真机验收。
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 头程到尾程分阶段流程
|
# 头程到尾程分阶段流程
|
||||||
|
|
||||||
本目录是端到端流程的分段查找入口。流程基线已确认,当前用于收尾变更;其中阶段三的报关协同代码尚未完成。总览和节点关系看[《头程到尾程流程节点梳理》](../头程到尾程流程节点梳理.md),字段、页面操作、权限和异常细节在对应阶段文件维护。
|
本目录是端到端流程的分段查找入口。F01-F40 流程基线已确认,当前用于全流程收尾变更;阶段三报关协同代码已接入并通过真实 HTTP 验收。总览和节点关系看[《头程到尾程流程节点梳理》](../头程到尾程流程节点梳理.md),字段、页面操作、权限和异常细节在对应阶段文件维护。
|
||||||
|
|
||||||
## 三大业务块与六个分段
|
## 三大业务块与六个分段
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
- 阶段三的装柜完成(`LOADED`)后先完成退税报关;报关完成后货柜进入待发区,再推进送港运输。甩柜/改配只影响船期,不改变已完成报关事实。
|
- 阶段三的装柜完成(`LOADED`)后先完成退税报关;报关完成后货柜进入待发区,再推进送港运输。甩柜/改配只影响船期,不改变已完成报关事实。
|
||||||
- 报关协同必须经过“客户资料 → 报关行回执 → 客户确认/打回重做”,柜内所有客户确认后才提交整柜资料并正式申报。
|
- 报关协同必须经过“客户资料 → 报关行回执 → 客户确认/打回重做”,柜内所有客户确认后才提交整柜资料并正式申报。
|
||||||
- 送港完成、进港或甩柜都不等于海运中;承运船舶实际开航后才进入阶段四的海运节点。
|
- 送港完成、进港或甩柜都不等于海运中;承运船舶实际开航后才进入阶段四的海运节点。
|
||||||
- 阶段四形成海外接柜输入后,阶段五负责实收、入库和库存,阶段六负责出库、派送、签收和异常回写。
|
- 阶段四形成海外接柜输入后,阶段五负责实收、入库和库存,阶段六负责出库、派送、签收和异常回写。F01-F37 以海外出库为阶段性业务终点,F38-F40 继续完成派送、签收和国内最终回写。
|
||||||
|
|
||||||
## 旧文档的使用范围
|
## 旧文档的使用范围
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
# 头程到尾程流程节点梳理
|
# 头程到尾程流程节点梳理
|
||||||
|
|
||||||
> **当前用途:收尾变更的流程入口。** 整体流程基线已确认,报关协同代码尚未完成;本文件只保留三大业务块、关键节点和节点之间的关系,便于查找和修改。报关开发请看[报关代码开发交接清单](头程到尾程/报关代码开发交接清单.md),历史开发规划、进度、门禁和评审不在这里继续维护。
|
> **当前用途:全流程收尾变更的流程入口。** F01-F40 的业务基线已经确认,报关协同代码已接入并通过测试环境验收;本文件只保留三大业务块、关键节点和节点之间的关系,便于查找和修改。报关实现细节请看[报关代码开发交接清单](头程到尾程/报关代码开发交接清单.md),历史开发规划、进度、门禁和评审不在这里继续维护。
|
||||||
>
|
>
|
||||||
> **维护原则:** 客户看到的是进度投影,后台看到的是业务对象节点,明细节点记录真实操作和结果。三者使用同一组业务事实,不另建一套客户状态。
|
> **维护原则:** 客户看到的是进度投影,后台看到的是业务对象节点,明细节点记录真实操作和结果。三者使用同一组业务事实,不另建一套客户状态。
|
||||||
|
|
||||||
@@ -42,10 +42,10 @@
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| F01-F07 | 头程下单 | 待下单、审核中、已审核 | 企业、订单、审核任务 | 填写、提交、补件、审核、生成入仓单 | 审核通过后进入国内履约 |
|
| F01-F07 | 头程下单 | 待下单、审核中、已审核 | 企业、订单、审核任务 | 填写、提交、补件、审核、生成入仓单 | 审核通过后进入国内履约 |
|
||||||
| F08-F10 | 头程下单 | 待到仓、测量中、待确认 | 入仓单、测量记录 | 到仓收货、扫码、称重、测量、审核 | 形成可排柜的实测数据 |
|
| F08-F10 | 头程下单 | 待到仓、测量中、待确认 | 入仓单、测量记录 | 到仓收货、扫码、称重、测量、审核 | 形成可排柜的实测数据 |
|
||||||
| F11-F13 | 头程下单 | 费用待确认、待组托、待分柜 | 费用版本、确认记录、托盘 | 计费、推送、客户确认、组托/封托 | 费用不阻断主链;装柜完成时未确认的当前有效费用按系统默认确认留痕 |
|
| F11-F13 | 头程下单 | 费用待确认、国内扣货/解除、待组托、待分柜 | 费用版本、确认记录、HOLD 记录、托盘 | 计费、推送、客户确认、国内扣货/解除、组托/封托 | 费用确认不阻断主链;国内扣货单独控制作业门禁;装柜不能代替客户确认费用 |
|
||||||
| F14-F20 | 海运(货柜) | 待分柜、订舱中、装柜准备/进行中 | 柜次、装柜计划、拖车任务、拣货任务 | 分柜、订舱、排车、拣货、拍照、铅封、数量核对 | 通过装柜门禁后才能完成装柜 |
|
| F14-F20 | 海运(货柜) | 待分柜、订舱中、装柜准备/进行中 | 柜次、装柜计划、拖车任务、拣货任务 | 分柜、订舱、排车、拣货、拍照、铅封、数量核对 | 通过装柜门禁后才能完成装柜 |
|
||||||
| F21 | 海运(货柜) | 国内已装柜 | 装柜任务已完成 | 实际柜号、实装数量、装柜证据确认 | 产生 `LOADED`;完成报关后才进入待发区 |
|
| F21 | 海运(货柜) | 国内已装柜 | 装柜任务已完成 | 实际柜号、实装数量、装柜证据确认 | 产生 `LOADED`;完成报关后才进入待发区 |
|
||||||
| F22 | 海运(货柜) | 报关确认中、待补资料、已提交报关 | 客户报关案例、报关批次 | 收集资料、发报关行、接收回执、客户确认或打回、重新上传和重发 | **流程已确认、代码未完成**;柜内所有客户确认后,才能提交整柜资料并正式申报;客户确认不等于海关放行 |
|
| F22 | 海运(货柜) | 报关确认中、待补资料、已提交报关 | 客户报关案例、报关批次 | 收集资料、发报关行、接收回执、客户确认或打回、重新上传和重发 | **已实现并通过真实 HTTP 验收**;柜内所有客户确认后,才能提交整柜资料并正式申报;客户确认不等于海关放行 |
|
||||||
| F23 | 海运(货柜) | 待发区、送港中、已进港、待开船、已甩柜 | 待发区、送港/拖车任务、港口和船次事实 | 报关完成后入待发区、离仓、送港、进港、甩柜、改配 | 报关完成是进入待发区的门槛;甩柜/改配只改变运输船期,不重做已完成报关 |
|
| F23 | 海运(货柜) | 待发区、送港中、已进港、待开船、已甩柜 | 待发区、送港/拖车任务、港口和船次事实 | 报关完成后入待发区、离仓、送港、进港、甩柜、改配 | 报关完成是进入待发区的门槛;甩柜/改配只改变运输船期,不重做已完成报关 |
|
||||||
| F24 | 海运(货柜) | 海运中 | 船次实际状态 | 承运船舶实际开航、船期回写 | 只有实际开航后进入海运节点 |
|
| F24 | 海运(货柜) | 海运中 | 船次实际状态 | 承运船舶实际开航、船期回写 | 只有实际开航后进入海运节点 |
|
||||||
| F25-F27 | 海运(货柜) | 目的港处理中、待海外接柜 | 目的港清关/提柜、尾程订单、入仓计划 | 清关、提柜、创建尾程计划 | 形成海外接柜输入,不等于已经入库 |
|
| F25-F27 | 海运(货柜) | 目的港处理中、待海外接柜 | 目的港清关/提柜、尾程订单、入仓计划 | 清关、提柜、创建尾程计划 | 形成海外接柜输入,不等于已经入库 |
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
|
|
||||||
### 2. 费用确认不阻断装柜主链
|
### 2. 费用确认不阻断装柜主链
|
||||||
|
|
||||||
费用确认是头程下单块中的并行事项。客户未确认时可以继续排柜、拣货和装柜;装柜完成后仍未确认的当前有效费用按系统默认确认,并保留“系统默认确认”的来源和时间。系统默认确认不能用于报关资料的客户确认。
|
费用确认是头程下单块中的并行事项。客户未确认时可以继续排柜、拣货和装柜。按阶段二及 Firstleg 当前服务指引,装柜完成可以触发平台费用确认与发布,但不能代替客户主动确认;客户已确认且本票装柜完成时才最终冻结。费用确认与报关资料的客户确认分别记录。
|
||||||
|
|
||||||
### 3. 异常附着在主节点上
|
### 3. 异常附着在主节点上
|
||||||
|
|
||||||
|
|||||||
+38
-150
@@ -1,159 +1,47 @@
|
|||||||
# 开发/测试环境 Jenkins API 自动部署指南
|
# TEST 环境 Jenkins 部署指南
|
||||||
|
|
||||||
> 最后核对:2026-08-25
|
更新日期:2026-09-29。本指南描述唯一 TEST 单机目标;仓库配置已收敛不表示实际服务器已部署。统一架构切换与验收以[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)为准。
|
||||||
>
|
|
||||||
> 只适用于当前开发、测试阶段。生产环境启用后必须重新收紧权限、轮换并移除开发 Token。
|
|
||||||
|
|
||||||
## 1. 使用场景
|
## 授权与边界
|
||||||
|
|
||||||
本指南用于长时间全量测试或夜间任务。用户在当前对话明确要求“持续修复并部署”“自动部署并测试”或等价表述后,工具可以在本次授权范围内循环执行:
|
默认只做本地修改与离线检查。实际Jenkins构建发布、Nacos发布、SQL和清理分别落实本轮授权范围;本指南不授予持续部署权限。不得读取或覆盖其他任务维护的真实生产/测试凭据。运行事实与本目标不一致时先核对,不自行改名或删除运行环境。
|
||||||
|
|
||||||
`定位失败 → 修改代码 → 本地门禁 → 提交并推送 → API 部署 → 等待终态 → 健康/业务验收 → 继续修复`
|
## 唯一发布入口
|
||||||
|
|
||||||
同一轮任务不需要每次提交或重试都重新询问。以下情况仍必须停下确认:
|
| 对象 | 入口 |
|
||||||
|
|
||||||
- 涉及预发布或生产环境。
|
|
||||||
- 需要执行 SQL、初始化数据库、修改真实数据或清理容器/数据。
|
|
||||||
- 需要跳过测试、停止他人构建或扩大到未授权服务。
|
|
||||||
- 缺少环境凭据,或连续三次遇到同一个外部阻断。
|
|
||||||
|
|
||||||
## 2. 本机一次性配置
|
|
||||||
|
|
||||||
Jenkins API 信息固定保存在以下未提交文件:
|
|
||||||
|
|
||||||
`C:/Users/BY-OY/.codex/jenkins-api.env`
|
|
||||||
|
|
||||||
文件格式:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
JENKINS_URL=https://jenkins.example.com
|
|
||||||
JENKINS_USER=admin
|
|
||||||
JENKINS_API_TOKEN=replace-with-current-development-token
|
|
||||||
DEV_GATEWAY_URL=https://dev-api.example.com
|
|
||||||
TEST_GATEWAY_URL=https://test-api.example.com
|
|
||||||
```
|
|
||||||
|
|
||||||
工具直接读取该文件,不把 Token 输出到 commentary、最终回复、命令日志或仓库。使用 API Token 的 Jenkins 请求不需要 CSRF Crumb。
|
|
||||||
|
|
||||||
连通性检查:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
|
|
||||||
"${JENKINS_URL%/}/api/json?tree=nodeName,mode"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. Job 对照
|
|
||||||
|
|
||||||
| 环境 | 后端总控 | Admin | Client | 后端分支 | 下游前缀 |
|
|
||||||
|---|---|---|---|---|---|
|
|
||||||
| 开发 | `backend-java-dev` | `admin-web-dev` | `client-web-dev` | `dev` | `baiyue-firstleg-dev-` |
|
|
||||||
| 测试 | `backend-java` | `admin-web-test` | `client-web-test` | `test` | `baiyue-firstleg-` |
|
|
||||||
|
|
||||||
后端可部署服务:
|
|
||||||
|
|
||||||
`gateway`、`gateway-overseas`、`auth`、`iam`、`firstleg`、`finance`、`order`、`warehouse`、`file`、`print`、`integration-service`、`lastleg-service`、`warehouse-overseas-service`、`event-bridge-service`、`audit-service`。海外安全投影随 `lastleg-service` 部署,不再有独立 Job。
|
|
||||||
|
|
||||||
正常从总控 Job 发起。只有重跑同一提交的单个失败服务时,才直接触发下游 Job。
|
|
||||||
|
|
||||||
## 4. API 触发
|
|
||||||
|
|
||||||
### 4.1 前端
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsS -X POST \
|
|
||||||
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
|
|
||||||
-D build.headers -o /dev/null \
|
|
||||||
"${JENKINS_URL%/}/job/admin-web-dev/build"
|
|
||||||
```
|
|
||||||
|
|
||||||
按目标环境和应用替换 Job 名称。
|
|
||||||
|
|
||||||
### 4.2 后端
|
|
||||||
|
|
||||||
开发环境选择两个服务的示例:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsS -X POST \
|
|
||||||
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
|
|
||||||
-D build.headers -o /dev/null \
|
|
||||||
--data-urlencode 'BUILD_MODE=SELECT' \
|
|
||||||
--data-urlencode 'SERVICE_GATEWAY_OVERSEAS=true' \
|
|
||||||
--data-urlencode 'SERVICE_LASTLEG=true' \
|
|
||||||
--data-urlencode 'ENVIRONMENT=development' \
|
|
||||||
--data-urlencode 'DEPLOY=true' \
|
|
||||||
--data-urlencode 'SKIP_TESTS=false' \
|
|
||||||
--data-urlencode 'EVENT_BRIDGE_REGION=BOTH' \
|
|
||||||
--data-urlencode 'DOWNSTREAM_JOB_PREFIX=baiyue-firstleg-dev-' \
|
|
||||||
"${JENKINS_URL%/}/job/backend-java-dev/buildWithParameters"
|
|
||||||
```
|
|
||||||
|
|
||||||
规则:
|
|
||||||
|
|
||||||
- 日常优先 `AUTO`;明确修复单个或少量服务时使用 `SELECT`。
|
|
||||||
- `SELECT` 只把目标 `SERVICE_*` 设为 `true`,其余保持 `false`。
|
|
||||||
- `ALL` 只用于用户明确授权的全量部署。
|
|
||||||
- 开发环境固定 `ENVIRONMENT=development`;测试固定 `ENVIRONMENT=test`。
|
|
||||||
- 开发/测试默认 `DEPLOY=true`、`SKIP_TESTS=false`。
|
|
||||||
- 事件桥默认 `BOTH`;单区故障重跑才使用 `CN` 或 `OVERSEAS`。
|
|
||||||
- 不在 API 参数中传密码、数据库凭据或服务 Token。
|
|
||||||
|
|
||||||
## 5. 自动等待终态
|
|
||||||
|
|
||||||
触发响应的 `Location` 是队列地址:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
QUEUE_URL="$(awk 'BEGIN{IGNORECASE=1} /^Location:/{gsub("\r",""); print $2}' build.headers)"
|
|
||||||
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
|
|
||||||
"${QUEUE_URL%/}/api/json?tree=id,why,cancelled,executable[number,url]"
|
|
||||||
```
|
|
||||||
|
|
||||||
出现 `executable.url` 后,将其作为 `BUILD_URL`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
|
|
||||||
"${BUILD_URL%/}/api/json?tree=number,building,result,url,duration,estimatedDuration"
|
|
||||||
```
|
|
||||||
|
|
||||||
每 5–10 秒轮询一次。只有 `building=false` 且 `result=SUCCESS` 才成功;进入队列、拿到构建号或 HTTP POST 成功都不算完成。后端总控还必须确认每个下游 Job 都是 `SUCCESS`。
|
|
||||||
|
|
||||||
失败时读取:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
|
|
||||||
"${BUILD_URL%/}/consoleText"
|
|
||||||
```
|
|
||||||
|
|
||||||
删除本次产生的临时 `*.headers` 文件,不提交。
|
|
||||||
|
|
||||||
## 6. 夜间自动闭环
|
|
||||||
|
|
||||||
1. 记录目标环境、服务和远端 commit。
|
|
||||||
2. 运行直接受影响的本地测试;签名变化必须编译测试源码。
|
|
||||||
3. 只提交当前修复文件并推送目标分支。
|
|
||||||
4. 用 API 触发对应 Job,保存队列 URL、构建 URL 和构建号。
|
|
||||||
5. 等待总控及全部下游进入终态。
|
|
||||||
6. 失败时读取第一个有效错误,修改后使用新 commit 再部署。
|
|
||||||
7. 网络抖动、镜像拉取等瞬时基础设施错误允许同一提交重试,最多两次。
|
|
||||||
8. 部署成功后检查 Gateway `/actuator/health`,再执行本轮真实 API/全量测试。
|
|
||||||
9. 全部通过后汇总 commit、构建号、服务结果和验收结果。
|
|
||||||
|
|
||||||
不要因为某个服务失败就盲目重跑全量;优先修复并只重跑失败服务。部署脚本会在新容器不健康时自动回滚,任务仍视为失败。
|
|
||||||
|
|
||||||
## 7. 快速故障判断
|
|
||||||
|
|
||||||
| 现象 | 处理 |
|
|
||||||
|---|---|
|
|---|---|
|
||||||
| `401` | 检查本机 API Token 和反向代理 `Authorization` 头 |
|
| 后端总控 | `backend-java`,仓库 `baiyue-firstleg/Jenkinsfile` |
|
||||||
| `403` | 检查 Job Read/Build 权限;不要关闭 CSRF |
|
| 后端单服务 | `baiyue-firstleg-<module>`,`Jenkinsfile.service` |
|
||||||
| `400` | 参数名或 Choice 值与当前 Job 不一致 |
|
| 构建/部署节点 | `java-builder` / 同机 `java-test` |
|
||||||
| 队列长期等待 | 查询队列 `why`,检查节点、执行器和部署锁 |
|
| 环境凭据 | Jenkins Secret File `firstleg-test-env`,真实值不入库 |
|
||||||
| Maven/测试失败 | 修复代码并产生新 commit,不跳过测试 |
|
| 服务与镜像列表 | [service-map.yml](../baiyue-firstleg/deploy/service-map.yml) |
|
||||||
| 容器不健康 | 读取 Job 自动采集的容器日志和回滚结果 |
|
| Compose | [docker-compose.yml](../baiyue-firstleg/deploy/docker-compose.yml),项目 `firstleg-test` |
|
||||||
| 镜像被其他任务覆盖 | 核对同服务部署锁和实际运行镜像标签 |
|
| 环境模板 | [.env.test.example](../baiyue-firstleg/deploy/env/.env.test.example) |
|
||||||
| 总控成功但下游失败 | 整体仍按失败处理,只重跑失败服务 |
|
| Nacos | [config/nacos/test](../baiyue-firstleg/config/nacos/test/README.md),14个Data ID、一个实际Namespace ID |
|
||||||
|
| 执行顺序与恢复 | [TEST单机部署执行清单](../baiyue-firstleg/deploy/TEST单机部署执行清单.md) |
|
||||||
|
|
||||||
## 8. 完成记录
|
保留13个服务:gateway、auth、iam、order、firstleg、finance、warehouse、warehouse-overseas-service、lastleg-service、file、print、audit-service、integration-service。Gateway Overseas、两区Event Bridge不在新发布清单。停旧服务必须等统一认证、直接投递、撤销和四端切换验证完成;源码退役不等于获准停止当前服务。
|
||||||
|
|
||||||
最终只需记录:环境、Job、服务、分支、commit、Jenkins 构建号、最终结果、健康检查、业务验收及剩余阻断。不得输出 Token、Cookie、Jenkins Credential 或环境文件内容。
|
旧开发/生产Job不再匹配当前流水线,不能借环境参数使本版本执行生产部署。已有其他环境应由其独立明确授权任务处理,不在本次TEST发布中操作。
|
||||||
|
|
||||||
参考:[Jenkins Remote Access API](https://www.jenkins.io/doc/book/using/remote-access-api/)、[Jenkins CSRF Protection](https://www.jenkins.io/doc/book/security/csrf-protection/)。
|
## 参数与门禁
|
||||||
|
|
||||||
|
总控支持AUTO、SELECT、ALL。AUTO保留失败服务重试与直接依赖识别;架构首次切换使用审核后的完整匹配发布清单,不以AUTO遗漏服务。ENVIRONMENT仅test,下游前缀仅baiyue-firstleg-。DEPLOY默认false;IMAGE_REPOSITORY必须替换为已核镜像仓库,DOCKER_BASE_IMAGE由构建节点可访问的Java17镜像提供。不得将凭据拼入参数、URL或日志。
|
||||||
|
|
||||||
|
默认执行Maven测试;仅明确选择SKIP_TESTS时跳过执行,仍编译测试源码。总控先统一测试,再向固定commit的单服务任务传递跳过重复执行。发布前还须完成网关路由、部署拓扑、失败回滚和受影响前端合同。离线检查不能证明镜像健康或HTTP闭环。
|
||||||
|
|
||||||
|
单服务任务在取目标节点执行器前锁定对应服务,目标节点通过同一env文件拉镜像并更新容器。没有HEALTHCHECK、启动失败、不健康、退出或超时均判失败。只有同协议同Schema版本才可显式启用ALLOW_SAME_CONTRACT_ROLLBACK;架构切换保持false,恢复原则见执行清单。
|
||||||
|
|
||||||
|
## 配置与端侧
|
||||||
|
|
||||||
|
容器共用firstleg-test-network;同网络Web Nginx使用http://gateway:9000。Gateway宿主机发布仅127.0.0.1,业务服务只内部expose。Auth使用http://auth:9100,不能把Nacos应用名当Docker DNS。宿主机中间件通过host.docker.internal访问,不能使用容器localhost。
|
||||||
|
|
||||||
|
所有服务使用同一Nacos Namespace ID/Group、Redis DB与会话前缀。Auth独占签名私钥;JWKS和内部会话验证共用Auth。EVENT_OPERATIONS_TOKEN独立于内部业务令牌,留空禁用运维操作。现有文件卷和非桥业务MQ保留,topic/group使用test-前缀。
|
||||||
|
|
||||||
|
Admin与Client各自Compose项目共接后端网络,发布必须给出CLIENT_WEB_URL/VITE_ADMIN_WEB_ORIGIN;两个PDA保留独立产物及仓绑定。域名、Namespace ID、MQ范围、数据卷和主机容量必须据实际清单核实,不能用模板默认值充当验收。
|
||||||
|
|
||||||
|
## 发布与验收
|
||||||
|
|
||||||
|
按执行清单记录镜像、配置、SQL与四端版本,在停写窗口发布完整匹配版本。SQL不由Compose/Jenkins自动运行,初始化脚本仅接受两份显式审核的空库基线并受授权开关保护。禁止整机清空Redis/MQ/文件。
|
||||||
|
|
||||||
|
启动就绪后先验证统一登录/撤销/隔离/仓绑定、资源查询和文件,再用新造数据验证装柜至尾程、资金指令结果回传及故障恢复。真实API通过后还需页面/PDA验收。未部署、未验证项目必须明确标记;不能以Job成功替代整条业务链完成。
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# 测试环境单机部署与配置契约
|
||||||
|
|
||||||
|
更新日期:2026-09-29。当前只有 test,没有开发/生产环境。本文定义目标部署、切换与验收;具体路由、认证、投递契约唯一见[统一认证与服务通信契约](统一认证与服务通信契约.md)。
|
||||||
|
|
||||||
|
状态:目标已确认,统一 Gateway/Token、可靠直接投递、单 TEST Compose/Nacos 与四端统一入口已进入源码并完成分批本地验证,后端全量 Maven 回归已通过(4149项,12项跳过,0失败/错误)。尚未发布到测试环境;运行服务器、Nacos 发布值、主机资源和真实 MySQL 故障恢复尚未验证。
|
||||||
|
## 结论与范围
|
||||||
|
|
||||||
|
按“头程和海外仓不再分区域部署、所有服务同机运行、取消独立事件接收服务与海外网关”设计。这里将“事件接收”对应为当前 `event-bridge-service`,不推定要删除业务通知、异步任务或消息队列。
|
||||||
|
|
||||||
|
建议目标:一个 Gateway、一套 Auth/IAM 登录与权限体系、一个测试 Nacos 命名空间和一套测试内部容器网络。保留 Firstleg、Lastleg、Warehouse、Warehouse Overseas 等业务服务,各自拥有数据表与业务规则。同机可以共用 MySQL 实例,继续按服务分 Schema;不要求合并为一个数据库或一个 Java 进程。
|
||||||
|
|
||||||
|
最终移除 `gateway-overseas` 与 `event-bridge-service` 部署单元及其区域分支。服务名称中的海外业务含义可以保留;仓库类型、仓管角色、仓绑定和客户数据隔离仍有业务用途。
|
||||||
|
|
||||||
|
## 测试环境目标部署清单
|
||||||
|
|
||||||
|
| 类别 | 目标 |
|
||||||
|
|---|---|
|
||||||
|
| 环境 | 仅 test,所有服务同一台宿主机 |
|
||||||
|
| 用户端 | Admin、Client、国内 PDA、海外 PDA 共用一个业务 API 入口;页面和作业职责保留 |
|
||||||
|
| 入口 | Nginx/反向代理接统一 Gateway,业务内部端口不作为客户端访问入口 |
|
||||||
|
| 认证 | Auth、IAM、统一 JWT 与 Redis 会话,按平台/客户/PDA 校验权限 |
|
||||||
|
| 业务 | Order、Firstleg、Lastleg、Warehouse、Warehouse Overseas、Finance |
|
||||||
|
| 公共能力 | File、Print、Audit、Integration 按现有职责保留 |
|
||||||
|
| 配置与发现 | 一套 Nacos,使用实际 Namespace ID 的单一测试命名空间,不再分 test-cn/test-overseas |
|
||||||
|
| 数据与缓存 | 一套测试 MySQL 实例,按服务分 Schema;统一可访问的测试 Redis,保留必要键隔离 |
|
||||||
|
| 消息 | 保留现有 RocketMQ 用于导出、通知和审计等已发现用途 |
|
||||||
|
| 服务协同 | 同机内部调用;需要可靠交付的业务采用本地事务记录加直接投递和消费幂等 |
|
||||||
|
| 退出部署 | gateway-overseas、CN/OVERSEAS 两个 Event Bridge 实例及专用配置 |
|
||||||
|
|
||||||
|
服务名、Schema、端口、数据卷和实际中间件配置在改造前做一次清单核对;当前表是目标部署结构,不是对服务器现状的确认。旧 development/production 配置不再作为本次发布入口,也不要求新建对应环境。
|
||||||
|
|
||||||
|
## 分批实施与交付门槛
|
||||||
|
|
||||||
|
| 批次 | 工作 | 完成依据 |
|
||||||
|
|---|---|---|
|
||||||
|
| 0:文档与基线 | 确认仅 test 的目标、唯一接口路径、统一认证、直接投递职责;列出当前配置与服务清单 | 新目标、当前实现、待办三者明确区分 |
|
||||||
|
| 0A:资金消费前置修复 | 区分临时执行失败与最终业务拒绝;补齐并发 Inbox 抢占后的摘要校验和一致结果处理 | 临时故障原事件重试、并发同 hash/异 hash、执行成功后结果保存失败的恢复验证通过;修复规则见统一认证与服务通信契约;本地已通过,实库待验证 |
|
||||||
|
| 1:入口与认证 | Gateway 接入全部业务;Auth/common-security/海外服务统一认证;各端共用入口;解决仓库路由冲突 | 本地编译、认证测试、路由合同及受影响前端测试通过 |
|
||||||
|
| 2:业务通信 | 替换装柜、船节点、卸柜、暂扣、派送、费用和资金链;补齐直接投递重试及失败处置 | 各链路有直接消费者,成功确认、重复投递和故障恢复测试通过 |
|
||||||
|
| 3:部署收敛 | 单套 test Compose/Nacos/Jenkins;清理两个废弃服务和专用配置、SQL 初始化引用、安全投影依赖 | 构建与配置合同通过;形成唯一测试发布清单及启动依赖 |
|
||||||
|
| 4:测试环境验证 | 发布一致的新版本,以新造数据执行 API 全链路和各端实际操作 | 下表业务验收全部通过,保留报告及未通过项 |
|
||||||
|
|
||||||
|
改造批次可以分别完成代码检查;仅入口批次完成时,不把测试环境视为已跑通。正式测试部署须使用接口、认证、通信与配置相互匹配的一组版本,避免先停 Bridge 导致现有业务失联。
|
||||||
|
|
||||||
|
本地编译和离线检查只是开发工具使用,不代表存在独立“开发环境”。最低检查包括相关 Maven 测试编译/测试、网关路由与拓扑合同、前端类型检查及受影响测试;不以构建成功代替测试环境闭环通过。
|
||||||
|
|
||||||
|
## 测试环境跑通的验收标准
|
||||||
|
|
||||||
|
下表是测试环境验收标准;本地实现与离线测试不代表环境验收,当前所有环境验收项均待验证。
|
||||||
|
|
||||||
|
| 验收项 | 操作与预期 |
|
||||||
|
|---|---|
|
||||||
|
| 部署与发现 | 所有保留服务启动健康,统一命名空间中可发现;客户端无需访问海外 Gateway 或 Bridge |
|
||||||
|
| 登录与权限 | Admin、Client、两类 PDA 使用统一认证;刷新有效、退出后失效;停用账号/客户和越权访问被拒绝 |
|
||||||
|
| PDA 仓绑定 | 未绑定拒绝作业,绑定仓限制正确,换仓后旧会话失效 |
|
||||||
|
| 仓库路由 | 仓库主档、库位、托盘访问正确服务,原重复前缀不再造成路由歧义 |
|
||||||
|
| 订单到装柜 | 新造客户与订单走审核、入仓、测量、分柜和装柜;完成后正确生成尾程数据 |
|
||||||
|
| 海外履约 | 船节点同步、接柜、卸柜、入仓、库存、排车、出库、派送形成闭环;签收按来源回写 Firstleg/Order |
|
||||||
|
| 状态协同 | 暂扣/解除、卸柜事实、分单签收作用于正确单据,不误推进同柜或同车其他订单 |
|
||||||
|
| 费用与资金 | 费用准确入 Finance;资金指令与结果对应;重复请求不重复入账、冻结或扣款 |
|
||||||
|
| 可靠性 | 消费服务短时停止、重启、响应超时、重复和乱序投递后可恢复,失败可查且可重试,无永久丢单 |
|
||||||
|
| 公共能力 | 文件上传下载、标签打印、异步导出、消息通知、审计正常 |
|
||||||
|
| 客户与作业界面 | Admin/Client 和 PDA 实际操作完成核心流程;HTTP 通过不能替代页面/设备验证 |
|
||||||
|
|
||||||
|
每次验收记录版本、测试数据业务编号、覆盖场景、结果及错误诊断信息。修复失败项后执行受影响回归,再给出整体是否跑通的结论。
|
||||||
|
|
||||||
|
### D. 唯一测试环境的整体切换与失败恢复
|
||||||
|
|
||||||
|
本次采用测试停机窗口一次切换,允许测试数据按明确范围重建,不做新旧协议并行。实际部署、SQL、清理操作不在本文编写过程中执行。
|
||||||
|
|
||||||
|
| 顺序 | 操作 | 放行条件/记录 |
|
||||||
|
|---|---|---|
|
||||||
|
| D0 版本准备 | 记录各后端/前端/PDA 仓库提交、镜像 tag/digest、APK/WGT 版本、Nacos 配置版本与 SQL 基线 | 各端对应同一架构契约;本地检查通过 |
|
||||||
|
| D1 运行清单 | 列出当前容器、Compose 项目、网络、服务注册、Nacos Data ID/Group/Namespace、Redis DB/key、MQ topic/group、DB/文件卷引用 | 填实际标识,不输出凭据;确认主机容量和端口 |
|
||||||
|
| D2 停止写入 | 公告测试窗口、停止正在进行的验收/造数、阻断业务写入;停止旧业务容器、Relay 和相关消费任务 | 没有旧进程继续发消息、续写数据库或向旧 Nacos 注册 |
|
||||||
|
| D3 应用基线与配置 | 按逐项对象清单处理测试业务数据/旧投递、会话、必要 MQ 测试消息与文件引用;发布统一 test Nacos/Compose 配置 | 数据一致;不整机清空 Redis/MQ/文件,不触碰不在清单中的资源 |
|
||||||
|
| D4 启动新服务 | 中间件健康 → IAM/Auth 及公共能力 → 所有业务消费者与生产者 → Gateway → 前端;写入口保持关闭 | 健康检查通过且消费者就绪;无循环依赖导致的启动等待;旧网关/Bridge 不再启动 |
|
||||||
|
| D5 端侧切换 | 发布 Admin/Client 新构建,更新两类 PDA,清除旧登录态后重新登录 | 验收设备构建版本与配置正确;原生地址不再指向海外入口 |
|
||||||
|
| D6 冒烟 | 统一登录、主档/资源查询、越权拒绝、文件上传,加一条装柜→尾程链与一条资金指令→结果回传 | 无路由误投、认证失效或严重业务错误 |
|
||||||
|
| D7 完整验收 | 开放本轮验收写入,按前述矩阵新造数据执行完整 API、页面、PDA 及故障恢复 | 所有阻断项关闭才声明跑通 |
|
||||||
|
| D8 清理退役资源 | 核对旧容器、注册、配置及专用卷/库引用,形成明确清理清单 | 新链路通过、没有残余调用;删除动作单独按范围执行 |
|
||||||
|
|
||||||
|
启动顺序是依赖就绪原则,不允许写死为某服务必须业务调用另一未启动服务后才能健康。生产端 Outbox 可先记录并有限重试,不能在业务消费者启动前产生验收写入;冒烟前以实际健康状态确认。
|
||||||
|
|
||||||
|
停止条件:认证/客户隔离错误、资金重复执行、必需消费者不可达、投递无法恢复、数据库基线不匹配,任何一项即关闭测试写入并停止本轮验收,不用跳过场景换取整体通过。
|
||||||
|
|
||||||
|
失败恢复默认选择:保留故障证据,环境继续停写,修复新架构后用匹配版本重新部署并重建本轮失败测试数据。只有确需恢复原测试工作时,整体恢复旧镜像/前端/PDA、旧 Nacos/Compose 和匹配旧 Schema 基线,清理新旧会话及消息交叉引用;不恢复已经放弃的测试业务数据。单服务镜像回滚仅适用于确认契约和 Schema 未变的情况,不能代替本次架构整体恢复。
|
||||||
|
|
||||||
|
待部署准备时填写的运行值:测试窗口、发布清单、实际 Namespace ID、Data ID/Group、域名与端口、Redis DB/key 前缀、MQ 范围、SQL/卷操作清单、主机资源预算、验收数据编号。不得用猜测值替代运行检查;这些值未填写不进入 D2。
|
||||||
|
|
||||||
|
|
||||||
|
## 基线与范围
|
||||||
|
|
||||||
|
测试数据可以按明确对象重建,不设计存量迁移、双写、旧协议兼容或生产发布。本地编译不是独立开发环境。执行初始化、清理和部署前落实具体对象清单与适用授权,本契约不表示这些动作已执行。
|
||||||
|
|
||||||
|
配置收敛必须覆盖 Compose、Jenkins、deploy/service-map.yml、发布脚本、Nacos Data ID/Group/Namespace、前端代理与构建变量、PDA 地址、SQL 初始化引用、服务发现和健康检查。容器内不能用 localhost 代替其他服务名。保留文件数据卷及仍被导出/通知/审计使用的 RocketMQ。
|
||||||
|
|
||||||
|
不新增中间件,不合并业务服务、Schema、两类 PDA 或领域状态机;旧 development/production 退出当前发布入口,不顺手删除无关历史文件。模块旧指引中双区域部署、双 Token 或必须经海外 Gateway 的强制描述属于迁移前实现,后续实现以本契约和统一认证契约为准,并随对应批次更新模块说明。
|
||||||
|
|
||||||
|
验收记录保存各仓库提交、镜像/配置版本、业务编号、覆盖场景与失败项。本地检查、H2 事务测试与真实 MySQL/HTTP/页面/PDA 验收分别记录,不能互相代替。
|
||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
# 统一认证与服务通信契约
|
||||||
|
|
||||||
|
更新日期:2026-09-29。本文是已确认目标的唯一主契约;当前仅有测试环境,所有服务同机部署。部署与切换见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)。
|
||||||
|
|
||||||
|
状态:整体迁移尚未完成。统一 Token/JWKS/Redis 会话、八类业务事件直连与结构化 ACK、有限重试及人工原事件重试已进入源码并完成分批本地验证。构建与部署已收敛为单 TEST 的13个服务,两个旧模块已退出清单;旧模块源码批量清理被自动审批拒绝,尚未删除。撤销并发替代链已通过定向验证,旧安全投影链已移除,逐次投递审计与指标、协议去区域字段已实现,后端全量 Maven 回归已通过(4149项,12项跳过,0失败/错误),真实测试环境尚未部署验收。不得混合发布新旧协议或把本地测试视为环境验收。
|
||||||
|
|
||||||
|
下文路径、响应与时序为改造目标。实际业务服务、客户隔离、仓库类型、作业角色与状态机保持原职责;不能将“同机”解释为合并数据库表或绕过权限。
|
||||||
|
### A. 唯一路由与消费端映射
|
||||||
|
|
||||||
|
全部客户端共用 Gateway。下表写完整服务端路径;前端 HTTP Base 若已含 `/api`,业务调用不重复拼接该段。所有资源接口仍校验平台身份、客户范围及业务权限。
|
||||||
|
|
||||||
|
海外资源前缀记作 R=`/api/platform/v1/overseas-warehouse-resources`,权限前缀记作 P=`platform:overseas-warehouse:`。以下 R/P 仅用于文档缩写,不是配置变量。
|
||||||
|
|
||||||
|
| 方法与目标路径 | 目标服务 | 权限 | 主要调用方/改动 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| GET `/api/platform/v1/warehouse-admin` 及现有主档 CRUD | Warehouse | 维持现有主档权限,GET 为 `platform:warehouse:list` | 主档页面与 IAM 的共享收货仓查询保留现有调用;写操作不改权限 |
|
||||||
|
| GET `/api/platform/v1/warehouse-admin/overseas-receiving-options` | Warehouse | P+`warehouse:list` | 新增限定用途查询;替代海外资源服务原根目录查询,返回平台公共、OVERSEAS、ACTIVE、RECEIVING 仓库,不因迁移给资源角色授予主档维护权限 |
|
||||||
|
| GET R+`/pallets`、R+`/pallets/summary` | Warehouse Overseas | P+`pallet:list` | Admin `overseas-warehouse/api/pallets.ts` 跨仓查询 |
|
||||||
|
| GET R+`/{warehouseId}/locations`、R+`/{warehouseId}/locations/{id}` | Warehouse Overseas | P+`location:list` | Admin `overseas-warehouse/api/locations.ts` |
|
||||||
|
| POST R+`/{warehouseId}/locations` | Warehouse Overseas | P+`location:create` | 同上 |
|
||||||
|
| PUT R+`/{warehouseId}/locations/{id}` | Warehouse Overseas | P+`location:edit` | 同上 |
|
||||||
|
| DELETE R+`/{warehouseId}/locations/{id}` | Warehouse Overseas | P+`location:delete` | 同上 |
|
||||||
|
| GET R+`/{warehouseId}/pallets`、`/pallets/summary`、`/pallets/{id}`、`/pallets/{id}/label`(后面三项同属 R+`/{warehouseId}`) | Warehouse Overseas | P+`pallet:list` | Admin `overseas-warehouse/api/pallets.ts`,标签二进制响应保持原格式 |
|
||||||
|
| POST R+`/{warehouseId}/pallets` | Warehouse Overseas | P+`pallet:create` | 同上 |
|
||||||
|
| PUT R+`/{warehouseId}/pallets/{id}` | Warehouse Overseas | P+`pallet:edit` | 同上 |
|
||||||
|
| DELETE R+`/{warehouseId}/pallets/{id}` | Warehouse Overseas | P+`pallet:delete` | 同上 |
|
||||||
|
| 现有方法 `/api/platform/v1/last-leg/**`、`/api/merchant/v1/last-leg/**`、`/api/pda/v1/last-leg/**` | Lastleg | 保留对应 Controller 权限与作业数据范围 | Admin、Client、海外 PDA 改用统一 HTTP/Token,业务路径保持 |
|
||||||
|
| 现有文件、打印、审计、集成公开接口 | 原对应服务 | 保留现有权限 | 从原双网关去重后接入唯一入口 |
|
||||||
|
| 任意 `/internal/**` | 仅服务间内部网络 | 内部服务身份 | Gateway 无公开路由;测试内部接口不能通过公网入口调用 |
|
||||||
|
|
||||||
|
新增收货仓选项查询沿用原海外目录的分页参数 `page/size`(size≤200)和 `WarehouseOption` 字段语义,由 Warehouse 直接查询权威主档,不能只通过客户端过滤实现范围限制。该用途查询需在 Warehouse Controller/OpenAPI/IAM 权限合同中明确登记。现有 IAM 查询与 Admin pallets 中 `listSharedReceivingOverseasWarehouseOptions` 已使用主档接口,保留其现有权限边界;仅原海外目录的直接调用者迁移到新用途接口,不批量改写无关主档消费者。
|
||||||
|
|
||||||
|
修改 `PlatformWarehouseResourceController` 和 `PlatformWarehouseDirectoryController` 的资源路径;移除海外服务中的重复目录代理和无独立必要性的公开健康路由。内部资源锁、托盘作业路径保持服务内使用。Gateway 对 `/warehouse-admin/**` 只指向 Warehouse,对 R 只指向 Warehouse Overseas,不按路由先后顺序或请求 warehouseId 猜测目标服务。
|
||||||
|
|
||||||
|
路由验收:逐条 method/path 唯一匹配;静态 `/overseas-receiving-options` 不误命中 `/{id}`;同名旧前缀下的国内接口仍有效;海外调用方全部迁移,不为其保留旧别名;客户端角色只能读取被授权目录,不能借新增用途查询修改主档。
|
||||||
|
|
||||||
|
### B. 逐事件直接投递与结果确认
|
||||||
|
|
||||||
|
以下内部路径复用当前消费者入口,统一为 POST,使用内部服务令牌、服务发现或容器服务名,不能经公开 Gateway。按 eventType 明确选择目标,不再根据 CN/OVERSEAS 选择目标;未知事件类型直接记录永久错误,不默认投某个业务服务。
|
||||||
|
|
||||||
|
| eventType | 当前生产与投递入口 | 直接目标 |
|
||||||
|
|---|---|---|
|
||||||
|
| `FirstLegLoadingPlanCompleted` | Firstleg `LoadingCompletedOutboxService` → `LoadingCompletedOutboxRelay` | Lastleg `/internal/lastleg/events` |
|
||||||
|
| `FirstLegContainerShippingNodeRecorded` | Firstleg `CarrierScheduleNodeOutboxService` → 同一 `LoadingCompletedOutboxRelay` | Lastleg `/internal/lastleg/events` |
|
||||||
|
| `OverseasContainerUnloaded` | Lastleg `InboundUnloadCompletedOutboxService` → `InboundUnloadCompletedOutboxRelay` | Firstleg `/internal/firstleg/v1/container-events` |
|
||||||
|
| `OverseasInboundOrderDetainedChanged` | Lastleg `InboundOrderDetainedOutboxService` → 同一卸柜 Relay | Firstleg `/internal/firstleg/v1/container-events` |
|
||||||
|
| `OverseasDeliveryCompleted` | Lastleg `DeliveryCompletedOutboxService` → 同一卸柜 Relay | Firstleg `/internal/firstleg/v1/container-events` |
|
||||||
|
| `BusinessFeeSourceChanged` | Lastleg `OverseasFeeOutboxService` → `OverseasFeeOutboxRelay` | Finance `/internal/finance/v1/business-fee-source-events` |
|
||||||
|
| `WalletCommandRequested` | Lastleg `WalletCommandOutboxService` → `InboundUnloadCompletedOutboxRelay` | Finance `/internal/finance/v1/wallet-command-events` |
|
||||||
|
| `WalletCommandCompleted` | Finance 资金指令处理的结果 Outbox → `WalletResultOutboxRelay` | Lastleg `/internal/lastleg/events` |
|
||||||
|
| `IamUserStatusChanged`、`IamTenantStatusChanged`、`IamPermissionVersionChanged` | IAM 安全事件专用生产/Relay | 不迁移业务投递;完成 C 的撤销替代验证后移除专用投影链 |
|
||||||
|
|
||||||
|
已核对:Lastleg 卸柜 Relay 的 Repository 还选择了资金指令,不能把它整体改成 Firstleg URL;费用 Relay 只选择费用来源事件。实现时使用明确的事件白名单分派,并测试资金请求不误投 Firstleg。Firstleg 现有直达 Finance 的其他费用链、Order 的既有投递和 RocketMQ 导出/通知不并入本次新路由表,保持现有行为并做受影响回归。
|
||||||
|
|
||||||
|
统一目标返回结构为 `ApiResponse<DeliveryAck>`,其中 `DeliveryAck={eventId,payloadHash,outcome}`。`outcome` 只允许 `APPLIED`(已完成消费)、`DUPLICATE`(已成功处理的同一事件)、`STALE`(该类事件明确允许忽略的旧版本)。四个内部消费路径同步修改为这个返回结构,Relay 与全部直接调用者同步更新;当前 Integer/Object/feeSourceId 等响应不作为最终成功判定依据,不引入双响应兼容。
|
||||||
|
|
||||||
|
成功必须同时满足:HTTP 2xx、body code 为字符串 `200`、ACK 中 eventId/payloadHash 与发送一致、outcome 为该类事件允许的值。消费端只在可靠提交后返回成功;不能刚入内存或仅保留待处理记录就返回 APPLIED。重复确认必须来自持久化幂等记录;同 eventId 不同 hash 为冲突,不允许覆盖。
|
||||||
|
|
||||||
|
消费处理的原子性按业务实现验证:普通消费者将业务变更与成功幂等记录同事务提交;第 0A 批已将资金执行、成功 Inbox 和结果 Outbox 收敛到同一事务,保存结果失败时资金一同回滚;事件身份独立持久化防止重试换内容。保留既有钱包业务幂等键和状态机,真实 MySQL 故障恢复仍需验证。
|
||||||
|
|
||||||
|
特别约定:资金指令的投递成功不等于冻结/扣款成功。Finance 必须可靠保存 SUCCEEDED 或 FAILED 业务结果及结果 Outbox 后确认该指令已消费,Lastleg 以 `WalletCommandCompleted` 更新业务状态。余额不足等已形成 FAILED 结果的指令不进行无意义的传输重试;成功扣款后结果发送失败,只重试原结果事件,不能再次生成扣款指令。
|
||||||
|
|
||||||
|
| 情况 | 生产端动作 | 消费端要求 |
|
||||||
|
|---|---|---|
|
||||||
|
| APPLIED / DUPLICATE | 标记完成 | 已提交、幂等记录可核验 |
|
||||||
|
| STALE | 仅显式允许旧版本忽略的事件标记完成 | 证明较新版本已覆盖且不丢独立业务事实;资金和独立费用动作不能泛用 STALE |
|
||||||
|
| 连接失败、超时、HTTP 5xx/429、临时数据库失败 | 原事件重试 | 超时后可能已提交,下次必须幂等 |
|
||||||
|
| 船节点等先于依赖单据到达 | 返回明确的可重试“依赖未就绪”业务错误,退避重试 | 不以不存在直接当成功,不靠查询顺序假设到达顺序 |
|
||||||
|
| 非法信封/版本、hash 冲突、未知类型、明确不可执行协议错误 | DEAD 并保留原因 | 不修改业务,不兜底成功 |
|
||||||
|
| 401/403 或内部令牌错误 | DEAD,标注配置/认证失败,修复后人工原样重试 | 失败关闭,不绕过鉴权 |
|
||||||
|
| 响应缺失、ACK 不匹配、未识别业务错误 | 不确认成功,有限重试后 DEAD | 保留诊断信息,不能仅按 HTTP 200 通过 |
|
||||||
|
|
||||||
|
统一逻辑状态为待投递、投递中、重试等待、完成、DEAD;可映射到现有表字段,不要求批量改名。初始测试参数:连接超时 3 秒、单次请求超时 15 秒、租约 60 秒、累计自动尝试 12 次、退避从 5 秒翻倍上限 30 分钟,加入小幅抖动;参数需可配置。租约失效后的恢复和最终状态更新必须校验持有者,避免旧任务覆盖新任务。消费超时不能被解释为事务一定回滚。
|
||||||
|
|
||||||
|
源码配置已统一为 `baiyue.event-delivery.connect-timeout-ms=3000`、`read-timeout-ms=15000`、`max-attempts=12`、`base-delay-seconds=5`、`max-delay-seconds=1800`、`jitter=0.1`、`lease-seconds=60`,供四个业务 Relay 使用。事件 Feign 客户端显式应用 EventDeliveryFeignConfiguration,禁止客户端内部自动重试及重定向,最终构建参数不被旧的全局 Feign 超时覆盖;连接与读取超时之和必须小于租约时长。`retry_count` 表示已失败或租约超时的投递次数;普通领取不递增,领取超时任务或恢复超时租约时计入一次,自动预算耗尽后保持 DEAD。实际投递失败从失败时刻计算下一次重试时间;每次领取使用独立租约 ID 和当前时间,最终写入必须匹配该 ID。DEAD 保留原始事件,不能通过定时扫描自行恢复。人工重试、逐次审计和指标已落地并通过本地事务回归,真实数据库/多服务故障恢复仍未验证,尚未达到停桥部署门槛。
|
||||||
|
|
||||||
|
每次尝试在本服务 event_delivery_attempt 表记录事件、目标、时间、耗时、结果、有限错误码和下一次重试;领取与STARTED审计同事务提交后才发HTTP,持有者CAS完成与审计完成同事务,失败一同回滚。过期租约审计为LEASE_EXPIRED并退避,本轮不立即重发。按服务/类型提供 pending/DEAD 数量及最老待处理时长;指标 baiyue.event.delivery.pending/dead/oldest.pending.seconds/sample.timestamp/sample.success 默认30秒采样,Prometheus只读缓存。采样失败保留旧值并标记失败,未知初值为NaN,不误报零积压。告警接入现有能力,不为本次新增独立监控平台。人工重试采用各生产服务的受保护内部操作与配套运维脚本,不新增公开后台页面:只允许 DEAD 原事件重试,记录操作人/原因,保留 eventId/hash/payload/业务幂等键,禁止修改载荷或伪造新 ID 后重发。
|
||||||
|
|
||||||
|
人工重试源码接口已冻结:GET `/internal/{firstleg|lastleg|finance}/event-operations/{entryId}` 查询状态,POST 同路径加 `/retry` 提交 `{requestId,operator,reason,expectedPayloadHash}`。使用独立 `X-Event-Operations-Token`,服务配置 `baiyue.event-delivery.operations-token` 对应 `EVENT_OPERATIONS_TOKEN`;缺失或不足32字节时仅关闭该运维能力,不影响业务启动。请求编号为稳定UUID,锁定本服务原Outbox行,DEAD→PENDING和 `event_delivery_retry_audit` 同事务提交;相同请求参数幂等,不同参数冲突,审计失败回滚状态。脚本 `baiyue-firstleg/scripts/event-outbox-operations.mjs` 只接受显式服务源地址与 `CHONGCHONG_ENV=test`,凭据仅从环境读取,不跟随重定向、不自动重试。不得通过公网Gateway或直接改表验收。
|
||||||
|
|
||||||
|
信封保留业务事件类型/版本、客户归属、聚合版本、因果/追踪标识及 payloadHash;删除 sourceRegion/targetRegion 及纯区域部署字段时同步 DTO、Validator、构造调用、SQL 基线和测试。语义事件版本及业务载荷不因去桥而随意改动。本轮不重写旧测试事件,不做旧信封兼容。
|
||||||
|
|
||||||
|
### C. 统一认证和会话撤销矩阵
|
||||||
|
|
||||||
|
Auth 是唯一签发者;Gateway 负责入口令牌与访问域校验,业务服务通过 common-security 校验同一会话及业务权限。统一使用 Auth 现有国内会话协议,不只调整海外 Audience。Auth、Gateway、Lastleg、Warehouse Overseas 必须使用一致 Redis DB、会话键前缀、序列化结构与有效期规则;业务缓存用独立前缀,不能混同会话键。
|
||||||
|
|
||||||
|
JWT 不携带角色或权限集合,只保留必要身份、客户/应用/仓绑定与版本声明;授权快照取服务端会话,平台/客户/PDA 访问域仍独立校验。客户端不能从 JWT 或外部伪造头获得绕过服务器权限检查的能力。
|
||||||
|
|
||||||
|
并发撤销以持久版本和权威快照指纹为准,不能只依赖删除Redis:Auth账号变更与签发读取使用行锁,Access会话另存状态指纹,Refresh签发前复核旧指纹;Gateway及common-security在Redis会话检查后调用Auth `/internal/auth/accounts/sessions/validate`。Auth重新核对账号版本及IAM当前授权快照,缺失状态或下游不可用拒绝访问。IAM用单条SELECT读取身份、客户、角色权限、两类仓绑定及subject/tenant版本,避免跨查询混合快照。Gateway采用非阻塞HTTP,校验调用不转发Bearer Token,内部服务令牌保护该端点且不递归调用会话验证。此依赖增加每次请求的权威校验成本,测试环境仍须测可用性与延迟。
|
||||||
|
|
||||||
|
| 触发行为 | 撤销范围与负责链 | 必须验证 |
|
||||||
|
|---|---|---|
|
||||||
|
| 当前会话退出 | Auth 撤销当前会话的 Access/Refresh 能力 | 原 Access 被拒绝,原 Refresh 不能恢复 |
|
||||||
|
| 密码重置、账号停用 | Auth 或 IAM 调 Auth,撤销该账号全部相关会话 | 多端旧 Token 均失效,停用后不可重新登录 |
|
||||||
|
| 客户停用 | IAM 确定该客户成员范围,Auth 撤销该客户作用域会话 | 该客户业务不可访问/刷新;其他客户与平台账号不被误撤销 |
|
||||||
|
| 成员移除、成员角色改变 | IAM → Auth 撤销对应成员/客户作用域会话 | 旧权限不可继续使用,重新登录/刷新不能恢复被移除身份 |
|
||||||
|
| 角色权限、角色分配变化 | IAM RBAC 确定所有受影响账号与作用域 → Auth 撤销 | 已登录用户不能继续使用旧权限快照,遗漏批量关联用户算失败 |
|
||||||
|
| 平台人员角色改变 | IAM 平台人员维护 → Auth 撤销相应账号会话 | 新旧角色与平台访问域正确 |
|
||||||
|
| PDA 仓绑定修改/清空 | IAM → Auth 撤销绑定账号全部相关会话 | 原仓 Token 拒绝;新登录只获得新仓;无绑定拒绝受限作业 |
|
||||||
|
| Refresh Token 轮转与重放 | Auth 维持现有会话轮转规则,各端共用刷新编排 | 失效 Refresh 不重复换取;并发刷新行为与当前契约一致 |
|
||||||
|
|
||||||
|
撤销职责优先复用现有 MemberService、RbacService、PlatformInternalUserService/PlatformUserManagementService 与 Auth revokeSessions 链。逐入口确认,不能只凭其中一处已有调用就删除全体安全投影。
|
||||||
|
|
||||||
|
安全变更不得在撤销失败后仍返回完整成功。实施必须核对调用与提交顺序,证明“新安全状态已生效、旧会话却残留”的异常路径不会继续授权;同进程 try/catch 或口头要求重试不构成保证。若当前实现无法保证,应在该批次补齐可靠撤销及失败关闭机制,并先验证再删投影,不能降级为等待 Token 自然过期。这里冻结的是安全结果,具体撤销代码调整依据逐入口核查限定范围。
|
||||||
|
|
||||||
|
必须覆盖 Redis 不可用、Auth 撤销调用超时、账号/客户停用后的刷新、跨客户 Token 混用、伪造身份头。业务服务不能仅信任浏览器提供的权限头;统一服务端认证后清除对原海外可信头及 Lastleg 安全投影的专用依赖。权限继续由服务器决定,客户端快照只用于显示。
|
||||||
|
|
||||||
|
|
||||||
|
## 业务归属与权限边界
|
||||||
|
|
||||||
|
平台和客户两级模型、服务端客户隔离、实际收货仓与 FBA 目的仓的区分继续有效。仓管绑定修改须撤销会话;无关平台角色不能通过客户端参数假冒仓绑定。统一认证后,不再用双区域安全投影作为权限来源。
|
||||||
|
|
||||||
|
资金指令当前实现补充:Finance 先单独提交 eventId/hash 身份记录,再在事务内锁定 Inbox 并复核 hash。资金变更、Inbox 最终结果及结果 Outbox 同事务提交;明确业务拒绝在原事务回滚后重新加锁记录,已有最终结果不得覆盖。可重试异常不产生最终 FAILED。内部消费响应已统一为 ApiResponse<DeliveryAck>,可靠提交后才确认成功。
|
||||||
|
|
||||||
|
最终业务拒绝白名单为 FIN-WALLET-INSUFFICIENT、FIN-WALLET-HOLD-409、FIN-IDEMPOTENCY-CONFLICT、FIN-REQ-400;处理中、乐观锁冲突、依赖冻结未到达及未分类异常继续向投递方抛出。基于 H2 的 JDBC 并发与回滚测试已经通过,不替代真实 MySQL 和测试环境全链路验证。
|
||||||
|
|
||||||
|
### 国内仓库目录同步读取
|
||||||
|
|
||||||
|
- 国内 `warehouse-service` 是 Warehouse ID、类型、状态、地址和能力的唯一权威。海外数据库不得复制仓库、地址或服务能力主表。
|
||||||
|
- `warehouse-overseas-service` 只保存库位、托盘、资源锁及其国内 `warehouseId` 引用;资源写入和 Lastleg PDA 仓绑定校验通过受内部服务令牌保护的国内只读目录完成。
|
||||||
|
- 只允许平台共享、`OVERSEAS`、`ACTIVE` 且启用 `RECEIVING` 的仓作为海外实际收货仓。低频正结果可缓存 30 分钟,空目录、不存在和停用结果不得长缓存。
|
||||||
|
- FBA 目的仓同样只以国内 `warehouse-service` 的平台公共主数据为权威,但语义与海外实际收货仓严格分离:Admin 候选使用 `warehouseType=FBA&status=ACTIVE` 的平台仓库分页;Lastleg 写入通过受内部服务令牌保护的 `/internal/warehouses/0/{warehouseId}/active` 读取当前事实,并继续校验 `warehouseType=FBA` 及 ID/编码/名称一致。`OVERSEAS`、`OVERSEAS_PARTNER` 或 `DOMESTIC` 均不得作为 FBA 目的仓。
|
||||||
|
|
||||||
|
- 按 FBA 仓拆分的海外派送单在签收完成时,由 Lastleg 在同一事务按关联来源入仓单分别写 `OverseasDeliveryCompleted` V1 Outbox;Lastleg Relay 直接投递 Firstleg 的 `/internal/firstleg/v1/container-events`。Firstleg 校验事件信封、客户、来源入仓单/订单、入仓码和 FBA 仓后,只将该来源入仓单从 `LOADED` 推进到 `DELIVERED`;同一 Order 的全部有效入仓单均为 `DELIVERED` 后,才以内部服务身份幂等推进该 Order 到 `COMPLETED`。同车其他 FBA 派送单必须各自签收,不得随整车一起完成。
|
||||||
@@ -123,6 +123,16 @@ Finance 不以当前查询结果覆盖已保存快照。查询超时、5xx 或
|
|||||||
|
|
||||||
## 7. 错误码与响应语义
|
## 7. 错误码与响应语义
|
||||||
|
|
||||||
|
### 资金指令消费可靠性(2026-09-29)
|
||||||
|
|
||||||
|
`WalletCommandRequested` 先独立提交 eventId/hash 身份记录,再在处理事务使用 Inbox 行锁重新校验 hash;相同 ID 不同 hash 即使并发到达也不能执行钱包。资金变更、成功 Inbox 结果和结果 Outbox 同事务提交,任何结果写入失败均回滚资金变更,原事件保留身份并允许重试。
|
||||||
|
|
||||||
|
仅 `FIN-WALLET-INSUFFICIENT`、`FIN-WALLET-HOLD-409`、`FIN-IDEMPOTENCY-CONFLICT`、`FIN-REQ-400` 作为明确业务拒绝,在原事务回滚后重新锁定事件、确认无既有最终结果,再保存 FAILED 与结果 Outbox。临时数据库异常、处理中、乐观锁冲突、冻结依赖未到达及其他未分类异常继续抛出,不确认消费成功,不固化为最终业务失败。传输确认仍不等于资金业务成功,Lastleg 继续消费资金结果事件。
|
||||||
|
|
||||||
|
本条是当前消费者实现规则;单机去桥目标及统一 ACK 见[统一认证与服务通信契约](../统一认证与服务通信契约.md),后者尚未整体落地。
|
||||||
|
|
||||||
|
### 通用响应
|
||||||
|
|
||||||
错误码是跨服务稳定字符串,message 可本地化且不能作为程序判断依据:
|
错误码是跨服务稳定字符串,message 可本地化且不能作为程序判断依据:
|
||||||
|
|
||||||
| 错误码 | 语义 | 是否重试 |
|
| 错误码 | 语义 | 是否重试 |
|
||||||
|
|||||||
+3
-53
@@ -1,55 +1,5 @@
|
|||||||
# 跨区域认证与服务通信契约
|
# 跨区域认证与服务通信契约(已替代)
|
||||||
|
|
||||||
## 适用范围
|
自 2026-09-29 起,当前目标仅有一个测试环境,服务同机部署。旧双区域认证、独立海外网关及事件桥约束已由[统一认证与服务通信契约](统一认证与服务通信契约.md)替代;部署与切换见[测试环境单机部署与配置契约](测试环境单机部署与配置契约.md)。
|
||||||
|
|
||||||
- 本契约适用于 Admin、Client、国内头程服务、海外网关、尾程服务、海外仓资源服务及跨区域事件桥接。
|
此文件仅保留旧链接入口,不再定义有效规则。目标已确认不代表当前代码和环境已经迁移完成。
|
||||||
- 业务范围仍按对应阶段和模块文档确定;本文件只冻结跨区域账号、请求路由、服务鉴权和事件通信边界。
|
|
||||||
- 开发/测试同机共置及生产国内/海外双控制面的实际部署拓扑、Nacos、数据库和 Event Bridge 规划见[双区域部署与 Nacos 规划](双区域部署与Nacos规划.md)。
|
|
||||||
|
|
||||||
## 统一账号与 Token
|
|
||||||
|
|
||||||
- Admin、Client 只维护一套前端和一套用户账号体系;用户登录和 Token 签发统一归国内头程 Auth,不得为海外仓再创建独立登录、账号或权限体系。
|
|
||||||
- 统一使用 RS256/JWKS 信任链,但区分 Token 用途:国内登录/刷新时由同一 Auth 同时签发国内 Token 和短时海外 Token;海外 Token 限定海外 Audience,只携带稳定身份、客户范围与版本声明,不携带角色或权限集。
|
|
||||||
- 平台 `WAREHOUSE_PICKER` 必须在 IAM 成员关系中绑定一个启用的实际海外收货仓;Auth 将该绑定以可空 `overseas_warehouse_id` Claim 同步写入国内与海外 Token,海外 Token 同时携带账号 `token_version`。该 Claim 只用于已绑定的平台仓管员,页面和 PDA 请求不得传入或覆盖仓库身份;修改或清空仓绑定时 IAM 必须调用 Auth 撤销该账号全部会话并递增 `token_version`,随后重新签发 Token。
|
|
||||||
- 用户只登录一次,由前端统一认证模块按目标 API 自动选择 Token,不在页面或业务模块中分叉登录逻辑。
|
|
||||||
- JWKS 只暴露公钥验证能力,不暴露私钥;国内服务验证登录 Token 并结合 Redis 会话实现即时退出和权限变更,海外业务服务不访问国内 Redis。`gateway-overseas` 对普通 Admin/Client 海外接口验证海外 Token 的签名、Issuer、Audience、有效期、应用域和客户范围,再按 `userId/tenantId/permissionVersion` 从 Lastleg 安全投影取得当前海外授权快照;仅 `/api/pda/**` 在本地验签后,以内部服务身份向 Auth 发送 `userId/tokenVersion/overseasWarehouseId` 做无缓存实时核对。该调用不得传递 raw Token 或用户凭据,Auth 超时、不可用、账号停用、版本或仓绑定不一致均 fail-closed。
|
|
||||||
- 本期普通 Admin/Client 海外 Token 的即时失效范围固定为 IAM 投影的账号停用、客户停用和权限版本推进;Gateway 向 Lastleg 安全投影仅发送 `userId/tenantId/permissionVersion`,旧 Token 被拒绝后客户端必须退出并重新登录。`token_version` 仍是海外 JWT 必填 Claim,但其权威实时比对只用于上述 PDA→Auth 链;普通 Admin/Client 的退出、密码重置或普通会话撤销依赖短时 Token 自然过期,不得宣称已由 Lastleg 即时撤销。
|
|
||||||
|
|
||||||
## 区域 API 路由
|
|
||||||
|
|
||||||
- 一套前端使用国内、海外两个区域 API Base:国内业务直连 `gateway/`,海外仓业务直连 `gateway-overseas/`,再由海外网关路由到 `lastleg-service/`、`warehouse-overseas-service/` 和海外部署的公共服务。
|
|
||||||
- 日常海外请求不得经国内 Gateway 中转。区域地址、Token 选择和刷新由环境配置与统一 API/认证层处理,业务页面不得感知部署区域差异。
|
|
||||||
- 海外浏览器请求的具体 Audience、Claim 和路由以前端项目、`auth/`、`gateway-overseas/` 最近的 `AGENTS.md` 与实际配置为准;修改其中任一项时必须联查全部生产者和消费者。
|
|
||||||
|
|
||||||
## 跨区域事件与服务身份
|
|
||||||
|
|
||||||
- 头程与海外仓的数据流转使用 MQ 的 Outbox → Inbox、事件幂等、重试和死信机制。
|
|
||||||
- 事件使用版本化信封、事件 ID、业务键、来源/目标区域和 Payload 哈希,不携带用户 Access Token。
|
|
||||||
- 费用由海外仓发布事件,头程 Finance 消费并按来源快照入账;财务状态机和结算口径仍由财务契约冻结,海外服务不得自行定义。
|
|
||||||
- MQ 使用独立的服务身份、TLS 和 ACL;服务间事件鉴权与用户 JWT 鉴权分开。只有明确的同步 HTTP 内部接口才使用内部服务令牌。
|
|
||||||
- 修改事件时联查 `common-event-contract/`、`event-bridge-service/`、生产服务、消费服务、幂等记录、重试/死信和契约测试。
|
|
||||||
- 按 FBA 仓拆分的海外派送单在签收完成时,由 Lastleg 在同一事务按关联来源入仓单分别写 `OverseasDeliveryCompleted` V1 Outbox;Event Bridge 定向投递 Firstleg。Firstleg 校验事件信封、客户、来源入仓单/订单、入仓码和 FBA 仓后,只将该来源入仓单从 `LOADED` 推进到 `DELIVERED`;同一 Order 的全部有效入仓单均为 `DELIVERED` 后,才以内部服务身份幂等推进该 Order 到 `COMPLETED`。同车其他 FBA 派送单必须各自签收,不得随整车一起完成。
|
|
||||||
|
|
||||||
### 国内仓库目录同步读取
|
|
||||||
|
|
||||||
- 国内 `warehouse-service` 是 Warehouse ID、类型、状态、地址和能力的唯一权威。海外数据库不得复制仓库、地址或服务能力主表。
|
|
||||||
- `warehouse-overseas-service` 只保存库位、托盘、资源锁及其国内 `warehouseId` 引用;资源写入和 Lastleg PDA 仓绑定校验通过受内部服务令牌保护的国内只读目录完成。
|
|
||||||
- 只允许平台共享、`OVERSEAS`、`ACTIVE` 且启用 `RECEIVING` 的仓作为海外实际收货仓。低频正结果可缓存 30 分钟,空目录、不存在和停用结果不得长缓存。
|
|
||||||
- FBA 目的仓同样只以国内 `warehouse-service` 的平台公共主数据为权威,但语义与海外实际收货仓严格分离:Admin 候选使用 `warehouseType=FBA&status=ACTIVE` 的平台仓库分页;Lastleg 写入通过受内部服务令牌保护的 `/internal/warehouses/0/{warehouseId}/active` 读取当前事实,并继续校验 `warehouseType=FBA` 及 ID/编码/名称一致。`OVERSEAS`、`OVERSEAS_PARTNER` 或 `DOMESTIC` 均不得作为 FBA 目的仓。
|
|
||||||
|
|
||||||
### IAM 安全事件海外投影冻结
|
|
||||||
|
|
||||||
- `IamUserStatusChanged`、`IamTenantStatusChanged`、`IamPermissionVersionChanged` V1 固定由 Lastleg 独立安全入口 `/internal/lastleg/security/v1/events` 消费;不得投递到 Lastleg 的 LoadingCompletedConsumer。
|
|
||||||
- 安全状态只使用 `ACTIVE`/`DISABLED`:`IamTenantStatusChanged` 仅在 IAM 客户业务状态为 `ACTIVE` 时发布 `ACTIVE`,`PROFILE_REQUIRED`、`PENDING`、`REJECTED`、`DISABLED`、`ARCHIVED` 及其他不可用状态统一折叠为 `DISABLED`。Lastleg 只校验该两态安全快照,不解释国内建档/审核工作流。
|
|
||||||
- Event Bridge 只按冻结的 eventType→consumer URL 选择下游,不解析状态、权限版本或 payload 业务字段。海外业务事件仍投 Lastleg,国内回流事件仍投 Firstleg。
|
|
||||||
- Lastleg 以 MySQL `ll_security_event_inbox` 和 `ll_security_projection` 为可靠来源:eventId 相同 hash 相同幂等,异 hash 冲突;聚合版本只单调推进,旧版本标记 STALE,同版本异 hash 冲突。Redis 仅为提交后写入的可重建镜像,授权校验不依赖 Redis 默认放行。
|
|
||||||
- 海外 Gateway 对全部 `/api/**` 在本地 JWT 验签后,传递 `userId/tenantId/permissionVersion` 到 Lastleg 安全入口。Lastleg 校验通过时返回该版本的角色与海外权限快照,Gateway 清除外部伪造的授权头后,以内部服务令牌保护的可信头传给海外业务服务。业务服务必须同时验证 JWT 和内部服务令牌,不得从 JWT 回退读取完整权限集。用户停用返回 A0401;客户停用或 Token 权限版本不一致返回 A0403;安全投影、SQL 或调用链不可用均 fail-closed。PDA 在此基础上继续执行 Auth 仓绑定实时核验。
|
|
||||||
- Auth 的登录、刷新和海外 Token 兑换响应在响应体中返回当前 `roles/authorities` 授权快照;国内与海外 JWT 都只保留主体、客户、成员、应用、版本和海外仓绑定等最小身份 Claim,不携带角色或权限集合。客户端可用响应快照做入口展示或本地前置提示,但每次业务请求的最终授权仍由 Gateway/Lastleg 的实时投影决定;客户端不得再从 JWT 解析角色或权限,也不得把响应快照作为绕过服务端校验的依据。
|
|
||||||
- 新客户创建、审核激活以及新用户授权均由 IAM 在业务事务内写初始安全事件。开发阶段不提供历史账号长期 Bootstrap 或兼容入口;固定 `platform_admin` 由 Lastleg 数据库基线初始化 version=0 的 USER/AUTHORIZATION 投影,其中 AUTHORIZATION 冻结当前 `PLATFORM_ADMIN` 角色及 IAM 跨区前缀下的完整权限集合,空库重建后无需人工补投即可访问海外接口,后续 version>=1 的真实 IAM 事件单调覆盖。其他既有开发账号仍须由总控按 IAM 当前事实一次性重建授权快照;任何缺失投影继续 fail-closed,不能在 Lastleg 运行时代填或默认放行。
|
|
||||||
|
|
||||||
## 修改与验收
|
|
||||||
|
|
||||||
- Token、Audience、Claim、JWKS、API Base 或刷新策略变化时,至少联查 Auth、IAM、Admin/Client 统一认证层、国内/海外 Gateway、`common-security/` 和目标海外服务。
|
|
||||||
- `overseas_warehouse_id` 变化时还需联查 IAM 平台用户维护、海外 PDA、Lastleg 收货会话及 Warehouse Overseas 共享仓校验;验收必须同时覆盖未绑定拒绝、非仓管角色禁止绑定和换仓后旧 Token 失效。
|
|
||||||
- 跨区域事件变化时同步检查事件版本、Payload 哈希、Outbox、Inbox、重复投递、失败重试、死信和全部实际消费者。
|
|
||||||
- 本文件是跨区域通信的公共事实来源;项目和模块 `AGENTS.md` 只保留执行所需摘要及本文件入口,不复制完整协议。
|
|
||||||
|
|||||||
Reference in New Issue
Block a user