docs: organize contracts by business domain

This commit is contained in:
2026-09-04 16:44:08 +08:00
parent 703f869841
commit 40492cdae8
79 changed files with 916 additions and 852 deletions
@@ -0,0 +1,105 @@
# 海外仓业务后端缺口清单
更新日期:2026-08-19
## 口径与边界
- 本清单以当前海外仓业务范围、后端代码、静态 OpenAPI、数据库基线、IAM 初始化 SQL 和本地测试为依据。
- “已实现”表示已有可定位的领域实现、持久化和直接测试,不代表已经部署或完成测试环境 HTTP 验收。
- “部分实现”表示已有主体或单点能力,但缺少安全、契约、状态衔接或页面所需查询中的至少一项,不能作为稳定前端契约交付。
- 明确排除海外仓出库、退货出库、海外派送及其他库存离仓履约。代码中的 `dispatch/`、`delivery/`、`ll_outbound_*` 不计入海外仓业务完成度。
## 总览
| 业务域 | 判定 | 当前事实 | 主要缺口或下一闭环 |
|---|---|---|---|
| 海外 Token 与 JWKS | 部分实现 | Auth 登录与刷新已同时返回国内 Token 和短时 RS256 海外 Token,海外 Token Claims 已统一为下划线命名;JWKS、海外网关和两个海外业务服务按 `lastleg-api` Audience 验签并使用 Claims 授权,不依赖国内 Redis 会话 | 仍缺 Auth—Gateway—Servlet 服务跨模块契约测试;`POST /auth/overseas/token` 仅保留为过渡兑换能力,不作为海外仓业务稳定前端契约 |
| `gateway-overseas` 路由与入口安全 | 部分实现 | 已路由 `/api/*/v1/last-leg/**`、海外仓库、File/Print 等海外部署服务;可校验 Issuer、Audience、必要 Claims 和应用域,并清洗可信身份头 | 网关只做应用域,不做资源权限;静态路由未覆盖尚未实现的海外仓业务通用资料 API;可信身份头只传身份、不传权限是合理边界,资源权限必须由下游 JWT Claims 校验 |
| 装柜完成跨区建单 | 已实现 | Firstleg Outbox、版本化装柜完成事件、Event Bridge Inbox/重试/死信式 `DEAD`、Lastleg Inbox 幂等和事务建单均有实现及测试 | 与海外仓业务到港/可提柜衔接是另一事件,当前缺失,不能复用装柜完成事件冒充到港 |
| 尾程订单 | 部分实现 | 有事件建单、列表、详情、CSV 导出、目的仓单条/批量调整、客户隔离与状态历史 | 平台接口大多仅校验平台应用域,未按 `list/edit/export` 等资源权限闭环;IAM 仍保留独立 `detail` 权限,违反“列表包含详情只读”统一语义;缺静态 OpenAPI |
| 海外接柜、卸货与入仓 | 部分实现 | 有入仓计划转换、FBA 预约、托盘分配、PDA 实收/上架/合托/完成以及实收后库存落账 | 缺“国内出仓后到港结果 → 海外可提柜/接柜任务”的事件或内部契约;缺接柜车辆/运抵/卸货节点聚合;入仓单列表和正式详情契约不足,现有 Controller 主要是转换与单号详情;权限资源和静态 OpenAPI 未闭环 |
| 换标 | 部分实现 | 有换标申请、明细、状态历史和库存联动服务及测试 | 仅有平台接口且权限未闭环;状态机与前端海外仓业务页面字段尚无静态 OpenAPI;需确认换标完成后库存 SKU/箱唛快照的稳定查询形态 |
| 海外仓托盘与库位 | 部分实现 | `warehouse-overseas-service` 有仓库、地址、能力、库位、托盘、绑定和资源锁;平台/商户及内部锁定接口均存在 | 平台资源接口要求显式 `customerId`,与“仓储资源可独立查询全部客户和仓库”的产品约定存在冲突;仅校验平台应用域,缺细粒度权限;缺静态 OpenAPI |
| 箱号管理 | 部分实现 | 一件代发领域保存来源箱唛、箱级库存和箱流水,库存查询可返回部分箱/SKU事实 | 没有面向海外仓业务 Admin 的箱号列表、详情、筛选及只读权限契约;现有 Dropship 接口是内部接收口,不能直接作为平台箱号管理 API |
| 产品库 | 缺失 | 现有 SKU 仅作为尾程明细、采购明细或一件代发库存快照存在 | 无独立产品主档、平台 CRUD/查询、唯一键/启停规则、静态 OpenAPI、权限和表结构 |
| 库存及库内操作 | 部分实现 | 有余额、仓位、流水、汇总查询;有 hold/release/allocate/unallocate/pick/ship/adjust 命令幂等;PDA 实收后可入可用库存 | 海外仓业务排除库存离仓,因此 `pick/ship` 不应作为海外仓业务交付;其余平台命令有代码权限常量但 IAM 未初始化;查询接口缺只读权限;跨仓转移包含出仓动作,需把海外仓业务可验收部分限定为不离仓库内操作;缺静态 OpenAPI |
| 海外采购订单 | 部分实现 | 商户下单、平台审核/管理、采购单据余量及测试已存在,PDA 实收才进入可用库存的边界已建立 | 页面需要的平台列表/详情/编辑字段需与现有 API 冻结;代码使用的 `lastleg:overseas-procurement:*` 未写入 IAM 种子;手工采购出库属于库存离仓,不纳入海外仓业务;缺静态 OpenAPI |
| 本土卡车 | 部分实现 | 平台/商户订单、托盘明细、状态历史和测试存在 | 需确认该子域是海外仓业务“本土卡车”而非海外派送;平台只使用单一 `manage` 权限且 IAM 未初始化;缺列表只读/操作拆分和静态 OpenAPI |
| 本土散板 | 缺失 | `lastleg-service` 无稳定子域、Controller、表或测试 | 新建独立领域,不能复用出库/派送表;先冻结状态、字段、权限和与库存的非离仓边界 |
| 海外仓合作仓类型 | 已实现 | 国内 Warehouse 已新增正式类型码 `OVERSEAS_PARTNER`,与普通海外仓 `OVERSEAS` 明确区分;保存、查询筛选、列表响应、批量导入、Schema 注释、统一 SQL 和测试已同步;Admin 已完成列表筛选、新增/编辑及保存透传;内部服务令牌接口 `GET /internal/warehouses/overseas-partners` 仅供海外报价服务读取当前启用候选 | 实际环境 SQL 尚未执行;前端不得调用内部合作仓接口,也不跨区域为报价拉取国内候选 |
| 海外仓报价 | 缺失 | 国内 Warehouse 有“海外仓阶梯仓租费”,但没有海外仓业务原型所指完整海外仓报价主数据;已冻结合作仓来源方案:海外报价服务仅在创建时通过内部服务身份读取国内 `ACTIVE + OVERSEAS_PARTNER` 列表并缓存 30 分钟 | 需实现报价维度、币种、有效期、服务项、仓库/客户作用域和权限/OpenAPI/SQL;报价保存合作仓 ID、编码、名称快照,缓存未命中时强制刷新一次后再拒绝 |
| 汇率管理 | 缺失 | 海外仓业务目标服务中无汇率主档、接口、权限或表 | 汇率仅作为业务换算主数据;财务记账/结算汇率口径必须交财务总控冻结 |
| 车辆列表/详情 | 缺失 | 卡车订单仅保存车辆字段快照,没有车辆主档 | 需独立车辆主数据、启停/证照字段、平台查询与权限;不得把订单快照当车辆主档 |
| 国内出仓后船节点 | 部分实现 | Firstleg 已有 `CarrierScheduleQuery` 任务、尝试、历史、来源、过期、幂等、真实订舱/柜次关联和“3 天窗口最多 3 次”约束;船期及查询任务的列表、详情、历史、船司辅助查询已统一使用 `*:list`,旧 `*:view` 初始化资源已清理 | 当前适配器全部返回 `MANUAL_REQUIRED`,Integration 无船司/轨迹 DTO、内部接口或适配器;没有定时调度、任务租约、退避、失败重试、到港停止条件、最新标准节点事实或到港跨区事件;领域 SQL 文件仍沿用历史国内货柜履约命名 |
| 海外仓业务 IAM 权限 | 缺失 | 仅初始化少量尾程订单权限;代码内有库存、PDA、废弃、转仓、采购、卡车等权限常量 | 建立海外仓业务资源矩阵;所有正式列表用 `*:list` 覆盖详情和只读辅助接口,写操作独立;同步 Controller、OpenAPI、IAM 基线、统一 SQL 和契约测试 |
| 海外仓业务静态 OpenAPI | 缺失 | 船节点已有静态 YAML;Lastleg、Overseas Warehouse、Auth 海外 Token、到港事件及海外仓业务主数据没有完整静态 OpenAPI | 按浏览器公网 API、内部 API、事件三类拆分契约,先于前端正式联调冻结 DTO 与错误码 |
| 海外费用与 Finance | 跨总控依赖 | Lastleg 当前无海外仓业务费用事实 Outbox;Finance 口径不属于本总控 | 本总控只定义来源事件候选、业务键、币种/金额/来源快照与幂等字段,提交财务总控冻结入池条件、审核、结算和汇率口径后再实现生产者 |
## 已确认可复用的实现
1. `common-event-contract` 的版本化信封、事件 ID、区域、Payload 哈希和装柜完成 V1/V2。
2. `event-bridge-service` 的 Inbox、投递尝试、租约式领取、重试上限、`DEAD` 和人工补投。
3. `lastleg-service` 的装柜完成幂等建单、来源快照、入仓计划/PDA、库存余额/仓位/流水、换标、采购和本土卡车主体。
4. `warehouse-overseas-service` 的海外仓档案、库位、实物托盘、业务绑定和资源锁。
5. Firstleg `CarrierScheduleQuery` 的人工任务壳、尝试/历史/来源/过期和操作幂等。
## 最小闭环实施批次
### 批次 0:认证与契约门禁
1. 收口海外 Token 下划线 Claims、Audience/JWKS 和 Claims 模式权限快照;增加 Auth—Gateway—Servlet 服务跨模块契约测试。
2. 冻结海外仓业务 API 路径、DTO、错误码和权限矩阵;删除尾程/船节点旧独立详情权限,按 `list` 统一只读语义。
3. 为 Lastleg、Overseas Warehouse、海外 Token 增加静态 OpenAPI;补齐 Gateway 路由合同测试。
验收终点:平台/商户海外 Token 能分别访问正确应用域;错误 Audience、缺 Claim、过期/错签、伪造身份头和缺资源权限均稳定拒绝。
### 批次 1:到港衔接与接柜入仓最小闭环
1. 在 Integration 建立标准船节点查询请求/响应、供应商错误归一、超时/限流/重试配置和内部服务令牌接口。
2. 在 Firstleg 增加出仓后自动建任务、到期任务租约领取、重试/退避,并按[船节点标准化契约](船节点标准化契约.md)完成十个标准节点、异常事实、预计/实际时间、幂等落库和实际还柜停止条件。
3. 新增目的港到达、卸船、可提柜、已提柜及已还柜的版本化跨区事实;Lastleg Inbox 按实际业务需要消费接柜/入仓衔接事实,不因中间节点缺失而补造事件。
4. 补齐入仓单列表/详情、接柜/运抵/卸货状态,复用现有入仓计划、PDA 实收/上架和库存落账。
验收终点:一条真实装柜/订舱/柜次链路从国内确认出仓,经节点查询,到港后在海外形成可操作入仓单,PDA 完成后生成库存,并持续记录提柜与还柜事实直至查询停止;重复事件和重复任务不产生重复节点、单据或库存。
### 批次 2:海外仓管理面闭环
1. 冻结并实现产品主档与箱号平台查询;明确来源快照与可编辑主档的边界。
2. 补齐换标、托盘、箱号、产品、库存查询及不离仓库内操作的权限/OpenAPI。
3. 调整海外仓资源查询,不以客户筛选限制仓库候选;补细粒度资源权限和越权测试。
验收终点:海外仓业务前端所需七类海外仓页面均有稳定的列表、详情和允许操作 API,且不暴露出库/派送能力。
### 批次 3:海外业务闭环
1. 收口采购订单与本土卡车的列表/详情/写操作权限和静态 OpenAPI,排除采购手工出库及派送语义。
2. 新建本土散板领域、状态历史、幂等、权限、SQL、OpenAPI 和测试。
验收终点:采购、本土卡车、本土散板均能独立建单、查询、推进本期允许状态,并与库存离仓业务隔离。
### 批次 4:合作仓与通用资料
1. 国内 Warehouse 与 Admin 的 `OVERSEAS_PARTNER` 主数据全链路已完成。
2. 实现海外仓报价、汇率、车辆主数据及权限/OpenAPI/SQL。
3. 将海外费用事件候选契约提交财务总控;只有财务口径冻结后才实现费用 Outbox。
验收终点:合作仓、报价、汇率、车辆均可作为稳定主数据被海外仓业务业务引用;任何财务落账仍以财务总控确认契约为准。
## 跨总控依赖
| 接收方 | 需要冻结/确认 | 本总控交付 |
|---|---|---|
| 海外仓业务前端页面总控 | 合作仓类型码、各页面最小字段/筛选/动作、平台与商户 API 使用范围 | 稳定路径、DTO、枚举、权限码、错误码、分页/幂等约定和 OpenAPI;不修改前端共享导航/根路由 |
| 财务改造总控 | 海外费用入池条件、审核与结算状态、记账/结算汇率、来源作废/调整规则 | 业务来源事件候选、不可变来源快照、业务键/版本/币种/金额/发生时间/区域和幂等语义;不改 Finance 状态机 |
当前协同状态:海外仓业务前端总控已完成双 Token 原子适配,登录/刷新消费 `overseasAccessToken: string | null` 与秒单位 `overseasExpiresIn`;海外请求缺 Token、临近过期或收到 401 时统一触发一次国内刷新并使用响应中的新海外 Token 重放,不再依赖 `POST /auth/overseas/token`。共享认证定向 19 个测试已通过;前端后续全量 typecheck 与 build 也已通过。
合作仓协同状态:Admin 已启用 `OVERSEAS_PARTNER` 的类型、筛选、新增、编辑与保存透传,普通 `OVERSEAS` 保持独立;前端定向 30 个测试、全量 1144 个测试、typecheck 与 build 均通过。前端不调用 `/internal/warehouses/overseas-partners`,该接口只属于未来海外报价服务的服务间契约。
## 本轮直接收口
- Auth 海外 Token Claims 改为与 Gateway、可信身份头和海外服务一致的 `user_id`、`tenant_id`、`membership_id`、`app_code`、`client_type`、`permission_version`,保留 `roles` 与 `authorities` 授权快照。
- Auth 登录、刷新共用一次权限快照并同时签发国内 Token 与 `overseasAccessToken`;`overseasExpiresIn` 单位为秒。海外 JWT 未启用的本地配置下两字段分别为 `null`、`0`。
- 港务船期与船司查询的只读 Controller、静态 OpenAPI、模块 SQL、统一 SQL 和契约测试统一使用 `*:list`;初始化脚本显式删除旧 `*:view` 角色关联与资源,不执行数据库操作。
- 国内 Warehouse 新增 `OVERSEAS_PARTNER` 海外合作仓类型,覆盖保存、筛选、响应、导入和 SQL 注释,并提供受内部服务令牌保护的启用合作仓候选接口;`mvn -pl warehouse -am test` 通过(192 个测试)。海外报价创建读取合作仓采用内部服务调用与 30 分钟缓存,缓存未命中时强制刷新一次。
- 验证:`mvn -pl auth,gateway-overseas -am test` 通过(33 个测试);`mvn -pl firstleg -am test` 通过(781 个测试,0 失败、0 错误、2 个既有跳过)。