货柜管理全链验收矩阵
更新时间:2026-08-14
当前任务:019ff90b-a72d-7000-abdf-e5363357a564
父任务:019ff600-f9f1-78f1-a357-7c80c13e574e
依赖任务:后端 019ff90b-9b45-7191-b68f-c3b52567e3e4、Admin 019ff90b-a037-79b0-b945-8f88bdbde9c5
边界:只维护根目录脚本、验收文档和测试矩阵;不修改 Admin 或 Java 业务源码,不部署、不触发 Jenkins、不写测试环境数据库。
验收口径
- 本矩阵以当前对话、三期产品确认版开发规划和实际冻结契约为准。旧确认单中的待确认项不覆盖后续已冻结结论。
- 已冻结能力按事实来源落具体路径和断言;尚未冻结能力继续只保留能力级占位,不预设 HTTP 方法、路径、DTO 字段或业务错误码。
- 自动化必须通过业务 API 生成数据;人工验收必须能从 Admin/PDA 可见入口点击到对应状态。不得以数据库直写、mock、原型或前端本地假状态代替。
- 每次真实 HTTP 验收记录请求用途、响应状态、业务码、
requestId、traceId、关键资源 ID 和清理/保留策略;敏感凭据不得写入报告。
- 柜态看板不纳入本轮。
状态数据目录
| 数据代号 |
必备状态/形态 |
生成前置 |
自动化断言 |
人工可点击入口 |
当前状态 |
| CT-D01 |
已确认订单 CONFIRMED,尚无柜次 |
可创建并确认订单 |
确认后自动产生唯一柜次;重复事件不重复建柜 |
订单详情可进入关联柜次 |
待契约 |
| CT-D02 |
不同渠道各一单 |
渠道主数据可用 |
柜次/清单/任务不得跨渠道混装或串查 |
排柜候选可按渠道辨识 |
待契约 |
| CT-D03 |
已排柜但无真实柜号 |
临时柜身份可生成 |
不要求真实柜号即可排柜,内部身份稳定 |
预装清单可查看“待补号”柜次 |
待契约 |
| CT-D04 |
已补真实柜号、PDA 可领取 |
CT-D03 |
补号后 PDA 入口开放且关联原内部柜身份 |
PDA 任务列表可进入 |
待契约 |
| CT-D05 |
作业中更换真实柜号 |
CT-D04,PDA 已开始 |
柜号变化但柜次 ID、任务、清单、证据归属不漂移 |
详情与 PDA 同步显示新柜号 |
待契约 |
| CT-D06 |
预装清单已生成/确认 |
CT-D03 |
清单版本、订单明细、数量及确认历史可追溯 |
预装清单列表/详情可点击 |
待契约 |
| CT-D07 |
装柜清单进行中/已完成 |
CT-D04 |
装载明细、数量、状态与预装来源一致 |
装柜清单列表/详情可点击 |
待契约 |
| CT-D08 |
PDA 领取、拣货、复核、异常摘要 |
CT-D04 |
overview 分别返回 taskStatus、workflowStatus、任务 ID、版本、计数、photoCounts、photos、downloadPath 和异常原因;逐照片代理下载成功 |
PDA 可完成主流程;Admin 入口待回传 |
服务端已冻结;人工入口待定 |
| CT-D09 |
报关/清关资料及有效回执 |
CT-D06 |
目的港清关走货柜 /clearance;出口报关走 loading-list /customs;分别验证上传、完成和完成后替换锁定 |
报关协同入口待回传 |
服务端已冻结;人工入口待定 |
| CT-D10 |
DO/PU 未齐、部分完成、全部完成 |
柜次与运输协同已建立 |
DELIVERY_ORDER、PICKUP_ORDER 可独立查询、上传和鉴权下载,版本与幂等有效 |
柜次详情入口待回传 |
服务端已冻结;人工入口待定 |
| CT-D11 |
正常、异常、取消异常 |
任意有效柜次及显式货柜版本 |
标记/取消使用版本和必填原因;overview 保留 MARK/CANCEL 全部历史 |
货柜详情入口待回传 |
服务端已冻结;人工入口待定 |
| CT-D12 |
多节点运输轨迹与操作日志 |
CT-D10 |
overview 时间线含运输更新、异常和 PDA 事件,按发生时间升序 |
详情时间线入口待回传 |
服务端聚合已冻结;人工入口待定 |
| CT-D13 |
满足全部 LOADED 硬门禁 |
订舱、拖车、有效放行回执、PDA、五类证据完成 |
仅全部满足时进入 LOADED,重复完成幂等 |
订单/柜次详情显示完成且编辑锁定 |
待契约 |
全链验收用例
| 用例 |
场景 |
服务端/契约断言 |
UI/设备断言 |
证据要求 |
状态 |
| CT-E01 |
CONFIRMED 自动建柜 |
状态事件自动建一个柜次;重放幂等;失败可观测 |
订单详情无需手工建柜即可看到柜次 |
前后资源 ID、事件/日志 |
待契约 |
| CT-E02 |
渠道隔离 |
不同渠道不能进入同一排柜结果;交叉 ID 请求失败 |
候选、清单和详情不串渠道 |
双渠道正向及交叉负向响应 |
待契约 |
| CT-E03 |
无真实柜号排柜 |
临时身份可完成排柜/预装;真实柜号字段可空 |
页面明确展示待补号,不伪造柜号 |
柜次 ID、预装版本 |
待契约 |
| CT-E04 |
补号开放 PDA |
合法补号后任务可领取;未补号时领取被稳定阻止 |
补号前后 PDA 入口状态同步 |
补号审计、领取响应 |
待契约 |
| CT-E05 |
作业中换号身份不漂移 |
只变更展示柜号;柜次 ID、任务 ID、清单、证据关联不变 |
Admin/PDA 刷新后显示新号且进度不丢 |
换号前后关联快照 |
待契约 |
| CT-E06 |
预装/装柜清单 |
生成、确认、版本、装载数量及来源关系完整 |
两类列表和详情均可人工点击 |
清单响应与页面截图 |
待契约 |
| CT-E07 |
PDA 主链 |
领取、扫码、批量提交、复核、完成;幂等与版本冲突有效 |
真机/目标设备可完成,失败不假成功 |
请求链、设备记录 |
待契约 |
| CT-E08 |
PDA 进度异常摘要 |
GET /api/platform/v1/containers/{id}/overview 返回 PDA taskStatus/workflowStatus、任务身份、版本、计数、照片摘要、文件 ID 与鉴权下载路径;每个路径真实 GET 200 |
Admin 入口待回传 |
overview 响应、字段完整性及二进制下载证据 |
服务端契约已冻结 |
| CT-E09 |
清关/报关资料闭环 |
目的港清关:货柜 /clearance 查询/上传/完成;出口报关:loading-list /customs 查询/上传/完成;两者完成后均禁止替换 |
Admin 入口待回传 |
两条专用链路的版本、幂等、完成和锁定负向响应 |
服务端契约已冻结 |
| CT-E10 |
DO/PU |
通用查询、multipart 上传、鉴权下载;上传要求 Idempotency-Key、真实文件、expectedVersion,重放不得重复上传 |
Admin 入口待回传 |
两类型响应、文件哈希/ID、二进制下载、幂等重放 |
服务端契约已冻结 |
| CT-E11 |
货柜异常及取消历史 |
POST/DELETE /api/platform/v1/containers/{id}/exception 要求 expectedVersion 和必填原因;冲突失败;overview 历史只追加不覆盖 |
Admin 入口待回传 |
标记/取消响应、版本冲突、overview 历史 |
服务端契约已冻结;版本来源阻断 |
| CT-E12 |
运输轨迹/日志 |
overview timeline 聚合 TRANSPORT_UPDATE、MARK/CANCEL、PDA_*,时间升序且含详情、操作者和发生时间 |
Admin 入口待回传 |
overview 时间线响应 |
服务端契约已冻结 |
| CT-E13 |
LOADED 正向与逐项负向 |
五项硬门禁分别缺失时 fail-closed;全部满足后只迁移一次 |
完成后详情锁定,状态一致 |
5 个负向 + 1 个正向 + 幂等重放 |
待契约 |
| CT-E14 |
跨客户与跨仓库隔离 |
交叉资源 ID 不可读写下载,不泄露资源存在性 |
页面无越权入口 |
双身份交叉请求证据 |
待契约 |
契约冻结清单
既有冻结基线
以下能力在本轮新增 overview 契约之前已经由三期产品确认版、既有 OpenAPI/Controller 和专项测试冻结。本轮不重定义其路径或状态机。
| 能力标识 |
冻结边界 |
事实来源 |
状态 |
confirmed-auto-container |
CONFIRMED 自动建柜、幂等和唯一性 |
三期产品确认版及既有订单/货柜契约 |
既有冻结,待环境验收 |
channel-isolation |
渠道隔离与禁止跨渠道混装 |
三期产品确认版及既有排柜契约 |
既有冻结,待环境验收 |
container-number-lifecycle |
无真实柜号排柜、补号开放 PDA、作业中换号身份稳定 |
既有预装/货柜/PDA 契约 |
既有冻结,待环境验收 |
preload-and-loading-list |
预装与装柜清单状态、版本、明细和历史 |
既有 Loading List OpenAPI/Controller/DTO |
既有冻结,待环境验收 |
customs-documents-lock |
清关/报关专用流程、完成态禁止替换 |
既有 LoadingListService、专用 Controller 与专项测试 |
既有冻结,待环境验收 |
本轮新增冻结契约
事实来源:baiyue-firstleg/firstleg/src/main/resources/openapi/phase3-container-overview-v1.yaml、PlatformContainerController、ContainerOverviewDtos、ContainerOverviewService、LoadingListService。
| 能力标识 |
冻结路径与字段 |
权限/并发 |
状态 |
container-overview |
GET /api/platform/v1/containers/{id}/overview;聚合 container、loadingPlanId、PDA 摘要、documents、exception/history、timeline |
platform:firstleg:container:list;旧 container:view 已移除 |
已冻结 |
pda-progress-exception-summary |
PDA taskStatus/workflowStatus、任务 ID/版本、明细计数、photoCounts、photos(含 fileId/status/downloadPath)及异常原因;照片下载为 GET /api/platform/v1/containers/{id}/pda/photos/{fileId}/download |
随 overview 查看权限;下载复核柜次、计划、入库单与文件归属 |
已冻结 |
container-abnormal-history |
POST/DELETE /api/platform/v1/containers/{id}/exception;请求使用 overview 返回的 container.version、必填原因和幂等键 |
platform:firstleg:container:edit;版本冲突 fail-closed |
已冻结 |
container-documents |
通用查询、multipart 上传和受控文件下载仅支持 DO/PU;下载透传已校验 Content-Type,非法类型回退 application/octet-stream,并返回 UTF-8 文件名、no-store 和内容长度 |
查询/下载用 platform:firstleg:container:list,上传用 platform:firstleg:container:edit;旧 container:view 已移除;下载校验柜次、类型、文件 ID 及文件服务 tenant/business 归属 |
已冻结 |
do-pu |
DELIVERY_ORDER、PICKUP_ORDER 通用查询/上传/下载 |
同 container-documents |
已冻结 |
transport-trajectory-log |
overview timeline 的事件类型、详情、操作者、发生时间;服务端升序 |
随 overview 查看权限 |
已冻结 |
最终安全分流
- overview 与通用 documents 只覆盖
DELIVERY_ORDER、PICKUP_ORDER,不得向通用路径传清关或报关类型。
- 目的港清关使用
/api/platform/v1/containers/{id}/clearance 及其专用上传、完成动作,权限为 platform:firstleg:customs:manage。
- 出口报关使用
/api/platform/v1/first-leg/loading-lists/{planId}/customs 及其专用上传、完成动作;查询使用 platform:firstleg:loading-list:list,旧 loading-list:view 已移除,写入使用 platform:firstleg:customs:manage。
- 清关和出口报关分别验证完成态禁止替换,不能用 DO/PU 通用上传替代。
- 下载允许透传经校验的 Content-Type,非法值回退二进制类型;同时必须保留 UTF-8 文件名、
no-store、内容长度及资源归属复核。
自动化落地门禁
真实环境脚本只有在对应能力“已冻结=是”后才能加入请求步骤,并必须满足:
- 环境地址、账号和令牌只从环境变量读取。
- 默认不执行;必须通过显式运行参数开启真实 HTTP。
- 只通过业务 API 造数,不连接数据库,不调用 Jenkins。
- 支持按本次运行标识检索资源,避免误用历史数据;清理动作仅在契约明确且安全时启用。
- 输出脱敏 JSON 报告,逐请求记录 HTTP 状态、业务码、
requestId、traceId 和资源 ID。
- 对未冻结能力或冻结来源不一致输出
BLOCKED_CONTRACT,不得以跳过后仍报告全链通过。
当前阻断
| 阻断 |
影响 |
解除条件 |
| 测试环境未获得部署授权且本任务禁止部署 |
无法验证环境是否已包含依赖实现 |
人工部署明确提交后,再执行获授权的验收轮次 |
| 未提供测试环境凭据和两组隔离身份 |
无法执行跨客户/跨仓库/下载鉴权负向用例 |
由总控提供临时验收身份或既有安全注入方式 |
Marker 回归增量(ADMIN-API-20260814032734876)
| 回归项 |
当前冻结事实与自动化断言 |
当前结论 |
| Release 正式 DTO |
POST /api/platform/v1/ocean-bookings/{id}/release 已冻结;ReleaseRequest 必填提单号、船名、航次、ETD、ETA,并保留 expectedVersion。HTTP fixture 必须携带五字段;Admin 未填齐不得调用 release |
LANDED,不是路径阻断 |
| PDA overview 状态语义 |
PDA 任务的 taskStatus=LOADING 与业务流转 workflowStatus=AWAITING_REVIEW 必须分字段返回;进度 100%、未解决数为 0 且任务仍为 LOADING 时必须明确为 AWAITING_REVIEW |
后端 DTO/OpenAPI/聚合已回传;LANDED,待环境 HTTP 验收 |
| PDA overview 照片下载 |
对 photos[] 每个服务端 downloadPath 执行真实鉴权 GET;仅接受站内 /api/ 路径、HTTP 200、非空二进制和非 JSON/HTML Content-Type |
HTTP 回归已准备;待获授权环境验收 |
| 客户公开名称一致性 |
customerId 筛选后的订舱、拖车和预装列表/详情必须显示 IAM tenantName,不得优先 legalName;列表、详情及关联名称一致 |
列表筛选与拖车预约新增表单已统一 tenantName;LANDED,待人工筛选回归 |
已有 containerNo 动作语义 |
已有真实柜号时补号动作不可伪装成首次补号;换号前后柜次 ID、PDA taskId、loadingPlanId 和证据归属必须稳定 |
Admin 已按柜号是否存在显示“录入集装箱号/修改集装箱号”,后端 HTTP fixture 已锁定身份稳定;LANDED |
| 订舱/拖车详情关联名称 |
详情中的客户、柜次、订舱及关联资源名称必须来自正式详情响应,并与同 ID 列表显示一致 |
后端详情已返回稳定名称字段,Admin 使用详情快照与受控候选回显;LANDED |
| 拖车附件闭环 |
POST /truck-appointments/{id}/attachments 引用、POST /truck-appointments/{id}/attachments/upload 上传关联与 DELETE /truck-appointments/{id}/attachments/{attachmentId} 已冻结 |
Admin 已提供选择文件、上传并关联、列表及删除入口,HTTP 删除后回查已覆盖;LANDED |
| 中文状态、弹框与 390px 布局 |
列表/详情状态必须中文;release、附件、柜号动作使用正式弹框;390px 下字段、按钮、弹框不横向溢出或遮挡 |
AWAITING_REVIEW、照片类型、确认按钮已中文化,放舱/改船/附件弹框已落地;桌面与 390px 浏览器无横向溢出;LANDED |
说明:BLOCKED_CONTRACT 仅标记明确缺失的 DTO 字段或 Admin 承载,不把已存在的 release、拖车附件 API 路径降级为未冻结能力。
订舱物流渠道与柜次隔离增量
| 验收项 |
自动化断言 |
当前结论 |
| Admin 渠道选择 |
订舱新增/编辑不允许自由输入 channelCode/channelName;选择起运仓后使用渠道下拉,查询必须携带 originWarehouseId |
LANDED:Admin 使用受控渠道下拉并调用正式平台渠道接口;Admin 与根静态合同均锁定渠道选择正向及自由输入负向 |
| 平台渠道目录 |
GET /api/platform/v1/ocean-bookings/channels?originWarehouseId=... 只返回当前 ACTIVE 价格簿渠道;HTTP fixture 记录本轮 marker、originWarehouseId 与服务端路径,不借 Merchant 身份或历史资源 |
OpenAPI 已冻结;真实查询生产者已发布 createdResources.platformLogisticsChannels |
| 双有效渠道 fixture |
跨渠道负向必须使用同一起运仓下两个真实有效渠道;只有一个有效渠道时输出 BLOCKED_FIXTURE,禁止派生 -OTHER 伪渠道 |
脚本门禁与正式渠道生产者已落地;待环境数据验证是否存在双渠道 |
| 船公司与物流渠道独立 |
shippingCompanyId/shippingCompanyName 与渠道选择分别建模,不用船公司字段代替渠道字段 |
LANDED:Admin 与写请求模型分别承载船公司和物流渠道,静态合同已转绿 |
CONFIRMED 柜次继承渠道 |
订舱确认生成柜次后,货柜详情 channelCode 必须等于所选有效渠道;异渠道入库单不能分配到该柜次 |
既有 HTTP 断言保留;异渠道负向已移除伪渠道来源;写 DTO 不再发送服务端拥有的 channelName |
订舱资料字段与可选客户增量
事实来源:原型 prototype-src/modules/06-containers.html、P3-Q14、OceanBookingDtos.DraftData、ocean-bookings-v1.yaml、Admin OceanBookingDetailView.vue 与 OceanBookingDraftData。
| 字段/链路 |
原型与阶段时序 |
自动化断言 |
当前结论 |
serviceTerm |
原型第 516 行以 * 标记主要运输条款必填;P3-Q14 未删除该业务快照 |
Admin 必填自由文本;Java @NotBlank;OpenAPI required 且非 nullable;模块基线和统一 SQL 均为 NOT NULL;不保留无来源的 CY-DOOR/DOOR-CY/DOOR-DOOR 自造字典;验收 fixture 使用原型展示值 CY-CY |
LANDED |
freightTerm |
原型第 518 行以 * 标记运费条款必填;示例值为 NINGBO,不构成枚举事实来源 |
Admin 必填自由文本;Java @NotBlank;OpenAPI required 且非 nullable;模块基线和统一 SQL 均为 NOT NULL;不保留无来源的 PREPAID/COLLECT 自造字典;验收 fixture 使用原型展示值 NINGBO |
LANDED |
| 可选客户 |
原型第 527 行“客户/公司名称”无必填标记;当前产品确认允许平台先建订舱后关联客户 |
Admin 可清空选择;前端类型、Java DTO 与 OpenAPI 均允许 customerId/customerName 同时为空,单边填写必须拒绝 |
LANDED |
| 无客户 HTTP fixture |
不以历史客户或占位 ID/名称替代可空契约 |
ocean-bookings 使用本轮 marker、正式渠道和仓库创建无客户订舱,详情回读真实 bookingNo 后按订舱号查询列表,断言空客户快照、CONFIRMED 及稳定柜次;发布 createdResources.oceanBookingUnassignedCustomer |
已准备,待部署后 HTTP 验收 |
| 指定客户隔离链 |
保留来自本轮入库单的正式客户范围 |
phase3-container-loading 与既有订舱主链继续断言客户、仓库、渠道一致和跨渠道拒绝,不借历史资源 |
已准备,待部署后 HTTP 验收 |
| 提单号、船名、航次、ETD、ETA |
原型存在相关展示/录入字段,但 P3-Q14 明确真实运输数据在 RELEASE 补录,阶段时序覆盖草稿直接编辑方式 |
草稿页面仅只读展示,OceanBookingDraftData 和保存 payload 不含五字段;确认放舱弹框与 ReleaseRequest 必须完整携带五字段 |
LANDED |
| 单证号 |
原型第 529 行存在“单证号”,但当前阶段 DTO/OpenAPI 未冻结对应写字段 |
不猜字段名或复用提单号;本轮不扩展写契约 |
非本轮能力,不标记接口阻断 |
离线合同:ocean-booking-prototype-contract.test.mjs 锁定原型证据、跨端可选客户、条款字段、草稿/放舱时序;ocean-booking-fixture-contract.test.mjs 与 full-regression-entry-contract.test.mjs 锁定无客户/指定客户双链和默认编排。