diff --git a/三期/货柜管理全链验收矩阵-2026-08-13.md b/三期/货柜管理全链验收矩阵-2026-08-13.md index 6e7d0e0..46d47c8 100644 --- a/三期/货柜管理全链验收矩阵-2026-08-13.md +++ b/三期/货柜管理全链验收矩阵-2026-08-13.md @@ -18,10 +18,10 @@ | 数据代号 | 必备状态/形态 | 生成前置 | 自动化断言 | 人工可点击入口 | 当前状态 | |---|---|---|---|---|---| -| CT-D01 | 线下已确认真实订舱登记为 `CONFIRMED`,尚未关联内部柜 | 创建请求必须携带提单号、船名、航次、预计开船/到港五项运输快照 | 登记直接产生 `CONFIRMED` 真实订舱事实,不自动创建内部柜;DRAFT/SUBMITTED 不进入正式列表 | 订舱列表只显示已确认及后续状态 | 已冻结,待环境验收 | +| CT-D01 | 线下已确认订舱登记 N 个真实柜 | 创建请求必须携带五项运输快照及 `containers[1..20]`;每柜唯一 `containerNo` 和固定规格 | 同一事务直接产生 `CONFIRMED`、N 个 quantity=1 requirement、N 个 `OCEAN_BOOKING/ACTIVE` 操作柜及 N 个 allocation;任一柜失败整单零写入 | 订舱和货柜列表均可逐柜打开 | 已冻结,待环境验收 | | CT-D02 | 不同渠道各一单 | 渠道主数据可用 | 柜次/清单/任务不得跨渠道混装或串查 | 排柜候选可按渠道辨识 | 待契约 | | CT-D03 | 内部模拟柜已排货、已 push,但无真实柜号/订舱 | 正式装柜仓库、ACTIVE 物流渠道、箱型和容量可用 | 服务端生成稳定 `containerBookingId/cabinetNo`;同仓同渠道 WAIT_SPLIT 可排;无号 `push-preload` 成功并冻结明细、建立唯一 bridge、使预装 `EDITING` 可见,但 PDA 查询必须为 `A0404` | 货柜列表可新增模拟柜,预装清单显示待关联/待补号 | 新时序已冻结,待环境验收 | -| CT-D04 | 已补真实柜号、已关联并放舱、预装已确认,PDA 可领取 | CT-D03;预装 `EDITING` 补号;关联 `CONFIRMED` 订舱并进入 `RELEASED`;预装进入 `CONFIRMED` | 三项前置任缺一项都无 PDA;最后一个前置到达后恰好生成一个任务,任务四元身份关联原内部柜;claim 前订单仍 `WAIT_SPLIT`,claim 后才进入 `LOADING` | PDA 任务列表可进入 | 新时序已冻结,待环境验收 | +| CT-D04 | 模拟柜合并真实柜、订舱放舱且预装已确认,PDA 可领取 | CT-D03;选择未消费 `OCEAN_BOOKING/ACTIVE` 真实柜合并;订舱进入 `RELEASED`;预装进入 `CONFIRMED` | link 将真实柜号/订舱/规格快照原子复制到原模拟柜,任务四元身份只使用存活的模拟柜 ID;三项前置任缺一项都无 PDA,claim 后才进入 `LOADING` | PDA 任务列表可进入 | 新合并契约已冻结,待环境验收 | | CT-D05 | 作业中更换真实柜号 | CT-D04,PDA 已开始 | 柜号变化但柜次 ID、任务、清单、证据归属不漂移 | 详情与 PDA 同步显示新柜号 | 待契约 | | CT-D06 | 预装清单已生成/确认 | CT-D03 | push 后 `EDITING` 清单可补真实柜号;订舱 `RELEASED` 后通过计划级 `/loading-plans/{loadingPlanId}/confirm` 原子确认全部关联预装票据,返回 `confirmationStatus=CONFIRMED`、`readyForPda=true` 和唯一 `pdaTaskId`;版本、明细、数量及确认历史可追溯 | 预装清单列表/详情可点击 | 计划级确认已冻结,待环境验收 | | CT-D07 | 装柜清单进行中/已完成 | CT-D04 | 装载明细、数量、状态与预装来源一致 | 装柜清单列表/详情可点击 | 待契约 | @@ -36,10 +36,10 @@ | 用例 | 场景 | 服务端/契约断言 | UI/设备断言 | 证据要求 | 状态 | |---|---|---|---|---|---| -| CT-E01 | 模拟柜显式关联真实订舱柜 | `CONFIRMED` 不自动建柜;模拟柜排货后首次 link 成功且内部身份/明细稳定 | 货柜详情可从正式订舱候选显式关联 | link 前后柜次、计划、明细及订舱分配快照 | 已冻结,待环境验收 | +| CT-E01 | 模拟柜原地合并真实订舱柜 | 订舱创建的真实柜先以 `OCEAN_BOOKING/ACTIVE` 出现在货柜列表;link 请求只传 `realContainerBookingId+expectedVersion`,成功后模拟柜 ID/cabinetNo/计划/明细稳定,来源变 `MERGED` 且 allocation 改指模拟柜 | 货柜详情只显示合并后的一个可操作身份 | link 前后柜次、计划、明细、allocation 及 ACTIVE 列表唯一性快照 | 已冻结,待环境验收 | | CT-E02 | 渠道隔离 | 不同渠道不能进入同一排柜结果;交叉 ID 请求失败 | 候选、清单和详情不串渠道 | 双渠道正向及交叉负向响应 | 待契约 | | CT-E03 | 无真实柜号排柜与 push | 临时身份可完成排柜;`push-preload` 在无 `containerNo` 时成功,只冻结计划、建立 bridge、开放 `EDITING` 预装,不创建 PDA;exact replay 原样返回且计划/版本/历史/link/task 零漂移 | 页面明确展示待补号,不伪造柜号 | push 原始 path/body/key、重放前后全快照、PDA `A0404` | 新时序已冻结,待环境验收 | -| CT-E04 | 补号及三项前置开放 PDA | 预装 `EDITING` 补号后身份稳定;未关联订舱、订舱未 `RELEASED`、预装未 `CONFIRMED` 分别查询 PDA 均为 `A0404`;最后一个前置完成后仅生成一个 task,claim 才推进 `LOADING` | 补号、关联、放舱、确认前后 PDA 入口状态同步 | 三个逐项负向、唯一 task 四元身份、claim 前后状态 | 新时序已冻结,待环境验收 | +| CT-E04 | 合并及三项前置开放 PDA | 无号 push 后仍无 PDA;未合并真实柜、订舱未 `RELEASED`、预装未 `CONFIRMED` 分别查询 PDA 均为 `A0404`;合并本身带入唯一真实柜号,最后一个前置完成后仅生成一个 task,claim 才推进 `LOADING` | 关联、放舱、确认前后 PDA 入口状态同步 | 三个逐项负向、唯一 task 四元身份、禁止 MERGED 来源 ID、claim 前后状态 | 新合并契约已冻结,待环境验收 | | CT-E05 | 作业中换号身份不漂移 | 只变更展示柜号;柜次 ID、任务 ID、清单、证据关联不变 | Admin/PDA 刷新后显示新号且进度不丢 | 换号前后关联快照 | 待契约 | | CT-E06 | 预装/装柜清单 | push 自动生成/关联预装聚合;仅允许按 `loadingPlanId` 原子确认整份计划,禁止旧单票 `/preload/confirming`、`/preload/confirm`;返回唯一 task 后 claim 才进入 `LOADING` | 两类列表和详情均可人工点击 | `PENDING -> EDITING -> CONFIRMED`、计划版本、readiness、taskId、幂等重放与历史 | 计划级确认已冻结,待环境验收 | | CT-E07 | PDA 主链 | 领取、扫码、批量提交、复核、完成;幂等与版本冲突有效 | 真机/目标设备可完成,失败不假成功 | 请求链、设备记录 | 待契约 | @@ -53,10 +53,10 @@ | CT-E15 | push 幂等、冲突与事务回滚 | 首次成功请求冻结 path/body/expectedVersion/key;同 key 原样重放只读且返回首次结果;同 key 异参、新 key 重复均冲突;各负向后计划、版本、历史、bridge、PDA 全快照零漂移;首次 push 在 bridge 中途失败时整事务零残留且不得触发 PDA | 冲突或失败后页面刷新仍只显示首次成功事实 | 原始请求、三次回查全快照、失败 `requestId/traceId`;中途失败由后端事务合同覆盖 | 新时序合同已冻结,待环境验收 | | CT-E16 | 默认 Admin HTTP 同 marker 完整链 | 默认入口按 `phase3-container-loading -> phase3-loading -> overview/PDA/evidence -> customs -> loading-finalize` 串行;下游只消费 `phase3Loading` 发布的 `taskId/inboundId/loadingPlanId/containerBookingId`,最终同一订单详情和列表均为 `LOADED` | 同一批次可从订单、柜次、预装、PDA、报关入口逐级回查 | 全新 marker、关键资源 ID、五类二进制证据、各请求 `requestId/traceId`、最终统一订单状态 | 静态合同已接入默认入口,待环境 HTTP | -## 新时序冲突待总控统一 +## P3-Q14 文档同步待总控统一 -- 当前冻结验收时序以用户最新确认的“先建内部模拟柜,再排货并无号 push,随后在预装 `EDITING` 补真实柜号、关联已确认订舱并放舱、确认预装,最后生成 PDA task”为准。 -- `docs/三期/三期需求确认表.md` 的 P3-Q14 仍写有“订舱创建时按箱型需求数量生成内部柜次”,与“订舱 `CONFIRMED` 不自动建内部柜、由模拟柜显式关联”的最新事实冲突。本任务不擅改需求确认表,状态标记为 `WAIT_CONTROLLER_RESOLUTION`,由总控统一产品事实后再更新 P3-Q14。 +- 当前冻结验收时序以用户最新确认的“两类柜并存”为准:订舱逐柜登记会生成可直接排货的 `OCEAN_BOOKING/ACTIVE` 真实柜;未订舱时也可先建 `SIMULATION/ACTIVE` 模拟柜并排货、无号 push,之后按 `realContainerBookingId` 原地合并一个未消费真实柜。 +- `docs/三期/三期需求确认表.md` 的 P3-Q14 尚未完整描述 `SIMULATION/ACTIVE -> 合并 -> OCEAN_BOOKING/MERGED` 的来源/状态模型。本任务不擅改需求确认表,标记为 `WAIT_CONTROLLER_DOC_SYNC`,由总控统一文档;本矩阵及自动化以当前冻结 DTO/OpenAPI 为准。 - P3-Q14 关于“五项运输快照在订舱创建时冻结、`RELEASED` 不覆盖首次快照”的部分无冲突,继续作为验收基线。 ## 契约冻结清单 @@ -67,10 +67,10 @@ | 能力标识 | 冻结边界 | 事实来源 | 状态 | |---|---|---|---| -| `simulation-container-link` | `CONFIRMED` 只形成真实订舱事实;内部模拟柜由货柜入口创建并显式关联,旧自动建柜语义已移除 | `PlatformContainerController`、`ContainerService`、`OceanBookingService`、`firstleg-v1.yaml`、`ocean-bookings-v1.yaml` | 本轮目标冻结,待环境验收 | +| `booking-real-containers-and-simulation-merge` | 订舱按 `containers[]` 原子生成真实柜;模拟柜是独立预排货能力;link 消费一个真实柜并保留模拟柜稳定身份,正常列表只返回 ACTIVE | `PlatformContainerController`、`ContainerService`、`OceanBookingService`、`firstleg-v1.yaml`、`ocean-bookings-v1.yaml` | 本轮目标冻结,待环境验收 | | `channel-isolation` | 渠道隔离与禁止跨渠道混装 | 三期产品确认版及既有排柜契约 | 既有冻结,待环境验收 | -| `container-number-lifecycle` | 无真实柜号允许排柜及 push;push 本身不开放 PDA;预装 `EDITING` 补号后内部柜、计划、bridge 身份稳定;作业中换号身份稳定 | `SmartLoadingService`、`SplitPreloadService`、`LoadingListService`、相关 OpenAPI 与合同测试 | 新时序已冻结,待环境验收 | -| `preload-and-loading-list` | `PENDING -> EDITING -> CONFIRMED`;计划级确认原子确认全部关联票据并唯一建 task;关联 `RELEASED` 订舱、真实柜号和 readiness 全部满足后 `readyForPda=true`,claim 才推进 `LOADING` | `LoadingListService.confirmPreload`、`LoadingPickService`、`POST /loading-plans/{planId}/confirm` 及 Loading List OpenAPI/DTO | 计划级确认已冻结,待环境验收 | +| `container-number-lifecycle` | 模拟柜无真实柜号允许排柜及 push;push 本身不开放 PDA;link 从未消费真实柜带入唯一 `containerNo`,内部柜、计划、bridge 身份稳定;作业中换号身份稳定 | `ContainerService`、`SmartLoadingService`、`SplitPreloadService`、`LoadingListService`、相关 OpenAPI 与合同测试 | 新时序已冻结,待环境验收 | +| `preload-and-loading-list` | `PENDING -> EDITING -> CONFIRMED`;计划级确认原子确认全部关联票据并唯一建 task;存活 ACTIVE 柜已合并 `RELEASED` 订舱、真实柜号和 readiness 全部满足后 `readyForPda=true`,claim 才推进 `LOADING` | `LoadingListService.confirmPreload`、`LoadingPickService`、`POST /loading-plans/{planId}/confirm` 及 Loading List OpenAPI/DTO | 计划级确认已冻结,待环境验收 | | `customs-documents-lock` | 清关/报关专用流程、完成态禁止替换 | 既有 `LoadingListService`、专用 Controller 与专项测试 | 既有冻结,待环境验收 | ### 本轮新增冻结契约 @@ -161,10 +161,13 @@ |---|---|---| | 正式订舱列表 | 仅允许 `CONFIRMED/CHANGE_PENDING/RELEASED/CANCELLED`;`DRAFT/SUBMITTED` 查询失败且默认列表不返回未确认记录;内部模拟柜不进入订舱列表 | 契约与 HTTP fixture 已落地,待部署后验证 | | 新增内部模拟柜 | `POST /api/platform/v1/containers` 只接收正式装柜仓库、当前 ACTIVE 物流渠道、箱型、容量和限重;不接收真实柜号或订舱;服务端生成稳定 `containerBookingId/cabinetNo` | 契约与 HTTP fixture 已落地,待部署后验证 | -| 排货后首次关联 | 同仓、同渠道、箱型/容量/限重及指定客户范围一致时,允许已有预排货的 `EDITING` 模拟柜首次 `POST /containers/{id}/ocean-booking-link`;关联前后柜次、计划和明细身份不变 | 契约与 HTTP fixture 已落地,待部署后验证 | -| 隔离与唯一占用 | 跨仓、跨渠道、箱型/容量/客户范围不匹配拒绝;同一 `requirementId` 的真实订舱容量只能关联一次;双渠道负向必须来自同仓真实 ACTIVE 渠道,否则报告 `BLOCKED_FIXTURE` | 静态合同已锁定;双渠道和主要 HTTP 负向待部署后验证 | +| 订舱逐柜建柜 | `POST /ocean-bookings` 必填 `containers[1..20]`;一单至少两柜 fixture 逐项断言唯一柜号、固定规格、独立 requirement/allocation、`OCEAN_BOOKING/ACTIVE` 身份及订舱/货柜列表一致;请求内重复号、全局重复号、行数或规格错误均整单零写入 | DTO/OpenAPI/静态合同及 HTTP fixture 已落地,待部署后验证 | +| 真实柜直接排货 | 未经过模拟柜时,订舱生成的 `OCEAN_BOOKING/ACTIVE` 真实柜本身可创建计划并接收同仓同渠道货物 | 静态契约已冻结;部署后补定向 HTTP 正向 | +| 排货后首次合并 | 同仓、同渠道、箱型/容量/限重及指定客户范围一致时,已有预排货的 `SIMULATION/ACTIVE` 模拟柜可用 `{realContainerBookingId,expectedVersion}` 合并;模拟柜 `containerBookingId/cabinetNo/loadingPlan/items` 不变,真实柜号与运输快照补入 | 契约与 HTTP fixture 已落地,待部署后验证 | +| ACTIVE 唯一操作身份 | 合并后来源真实柜置 `MERGED`、清空 `containerNo`、`mergedIntoContainerBookingId` 指向模拟柜,allocation 改指模拟柜;正常列表/详情只返回一条存活 ACTIVE 操作柜,PDA 禁止使用 MERGED 来源 ID | 静态合同与 HTTP 列表/详情断言已落地,待部署后验证 | +| 隔离与唯一占用 | 跨仓、跨渠道、箱型/容量/限重/客户范围不匹配拒绝;同一 `realContainerBookingId` 在 MERGED 时不可再次关联;所有失败必须保持柜、计划、明细、allocation 和列表零漂移 | 静态合同已锁定;双渠道和主要 HTTP 负向待部署后验证 | | 首次关联不可逆门禁 | 存在 PDA、有效装柜证据、业务单证或已进入 `LOADING/COMPLETED` 时首次 link 拒绝 | 服务端静态门禁已锁定;需部署后以独立 marker fixture 验证 | -| 解绑与换绑 | 完全空的 `WAIT_LOADING` 模拟柜允许 unlink 后 rebind;一旦已有排货、PDA、证据或单证事实,unlink/rebind 均拒绝 | 空柜正向和排货后负向 HTTP fixture 已落地,待部署后验证 | +| 解绑与换绑 | 服务端仍仅允许完全空的 `WAIT_LOADING` 合并柜执行原子 unlink,并恢复来源为 ACTIVE;一旦已有排货、PDA、证据或单证事实,unlink/rebind 均拒绝 | 静态门禁已锁定;排货后负向 HTTP fixture 已落地,待部署后验证 | | 全量编排 | 默认入口先运行 `phase3-container-loading` 完成“模拟柜新增 -> 同仓同渠道排货 -> 首次 link -> PDA”,再由证据、finalize、出仓模块沿本轮 marker 的稳定 ID 继续;禁止历史数据和 mock 回退 | Node 入口合同已锁定,待默认全量 HTTP 验证 | 离线合同:`container-simulation-association-contract.test.mjs` 锁定跨层契约及全量顺序;`phase3-producer-chain-contract.test.mjs`、`phase3-order-splitting-contract.test.mjs`、`ocean-booking-channel-contract.test.mjs` 锁定现有生产者不再依赖 `CONFIRMED` 自动建柜。