Files
baiyue-lastleg/docs/completed-features-report-20260815.md
2026-08-17 09:18:03 +08:00

122 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 尾程平台已完成功能报告(2026-08-15)
## 1. 交付结论
头程装柜完成到尾程订单的真实链路已打通。头程按客户发布
`FirstLegLoadingPlanCompleted V1` 事件,经 Event Bridge 可靠投递后,尾程按事件中
每一笔最终实装入仓单分别落一条订单记录。同一柜的订单记录共享尾程单号,
`sourceInboundId` 作为来源建单唯一标识。
本报告仅描述当前代码和已经取得证据的能力,不把规划中的功能列为已完成。
## 2. 已完成功能
### 2.1 跨区域事件桥
- 接收并持久化版本化事件信封,保存幂等键、负载摘要和冻结 JSON。
- 使用数据库租约领取待投递事件,支持多实例竞争和超时租约恢复。
- `RECEIVED` 与 `RETRY` 都可重新调度,失败采用指数退避,达到上限进入 `DEAD`。
- 每次投递写入 `bridge_delivery_attempt`,记录投递序号、结果、响应码和错误。
- 支持经过内部令牌保护的死信人工补投;成功后才把 Inbox 标记为 `PROCESSED`。
- Event Bridge 与尾程内部接口使用统一的 `X-Internal-Service-Token`。
### 2.2 装柜完成事件消费与尾程建单
- 只接受 `CN -> OVERSEAS`、`LOADING_PLAN`、版本为 1 的装柜完成事件。
- 强制校验实际 `containerNo` 和非空 `orders`,尾程不回查头程数据。
- 事件 Inbox 以 `eventId` 防重复,并校验重复事件的 `payloadHash`。
- 按 `orders` 逐笔创建尾程订单;同柜入仓单共享一个不可碰撞的尾程单号。
- 以 `(tenant_id, source_region, source_inbound_id)` 保证来源入仓单建单幂等。
- 保存根入仓单、来源订单、装柜计划版本、交接版本和来源摘要等追溯字段。
- 保存商品、箱数、数量、托数、重量、体积、目的仓、SKU、FBA 跟踪号、
shipmentNo 和唛头等实装冻结明细。
- 新订单初始化为 `PENDING_ASSIGNMENT`,同步写入状态历史。
- 同一来源入仓单摘要不一致时拒绝静默覆盖。
### 2.3 尾程订单查询与转仓
- 按租户分页查询,支持尾程单号、入仓码、头程订单号、柜号、状态、转仓、
异常、暂扣和创建时间筛选。
- 查询订单详情、实装明细和状态历史。
- 导出 UTF-8 CSV,并处理公式注入风险。
- 支持单笔和批量转仓,更新订单及明细目的仓快照并写状态历史。
- 已生成入库计划的订单禁止再次修改目的仓。
- 普通客户只能查询认证身份对应租户;平台身份必须显式指定客户租户,
不允许通过请求参数任意跨客户查询。
### 2.4 尾程入库计划与 PDA 作业
- 按租户和实际集装箱生成唯一入库计划。
- 保存入仓码明细、目的仓快照、计划托盘和托盘分配关系。
- 按目的仓隔离合托,支持固定容量托盘分配。
- 提供 PDA 任务、操作幂等记录、托盘合并记录及仓库资源锁关联字段。
### 2.5 仓库资源和海外认证边界
- 仓库维护库位、托盘及资源锁,资源锁使用租户幂等键并记录业务归属。
- 仓库数据源启动保护避免 schema 接错后误执行建表脚本。
- 海外 Gateway 使用 JWKS 验证非对称 JWT,校验 `lastleg-api` Audience 及必需 claims。
- 尾程内部事件入口使用常量时间令牌比较;未配置或令牌错误时拒绝消费。
### 2.6 工程规范与数据库交付
- 生产 Spring Bean 的依赖注入已统一为 `jakarta.annotation.Resource`;仅保留配置值
`@Value` 和普通值对象/校验器构造器参数,不把不可变业务值误当作 Bean 注入。
- 新增统一增量入口 `scripts/db/incremental.sql`,按 `001-006` 归档 Event Bridge、尾程订单与入库计划/PDA、仓库资源及仓库主数据的字段、中文注释和索引变更。
- 增量脚本使用 `information_schema` 守卫,45 个动态 DDL 均成对释放,且不包含业务数据写入、删除或清理语句。
## 3. 真实链路验收证据
| 项目 | 结果 |
|---|---|
| loadingPlanId | `2091000814000009002` |
| containerNo | `LLSYNC-CNTR-20260814` |
| tenantId/accountId | `10001` |
| eventId | `88cd0f63-dc9e-4c16-bdb7-c32b20a83c3b` |
| payloadHash | `sha256:23011feff2ff91203fb94ebab7cab8306f58e3e128f61d17913d2f74af5c87f4` |
| Event Bridge 状态 | `PROCESSED` |
| 尾程单号 | `LMO43831679558828067566368238939` |
同一事件实际生成两条入仓单维度订单记录:
| sourceInboundId | 入仓码 | 箱数 | 托数 | 明细数 |
|---|---|---:|---:|---:|
| `2091000814000000301` | `LLSYNC-20260814-IN-01` | 2 | 1 | 1 |
| `2091000814000001301` | `LLSYNC-20260814-IN-02` | 2 | 1 | 1 |
重复投递相同 `eventId` 后接口仍返回成功,数据库订单记录总数保持为 2,未重复建单。
## 4. 数据库交付约定
全量初始化脚本继续由各服务维护:
- `lastleg/src/main/resources/db/lastleg.sql`
- `event-bridge-service/src/main/resources/db/event-bridge.sql`
- `warehouse/src/main/resources/db/warehouse.sql`
从本次交付开始,所有字段和索引变更同时追加到
`scripts/db/incremental.sql`。该文件按日期和序号只追加,已发布段落不得修改;
新增字段和索引必须查询 `information_schema` 后再执行,禁止放入测试数据、
业务数据修复、`DELETE` 或 `TRUNCATE`。
当前归档段为 `001` Event Bridge、`002` 仓库资源、`003` 入库计划/PDA、
`004` Event Bridge 存量字段升级、`005` 尾程订单投影和 `006` 仓库主数据注释/索引。
脚本静态契约校验结果:UTF-8、614 行、45 个 `PREPARE` 与 45 个释放操作,
未包含业务 DML,也未检测到乱码字符。
## 5. 验证结果
- `mvn -pl lastleg -am test`:34 tests passed。
- `mvn -pl event-bridge-service -am test`:15 tests passed。
- `mvn -pl warehouse -am test`:26 tests passed。
- `mvn -pl gateway -am test`:7 tests passed。
- 注入改造额外验证:`integration-service` 1 test passed,`audit-service` 编译通过。
- 生产代码扫描无 `@Autowired`、`@Inject` 或 Lombok 构造器注入残留;文档和 SQL UTF-8 乱码扫描通过。
## 6. 当前未声明完成的范围
- 到港、清关、拆柜、正式入库、出库、派送和签收的完整状态命令链路。
- 前端尾程订单页面。
- 权限冻结事件的海外本地投影和完整生产密钥轮换演练。
- 生产级 mTLS、来源网络白名单、监控告警和灾备演练。