6.6 KiB
F21/F22 实装与部分装柜验收方案
本文件是本阶段的执行方案,不是已通过的 TEST 证据或状态主文档。不直接运行,不访问环境。真实执行必须等总控确认匹配 Firstleg 版本、受控触发器和独占样本窗口;发布、SQL、数据库取证由总控串行负责。凭据只从本轮指定 TEST 环境文件读取,报告不保存密码、Token 或内部服务令牌。
入口与样本
复用 admin-test-env-modules/phase3-container-loading.mjs 的合法订单、审核、测量、分柜、RELEASED 订舱、真实柜号、PDA 领取及五类装柜证据链;复用 phase3-container-customs-fixture.mjs 的客户资格和报关入口。现有全拣场景不能直接替代本方案的 PARTIAL/SKIPPED 场景,也不能直接运行内部模块当作新验收入口。
使用新批次标记 PARTIAL-ACTUAL-<运行时间>、独立客户/订单/柜次/任务。一个任务单请求流,只操作本批次样本;已有柜 TSTU8545690 仅做只读回查,不回填计划、库存、入仓单或重放历史事件。失败停在原样本,保留原请求和失败报告,不盲目重造样本。
最小场景分两柜,沿合法流程分别准备:
| 柜 | 来源与操作 | 验证目的 |
|---|---|---|
| A | 客户甲退税普通 PACKAGE 行计划 3 箱、每箱 7 件,实拣 2 箱并提交 PARTIAL;甲另一 SKU 零拣 SKIPPED;客户乙买单普通行全拣;客户丙退税整票零拣 SKIPPED | 混合客户/税制、部分数量缩放、同票跳过 SKU 与整客户跳过隔离 |
| B | 只有买单行实际装柜;同计划退税票全部 SKIPPED | 实际全买单柜不因计划历史退税票要求客户资料或退税发送 |
从预装详情冻结每行 itemId、客户/来源/明细三键、原箱数、unitsPerCarton、productQuantity、palletCount、重量和体积。件数先按每箱件数×实箱;无每箱件数时按原量比例 HALF_UP 至整数。重量 HALF_UP 至 3 位、体积至 4 位;NULL 保持 NULL。托数按原计划托数比例向上取整。托数为空/0 的标签回退另核对原入仓总箱数、合法确认称重/库位证据,不能用本次实拣总数替换原比例分母。样本中的未知值只来自正式接口允许的输入,不以 SQL 修改事实制造样本。
PDA 正式动作
接口基址为 /api/platform/v1/first-leg/pda-loading,按正式仓绑定会话访问。
- 回读任务、库存和每行版本;通过既有正式扫码/拣货入口取得真实箱码事实。PARTIAL 为最终实箱数,不能把增量当最终数量。
POST /tasks/{taskId}/items/{itemId}/partial:提交warehouseId, finalPickedPackageCount, version, operationId。SKIPPED 使用POST /tasks/{taskId}/items/{itemId}/skip,提交warehouseId, version, operationId, reason,仅限零拣行。- 上传并回查 PHOTO_STEP_1–4 与 SEAL 的五类有效照片和锁码;保留任务及计划全量基线、操作历史、预装冻结行。缺证据拒绝场景优先复用已有证据,不额外销毁照片。
- 在最终完成前回读标签,确认预检没有新增标签或占用冻结编号。内部数据库/序号核验由总控做只读取证;不存在公网独立预检写入口。
- 回读最新任务版本后,只提交一次
POST /tasks/{taskId}/complete,载荷expectedTaskVersion, operationId, remark;保存 HTTP 状态、业务 code、requestId/traceId、完整载荷和命令身份,等待实际 COMPLETED,不把受理态当完成。 - 完成后原 operationId、原 expectedTaskVersion、原载荷重放,确认返回同一业务结果;另一独立 operationId 不作为原请求重放。
完成后的独立核对
| 对象 | 必须成立的断言 |
|---|---|
| 完成清单 | /api/platform/v1/first-leg/loading-lists/{planId}?warehouseId=... 的行集合严格等于有效实拣集合;PARTIAL 行已结算为实箱,SKIPPED/零拣不出现;列表与详情汇总一致 |
| 计划历史/PDA | 计划历史允许保留 SKIPPED;任务保留真实实拣及原计划数量。不能以原计划总箱数与实装箱数相等作为完成断言 |
| 部分指标 | 原 3 箱 21 件变为实 2 箱 14 件;重量/体积按冻结行缩放。例:10.001/8.002/6.004 kg、0.1001 cbm 对应 6.667/5.335/4.003 kg、0.0667 cbm;实际期望以正式冻结值为准 |
| 来源与余量 | 实箱+余量=原可用箱数;余量沿正式分片产生,原订单/入仓编号及 lineage 可追溯。重放后版本、历史、资源结算和分片数量不重复推进 |
| 标签/事件 | 预测与最终冻结托盘码/托数一致,预检零标签写入;最终 V3 只携带各客户实际货物。总控只读核对唯一 Outbox、载荷摘要、ACK 与接收结果,不伪造事件 |
| 报关平台 | GET /api/platform/v1/customs/loading-plans/{planId} 的 actualBoxCount 等于实拣之和;退税票/客户范围、资料覆盖要求排除整票跳过;已实装票缺资料仍拒绝开始 |
| 客户资料 | /api/merchant/v1/customs/orders/{orderId}:甲只能见自身已实装退税来源;丙整票跳过没有该柜资料入口;乙买单不会获得退税客户入口;外客户拒绝保持原 code 与诊断字段 |
| 买单导出 | 复用正式导出服务,只含乙实际行,不含跳过的买单行;记录分页最大ID、总数、输出行集合与字节摘要,不能只核对 XLSX 魔数 |
| 全买单 B 柜 | 跳过退税不阻断全买单报关开始/完成;拒绝创建退税申报/发送。报关完成后的自动离仓必须满足既有正式前置,不能用本方案绕过 |
| 下游 | Lastleg/入仓计划/在途库存独立读回与事件实际数一致;禁止把正确下游改成原计划总箱数;原柜只读回查保持下游完整快照不变 |
负向预检与证据界限
跨客户第二来源缺客户/目的仓快照、非法 PARTIAL、未结算最终发布等服务内非法事实,使用 LoadingCompletedPreflightDatabaseTest 的真实 Mapper 场景核验;不得通过 TEST SQL 捏造非法业务数据。有效新样本的跨客户正常完成必须走上述真实 HTTP。H2 对 MySQL UPDATE JOIN 的语法适配与 pendingAutoDispatch 关联替换均需在报告中披露;真实 MySQL 触发器与最终完成另验。
证据建议落在 reports/partial-loading-actual-<批次>/:版本/健康与触发器就绪证明、请求序列、before/after 全量快照、逐断言结果、事件/接收端只读取证、失败原件、会话退出结果。执行结束退出自己的全部会话,不删除数据或恢复他人资源。HTTP/DOM证据与人工1920×1080、100%缩放及PDA设备验收分别报告,不据服务测试宣布页面或全流程完成。