Files
baiyue-firstleg/scripts/admin-test-env-modules/README.md
T
2026-09-30 17:13:11 +08:00

355 lines
64 KiB
Markdown
Raw 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.
# Admin 测试环境 HTTP 模块
`phase5-overseas-fulfillment.mjs` 的 `pickAll`、`saveReceiptAndComplete` 也供显式授权的 `../mixed-container-outbound-test-env.mjs` 留存混柜续跑入口复用;仍使用正式 PDA 拣货和签收文件绑定接口,不代替全模块验收。
总入口是 `../admin-test-env-acceptance.mjs`。每个业务模块使用独立的同名 `.mjs` 文件,避免多个对话同时修改总入口。
`phase5-root-fulfillment.mjs` 是显式 TEST 的 F40 两箱根/余量专项,通过总入口 `--modules phase5-root-fulfillment` 准备本轮资质客户;模块用正式下单、测量、国内 PDA 拆分装柜、船节点、海外 PDA 收货、拣货发车及文件签收链创建两柜真实来源。默认根先签,编程调用 `AcceptanceRun.context.f40SignatureOrder='CHILD_FIRST'` 切换子先签;分别核对第一片签收不得根完成、最后一片签收才根完成、真实签收时间、状态历史和重放零新增。
`AcceptanceRun.context.f40SignatureOrder='ROOT_SIGNED_REMAINDER_CANCELLED'` 单独验证合法末票余量取消:本轮新根通过 `orderStopAtApproved=true` 停在原始 `APPROVED`,只装运签收首箱;回查真实履约树及未装子单原始 `APPROVED`、入仓 `WAIT_SPLIT` 和一箱余量后,调用公开取消接口。`PROCESSING` 子单不得作为取消样本。根完成事件必须唯一发布,取消子单完成事件显式为零;原取消请求重放须 `A0409`,且根子版本、历史、摘要、履约树及完成 Outbox 零漂移。两种双签模式仍须两片实际签收,不能用取消替代第二签。
会写已授权测试环境,保留新客户、单据、文件及报告,临时海外 PDA 在 finally 停用;失败保留样本,不自动删除或重复执行部分已完成链。签收资料使用新 key 保存同文件时,按正式保存命令递增一次资料版本、新增一条版本历史及 `SAVE_DOCUMENTS` 审计;签收时间、状态、原完成记录、文件绑定和根子完成事件不得变化。同一新命令再用原 key、原请求重放,必须明确 `replayed=true` 且完整资料、派送事实、版本和审计历史零漂移。资料保存前后及原 key 重放响应保存在 `phase5RootFulfillment.receiptReplayProofs`,失败也保留已取得的快照。
配置仅来自显式测试环境文件,报告由总入口 `--output` 指定。完整验收还须向 `AcceptanceRun.context.f40ReadOnlyOutboxEvidence` 提供本轮客户/根/实际来源的只读完成 Outbox 计数(取消模式必须返回零事件子行);缺少该证据明确为 `HTTP_VERIFIED_OUTBOX_PENDING` 和阻断,不能报告全部通过。海外收货同时需要 `AcceptanceRun.context.phase4ReceivingEvidenceReader` 捕获首次完成和重放前后的完整库存证据,缺失明确阻断;四阶段原始库存快照通过 `phase5RootFulfillment.receivingCompletionEvidence` 原样保存,部分捕获与失败也保留,不用终态补造历史。离线合同为 `phase5-root-fulfillment-contract.test.mjs`;不能代替真实环境验收。
单票串行验收可显式传 `--modules phase4-overseas-return-followups --return-main-chain-only true`:仍由总入口准备本轮客户并完成退货签收、合箱、换标和出库;不执行第二客户、跨仓和并发扩展,报告 `excludedScope` 记录排除范围,不代表完整退货边界回归。目标由显式网关与账号参数指定;仅在已授权环境执行,保留业务单据及 `--output` 报告,失败先核对报告再重跑,不自动清理。
普通库存换标回归由 `phase4-overseas-pda-operations` 验证:正常箱先完成混合换标的箱标与 SKU 阶段,另两箱保留跳过/异常;首次显式异常完工后经平台 `/rework` 退回并验证幂等,返工重新完成全部箱标/SKU 事实,再生成本轮目标托盘、绑定及核对库存流水,最后正常完工和客户确认。PDA 不自行批准复核,不在客户确认后才首次组托;异常首次完工会创建关联异常记录,属于测试数据副作用,保留为验收证据。
尾程暂扣按真实入库阶段验收:`phase4-tail-order-controls` 在 PDA 入库前验证暂扣返回冲突并回查订单零漂移,继续人工节点及整柜计划转换;`phase4-overseas-pda-operations` 接收本轮完成库存后调用同模块的 `verifyReceivedOrderHold`,重新核对本轮客户、订单和 `INBOUND_COMPLETED` 状态,再执行暂扣、同键重放/异参冲突、解除。正向暂扣未执行或前置不足仍是失败,不以入库前拒绝代替正向通过。
`pda-loading-link-regression.mjs` 通过总入口 `--modules pda-loading-link-regression` 运行,复用 `dropship-pallet-matrix.mjs` 的国内正式订单、测量、封托、订舱、证据和完成生产链,仅执行国内关联回归。覆盖单票加入后全移除换柜完成、多票共托反复换三个旧柜后完成、逐托即时提交及同键重放,以及一单多柜中仍有实际分配的未开始柜导致 `OWNER_READY/A0409`。每次重新创建带 marker 的业务数据,通过公开 HTTP 回查旧柜有效分配数、PDA 终态和入仓状态;不写业务数据库伪造前置。零分配残留由真实整托移除链观察,报告保存 `createdResources.pdaLoadingLinkRegression`。负向柜保留为 `COMPLETION_FAILED`,成功柜保留为 `COMPLETED`,不自动清理;失败报告保留且不得算通过。使用显式测试环境文件及 `--output reports/<本轮名称>.json`,须有真实 HTTP 写入授权;不启动海外收货或出库。
退货专项同时核验新建退货单、退货主单、签收单、批次和自动箱唛的完整业务编号:`RT/RR/RB/RC/RETU-` 加 25 位大写 Base36 UUID 编码;不再截取内部 ID 六位尾号。幂等重放仍核对同一已保存编号,手工指定箱唛不受系统生成格式约束。编号生成器另有完整 128 位编码往返、原截断碰撞和本地并行生成单测;本地生成压测不增加 HTTP 并发。
退货专项只运行 `--modules phase4-overseas-return-receipt`,自动准备本轮客户;覆盖非法/重复预报、退货单号和 SKU 查询、非法/未知 SKU 实收、超收及失败不落账、分批签收完成、部分签收禁止合箱、合箱非法箱规/数量/来源、幂等重放前后库存快照一致、逐箱分页无重复遗漏、客户 SKU 数量守恒及标签。通过显式测试环境文件运行总入口,JSON 路径由 `--output` 指定;会创建隔离测试数据,finally 停用临时 PDA,不删除业务记录。失败保留报告,先核对记录再决定是否新批次重跑。
退货预报创建后为 `PENDING_REVIEW`。签收前必须通过客户详情确认归属,再经平台 `/return-orders/{returnNo}/review` 携带 `X-Customer-Id` 审核,客户回查 `PENDING_RECEIPT` 且实收为零;审核失败立即停止签收。`return-review-contract.test.mjs` 覆盖归属拒绝、审核权限失败和回查未收敛。主签收场景按单 SKU 分甲3件、乙2件两批,使用正式 PDA 退货托盘生成接口返回的 `palletCode`,不复用国内基础托盘;每批对应一个计费批次。最后一批先验证缺照片拒绝及库存不变,再上传明确为合成测试图片的 PNG 并完成签收;不把图片称为真实现场照片。边界扩展与换标后续仍需按新协议独立验证,主签收通过不能证明全部退货链通过。
`return-boundary-scenarios.mjs` 是退货专项自动调用的内部扩展,不单独注册入口:本轮新建第二隔离客户,复用两个有效海外仓,覆盖跨客户单据/箱/标签/列表隔离、跨仓 PDA 隔离、两人争抢最后一件的签收及合箱、同键并发签收与成功后重试、多单同 SKU 全量合箱和实际来源追溯、耗尽箱清零、多单 SKU 候选和输入边界。异常写入逐次前后回查订单、签收批次、箱及 SKU;同键重试只模拟响应丢失后的客户端行为,不代表网络故障注入。每组并发严格为两个请求,不启动批量 worker;缺少第二仓或操作员属于失败,不能跳过后宣称通过。finally 停用新增 PDA,保留测试客户和业务记录;不触发部署、SQL、换标、出库或二次合箱。真实运行须明确授权目标环境及此小规模并发边界。`merchant-qualification-fixture.mjs` 的内部参数 `publishEnvironment: false` 只将第二客户凭据留在独立内存上下文,不覆盖主客户环境凭据,默认主 fixture 行为不变。
扩展离线检查:`node --test scripts/admin-test-env-modules/return-boundary-scenarios-contract.test.mjs scripts/admin-test-env-modules/phase4-overseas-return-receipt-contract.test.mjs scripts/admin-test-env-modules/merchant-qualification-fixture-contract.test.mjs scripts/script-documentation-contract.test.mjs`。这些校验验证脚本编排和断言,不代替真实 HTTP 验收;运行报告中的每个失败均保留阻断。
边界扩展创建的每张退货单也必须先审核,并由绑定该仓的 PDA 经正式接口生成本轮退货实收托盘、上传合成打托测试图片;客户身份通过本轮登录会话映射,禁止用主客户替代第二客户。签收请求传 `palletCode`,成功响应核对同一托盘而非已移除的 `cartonMark` 字段;流水分两批时分别使用两个正式托盘。混合明细场景先验证两种 SKU 同批拒绝且不落账,再分别签收为两个来源库存箱以继续合箱回滚验证。三轮双请求并发范围保持不变。
同一退货扩展还覆盖五组完整性检查:混合明细中前项合法、后项超量/不存在时签收与合箱整笔回滚;同一操作员同键并发合箱及后续重试只生成一个目标箱;不同客户及仓库使用同一 SKU 时的候选、列表和库存隔离;客户/平台/PDA/无登录身份不得进入未授权退货入口;两批签收流水逐行核对客户、仓库、SKU、签收业务号及增量,并在重放和超收失败后回查不变。流水由现有接口从签收明细重建,不代表独立持久审计账本,也不验证后续换标或出库。并发合箱固定三轮、每轮两个请求,其余造数和校验顺序执行。
`phase4-overseas-return-followups.mjs` 是独立可选后续模块,只在显式 `--modules phase4-overseas-return-followups` 时依赖并运行退货前置,再关联换标单及执行退货出库;不计入退货专项通过结论。仅复用同次运行、同 marker 的退货资源,凭据只在内存中,finally 停用其独立临时 PDA。合同检查复用 `phase4-overseas-return-receipt-contract.test.mjs`;HTTP 必须有目标环境写入授权。
退货转换标请求按当前契约传 `items[{skuCode, quantity}]`、`fileScope` 和真实 FBA 目的仓 ID/编码,返回 `PENDING_REVIEW` 与 `skuCodes`。分页查找启用的 SCK8,缺失则阻断;总箱标文件回查 `cartonTotalFileId`。独立退货出库候选使用查询参数 `warehouseId`。同模块的 `completeReturnRelabel` 在独立出库之后继续审核本轮换标申请、PDA 认领与数量完成、来源托盘解析、正式生成目标托盘、组托及原键重放、上传合成完工图片、提交完工、客户确认及原键重放,最终回查原退货单仍为签收完成且换标关联一致。它不执行其他客户库存操作;目标托盘是本轮换标业务资源,不是国内基础托盘。客户确认后 `outboundRelabelledReturn` 逐箱核对本轮换标号、客户、仓库、来源单与数量,只为已完成换标的一件库存创建出库,检查创建原键重放、PDA 拣货/完成与平台、客户库存 `OUTBOUNDED` 终态;另存 `relabelOutboundNo`,不能用此前未冻结库存的独立出库结果替代。
退货专项复跑命令(在后端根目录执行,每次使用新的报告名;不要与其他环境混用):
```powershell
node --test scripts/admin-test-env-modules/phase4-overseas-return-receipt-contract.test.mjs scripts/script-documentation-contract.test.mjs
node --env-file="$env:USERPROFILE/.codex/chongchong-global-test-acceptance.env" scripts/admin-test-env-acceptance.mjs --modules phase4-overseas-return-receipt --output reports/return-<本轮批次>.json
```
PC/PDA 页面交互验收与 HTTP 独立取证,不用接口提交替代点击:PC 固定 1920×1080、缩放100%,验证空预报拦截后新建独立双SKU单(甲3乙2,不执行换标);PDA 固定390×848,验证不存在单号空态、按单号签收甲2、按SKU候选确认2/3与整单2/5、全部填入剩余甲1乙2并确认5/5;再合箱甲2乙1及30×20×10cm/1.2kg。PC 查询三箱3+1+1、两批真实来源、新箱明细、SKU汇总甲3乙2,并检查无结果查询后恢复正常列表。记录本轮业务单号、实际视口、截图与控制台信息;H5点击不代表真机扫码,标签HTTP不代表PDF分页或实体打印。人工重点确认布局、长字段换行、滚动、反馈和操作便利性。
需要为人工联调批量准备同一客户、同一国内仓和同一渠道的 `WAIT_SPLIT` 数据时,使用[《批量待分柜数据生成指南》](批量待分柜数据生成指南.md)。该入口通过正式下单、入库、称重和测量接口生成数据,支持 FBA、海外仓、私人地址及一件代发等稳定随机组合;不得直接写库或用于生产环境。
固定“IT测试”客户与“义乌仓”、其余线路随机并尽力生成最多 8,000 票时,独立编排入口是 `../it-test-wait-split-bulk.mjs`。它仍复用本目录的 `orders.mjs` 与 `inbound-measurement.mjs`,但逐票保存日志且单票失败后继续。测量前置只随机复用既有 `TP-001`、`YW-TP-002`,不得调用托盘新增接口;库位由正式仓储接口分配,普通位不足时使用公共位 `A0`,不得调用库位新增接口。
订单造数中的 `GET /api/merchant/v1/partners/candidates?type=SHIPPER` 属于 Warehouse 正式客户候选能力。失败时订单脚本仍可使用 sender 快照继续收集后续链路证据,但 HTTP 503/`S0503` 必须保留为 deployment blocker,不能因订单、测量、分柜或装柜后续通过而降级为 coverage gap。
人工分柜采用两个可选模块,不进入默认全量入口:`manual-order-splitting-fixture.mjs` 基于本轮至少四票 `WAIT_SPLIT` 数据生成部分分配、整票拼柜和未分配对照清单;人工在 Admin 完成计划分配后,`manual-order-splitting-verify.mjs` 读取准备报告和 `loadingPlanId`,只读核对柜次范围、计划箱数及候选余量。完整命令见同一指南的“人工分柜验收”章节。
人工分柜通过后可继续执行 `manual-preload-push-fixture.mjs`:它读取分柜核验报告并冻结推送前计划版本、明细及无号模拟柜状态;人工点击“推送预装”后,再由 `manual-preload-push-verify.mjs` 只读核对 `EDITING` 预装清单、PENDING bridge、版本递增、明细零漂移和 PDA `A0404`。两个模块同样不进入默认全量入口。
预装推送通过后,`manual-pda-ready-fixture.mjs` 冻结无号、未关联订舱、不可确认且无 PDA 的基线;人工依次完成订舱 DRAFT、RELEASED 放舱、原模拟柜关联真实柜号和整份计划确认,再由 `manual-pda-ready-verify.mjs` 只读核对 RELEASED、allocation、稳定柜次/计划身份、CONFIRMED readiness 和唯一 `UNASSIGNED` PDA task。两个模块不领取任务,也不进入默认全量入口。
PDA 待领取通过后,`manual-pda-batch-fixture.mjs` 冻结任务明细、稳定箱码和库存快照基线;目标 PDA 作业员人工领取、逐箱扫码并一次提交原子 batch 后,`manual-pda-batch-verify.mjs` 只读核对作业员绑定、全量 PICKED、`AWAITING_REVIEW`、一次 CLAIM、一次 BATCH、pending/detail 一致和入库级数量收敛。HTTP 不记录逐次扫码轨迹,真机扫码仍需人工证据。
PDA 待复核通过后,`manual-loading-complete-fixture.mjs` 冻结无证据、未完成、RELEASED 订舱和 LOADING 计划基线;人工现场上传五类证据并执行一次最终完成后,`manual-loading-complete-verify.mjs` 只读核对五类真实图片、唯一 COMPLETE_LOADING、任务/计划 COMPLETED、来源入库单和统一订单 LOADED、实装分片数量守恒及货柜总览终态。
例如 `--modules system,inbound-weight-ocr` 会依次加载:
- `system.mjs`
- `inbound-weight-ocr.mjs`
`fee-items` 需要同一 marker 的客户订单和入库单。执行 `--modules fee-items` 时,入口自动扩展为 `merchant-qualification-fixture,orders,fee-items`,无需手工补齐前置模块。
模块只需导出:
```js
export async function run(context) {
const response = await context.request('GET', '/api/platform/v1/example')
const data = context.apiSuccess('example', '查询示例', response)
context.assert('example', '示例结构正确', response, Array.isArray(data), `count=${data?.length ?? 'n/a'}`)
}
```
## 可用上下文
混柜收货的每一步均区分同键同载荷重放、同键异载荷冲突和同货物新键再次扫码:普通海外仓重复箱返回冲突,FBA 相同累计数和代发同托新键返回零增量;随后回查完整会话,确保三票事实均不变。
`mixed-container-receiving.mjs` 通过总入口 `--modules mixed-container-receiving` 执行,依赖客户资质准备。新建一票双托一件代发、一票普通 FBA、一票普通海外仓订单,固定同一起运仓和渠道,经正式接口混装同柜、完成国内装柜和船节点、按柜生成海外计划。使用本轮 PDA 身份交替执行 FBA 累计收货、代发整托收货、普通海外仓逐箱收货;每步核对全部票进度、同键重放和未齐正常完成拒绝。终点为 `MIXED_CONTAINER_INBOUND_COMPLETED`,不创建后续出库或派送,不代表仓储转运单混装。报告复用 `createdResources.dropshipPalletMatrix`;失败保留阻断,成功数据保留,finally 停用本轮 PDA 操作员。真实运行须环境授权,离线合同 `mixed-container-receiving-contract.test.mjs` 不能代替真实 HTTP。
一件代发矩阵出库前运行 `dropship-outbound-edge-cases.mjs` 的候选查询探针:先模拟平台首次打开页面只传海外仓,再传客户筛选,要求本轮每票全部托盘、箱数、仓位及 SKU 事实一致,并核对仓库与指定客户隔离。缺托、错误客户/仓库、A0400 或筛选后仓位漂移均阻断;候选达到服务端上限导致本轮数据不可见也不能按空场景通过。该探针不证明跨客户混柜造数已覆盖。
一件代发矩阵在每个剩余实物托盘收货前核对待收箱数,并以 `allowDifference=false` 尝试正常完成:必须返回 A0409,回查会话事实不变后才继续收货。这不覆盖显式差异完成,不得把正常完成门禁解读成系统禁止一切差异结案。
每托首次收货及重复扫描后,矩阵按本轮已提交的来源托盘、箱唛和入仓码独立计算期望进度,回查柜级及每票的总箱数、实收、待收三项。柜级总数正确但串票、重复行、缺票或逐票待收未刷新仍判失败。离线验证器包含三票交替进度样本,但该样本不等于三类混柜真实 HTTP 验收。
`dropship-browser-fixture.mjs` 通过总入口 `--modules dropship-browser-fixture` 执行,自动依赖客户资质准备;复用矩阵生产者创建一票四箱两托,完成国内装柜、船节点和按柜生成海外入库计划,明确停在 `READY_FOR_BROWSER_RECEIVING`。只准备新测试数据,不调用海外 PDA 收货或出库、不创建海外操作员;后续由浏览器页面验收。报告仍保存于 `createdResources.dropshipPalletMatrix`,准备通过不代表全流程通过,不自动删除数据。
`dropship-pallet-matrix.mjs` 验证下述四场景整托手工加入、整托移除、智能推荐、独立订舱与文件放舱、真实柜号关联、预装确认、PDA 整托拣货和五类证据上传;异步装柜完成必须等到任务 `COMPLETED` 并逐票回查 `LOADED`。智能装柜的托盘汇总与装柜详情逐票组成分别核对,不能把共托汇总行的首票编号当作全托归属。随后经正式报关、国内离仓及人工船节点接口推进至 `PICKUP_READY`,再按柜生成逐票海外入库计划,检查来源托盘完整绑定、共享托盘身份一致和同键重放。海外收货使用本轮创建并绑定接柜仓的 PDA 操作员,上传三类照片、签收、逐实物托盘收货、逐票箱数核平和完成入库,同键重放及同托新键扫码均不得重复入账。随后从本轮逐票库存候选创建一件代发专用出库,携带原始箱唛由 PDA 拣货、完成,核对终态、幂等和可用库存扣减;finally 停用本轮操作员。出库重放按业务身份和数据库毫秒时间精度核对。离线合同为 `dropship-pallet-matrix-contract.test.mjs`;脚本覆盖不等于真实 HTTP 已通过,须检查当轮报告和库存审计。
`dropship-physical-carton-chain.mjs` 复用同一条正式链路,专门覆盖多 SKU 共用物理箱:20 箱×2 SKU/2 托、5 箱×3 SKU/1 托、7 箱×2 SKU/预计 2 托后合为 1 托。每个场景从新订单、测量、箱唛冻结和 PDA 清点开始,按去重箱唛核对预装、装柜、尾程计划、海外整托收货、库存候选和一件代发出库;每箱必须保留全部 SKU 明细,但任何汇总不得按 SKU 行重复累计箱数。使用 `--modules dropship-physical-carton-chain`,会保留本轮业务数据和 JSON 报告,不自动清理。
- `dropship-pallet-matrix` 通过总入口 `--modules dropship-pallet-matrix` 执行,自动依赖客户资质准备。通过正式 HTTP 创建五票订单,覆盖单票多托、单票单托、单票移箱合托、多票共享开放托盘;会创建并保留测试数据,不自动清理。报告 `createdResources.dropshipPalletMatrix` 保存逐票箱唛、托盘及各阶段证据,失败即停止并保留阻断;重跑创建新批次,不借用历史资源。`fullFlowVerified=false`,不能代替海外收货及一件代发专用出库的完整验收。
- 一件代发任务 `Task.pallets` 只列实际参与绑箱的托盘;未使用的预生成托盘通过 `/api/platform/v1/first-leg/pda-dropship/inbound-orders/{inboundId}/pallets?accountId=...` 读取,客户范围取本轮任务。脚本同时核对 `generatedPalletCount/palletSetupReady`,不因空的任务托盘列表新增资源。
- `orders.mjs` 创建草稿前读取正式 `inbound-code-policy`:自动模式不传入仓码,手工模式按本轮 marker 生成短且稳定的测试入仓码,确保箱唛二维码长度有效;策略读取失败或矛盾立即停止,不修改系统全局配置、不重用历史订单。
- `dropship-outbound-edge-cases.mjs` 是 `dropship-pallet-matrix` 内部探针,不单独运行:使用本轮库存验证超量、错误 SKU、不存在/重复箱唛、箱数不符、同键异载荷、未拣齐完成、并发同键创建、未拣取消和重放。单票单托额外先拣一箱再拣剩余箱;部分拣货被拒时仍保留失败及部署阻断,只有回查冻结事实无变化才继续整条明细拣货以采集后续证据,不能将此计为分批通过。多票共托使用同一 SKU,来源区分必须依赖入仓码。成功数据保留,未拣并发探针出库单正常取消。本扩展不代表跨客户、跨仓、多 SKU 混箱、逐箱不等件数、跨区故障注入均已覆盖,结论以当轮真实报告为准。
- `phase3-container-documents` 从本轮货柜详情读取渠道:海铁验证 DO 上传被明确拒绝且聚合中没有 DO,其他渠道继续验证 DO 上传、重放及零漂移;缺渠道不猜测适用性。
- `phase4-overseas-pda-operations` 用三个独立逐箱任务分别验证正常换标、跳过和异常,异常不得重复使用前两箱。前一步失败时保留失败并停止该链,不继续使用空响应版本。
- 海外 PDA 生产矩阵为实际作业准备 `FBA-STANDARD`、`FBA-SECOND` 两个通过真实出仓和船节点达到 `PICKUP_READY` 的标准 FBA 柜,同时保留 `SECONDARY` 未放行柜用于负向门禁;不得将负向柜当作第二个收货柜。
- 海外 PDA 按真实柜号去重执行签收,缺少一件代发生产者不得用 FBA 生产者替代;原生产矩阵失败仍保留。P4 解绑样本保留为 `UNBOUND`,P5 只从本轮已完成同柜、同目的仓的入仓码中选择三箱实物托盘库存,排除 `UNBOUND` 和重复仓位,不借用历史订单。
- 排车详情按 `DispatchResponse.Item` 核对托盘与箱数,不读取 DTO 未提供的箱唛字段;`phase5-overseas-fulfillment` 将同一换标排车转为待出库单,通过 `OutboundDetail.pallets.cartonMarks` 验证全部新箱唛、排除原箱唛和重复箱。该测试生成的待出库单及派送单保留为本轮证据,不推进人工退货样本。
- 出库前同操作员、同草稿允许重复预排并更新原排车;脚本核对排车身份与业务数量不漂移,不要求重新生成的明细行 ID 不变。其他草稿抢锁仍必须冲突,生成出库单后仍验证托盘编辑被拒绝。
货柜查询使用 `/api/platform/v1/containers/domestic` 列表和 `/domestic/{id}` 详情,响应为 `WorkbenchItem`(`container`、`workbenchStage`、`statusSummary`、`allowedActions`),不接受旧扁平实体。默认 `phase3-container-loading` 同时验证页面的 ACTIVE、状态、关键字组合查询及详情结构;`container-detail-route-contract.test.mjs` 离线核对 Admin、Controller 和人工分段/同柜脚本读路径,并反证旧 DTO。定向真实 HTTP 使用总入口 `--modules phase3-container-loading`,仍自动展开本轮前置并创建测试资源;不借历史柜。
一件代发的 `inbound-measurement` 前置在测量草稿录入预计托数;审核通过时系统一次性预生成全部 DP 托盘码,允许空托先打印。PDA 既支持先清点箱再扫预生成托盘码批量归托,也支持先扫托盘后逐箱直接归托;预计托数不得超过实测箱数。验收逐托封托并确认全部箱数已绑定、全部预生成托盘已封托后任务才完成,默认一件代发后续链复用该前置。人工验收造数可传 `--prepare-dropship-manual-count true`,脚本会停在任务未领取、箱未清点、托盘未绑定的状态。
该前置保存成功解析且清点的原始 `boxCode`,随装柜完成生产 fixture 传入默认 `phase4-overseas-pda`。默认矩阵同时创建 FBA 和 OVERSEAS 两种一件代发,其中主生产者固定为 4 箱 2 个已封 DP 托盘:先逐托人工分配并确认首托加入后次托仍可选,再反证单条删除受阻、整托移除成功,随后执行真实智能推荐并核对两托完整加入,最终恢复精确两托继续装柜。海外侧必须先将全部原箱码经 `current/cartons/resolve` 精确解析到同一入仓码及冻结目的类型,再进入逐来源托盘实收及库存验证;OVERSEAS 逐箱实收,A0404、错误箱码/归属或数量缺失均阻断,不扩展推算箱号或排除失败候选。现行 V2 托盘 SKU 分组必须携带 `sourceInboundDetailId`,离线合同同时锁定两个生产分支来源明细和上述真实 HTTP 调用链。
- `request(method, path, body?, token?, extraHeaders?)`:JSON HTTP 请求,自动使用平台 Token;幂等写操作通过 `extraHeaders` 传 `Idempotency-Key`。
- `requestBinary(method, path)`:文件下载,不把二进制写入报告。
- `apiSuccess(module, name, response, evidence?, options?)`:断言 HTTP 200 + body code `200`,成功时返回 data。
- `assert(module, name, response, condition, evidence, options?)`:业务断言。
- `expectConflict(module, name, response, scenario)`:断言并发冲突。
- `addStep(...)`:写入统一步骤报告。
- `marker`:本轮唯一测试标记。
- `createdResources`:登记测试资源 ID。
- `context`:模块间共享少量 ID;模块应尽量独立。
## 约束
- 不记录密码、Token、图片二进制或 OCR 原文全文。
- 测试数据必须带 `context.marker`;可删除的清理,不能删除的最终停用。
- 缺少已确认契约时记录失败或 `deploymentBlocker`,不得模拟成功。
- 一个模块只修改自己的 `.mjs`,不要修改其他模块文件。
## 近期业务模块与静态合同快速索引
### 合并后的海外增量覆盖
本节核对 `d4fec829` 首父至 `fb66d920` 的海外后端差异及当前 Admin 调用端。
复用已注册默认模块,不新增独立造数入口;定向执行仍由总入口展开本轮客户、国内履约和海外 PDA 前置。
离线合同 `merged-overseas-coverage-contract.test.mjs` 锁定默认注册、定向依赖、陈旧 fixture 拒绝及新增断言。
离线通过只证明脚本合同,不证明部署环境已通过。
| 新增功能 | 全量模块 | 本轮 fixture / 依赖 | 正常与失败断言 |
|---|---|---|---|
| 仓储转运审核 | `phase4-overseas-client-services` 调用内部 `warehouse-transfer-review.mjs` | 本轮资质客户 Token、PDA 完成柜来源订单;另通过客户 API 创建独立新到仓转运对照票 | 平台显式 customerId;客户 Token 无审核权限;缺作用域/非法决定拒绝且状态不漂移;已有库存 APPROVED/PENDING_ASSIGNMENT;新到仓 APPROVE→WAIT_PDA_RECEIVING/WAIT_DELIVERY,REJECT→REJECTED/CANCELLED;同决定重放、反向审核冲突、客户详情回查;空驳回原因应 A0400 并保持待审核 |
| 智能预排真实草稿柜 | `phase4-overseas-dispatch` | `phase4-overseas-pda-operations` 后本轮实际收货托盘 | 草稿柜创建、明确 draftContainerId 绑定、结构回查、unlock 恢复候选、删除柜释放锁、重建柜预排;保留同草稿重锁、其他草稿冲突、旧载荷预排冲突与 release 合同 |
| 排车托盘移除 | `phase4-overseas-dispatch` | 同一本轮托盘先创建独立移除对照排车,移除后才进入主链预排 | DELETE 明细后箱数/托数/明细归零;重复删除 A0404;正式锁释放后候选恢复。空对照排车保留,不借历史排车 |
| 排车编辑、BOL、后台转派送 | `phase5-overseas-fulfillment` | `phase4-overseas-dispatch` 生成的主链排车 | 复用车辆编辑和客户转派送;新增 BOL content-type 与 %PDF- 签名检查;后台同载荷转派送复用同一出库/派送业务号;生成出库后移除托盘 A0409 且数量和身份不漂移;原 PDA 拣货/发车、派送、异常和回访继续执行 |
| 退货签收与合箱 | `phase4-overseas-return-receipt` | 本轮退货预报及临时 PDA,不使用历史100单 | 已有分批签收、超收、幂等、数量守恒、库存与计费批次、合箱;不重复编排 |
| PDA 收货、换标托盘及采购资金 | `phase4-overseas-pda`、`phase4-overseas-pda-operations`、`phase4-overseas-wallet-and-pallet-cost` | 原本轮收货与钱包前置 | 复用已有收货、换标拆托、出库衔接和采购冻结/结算/释放,不新增旁路写库 fixture |
明确缺口及待验收(不能计作已覆盖通过):
- 转运 `Review.remark` 仅有长度限制,`WarehouseTransferService.review` 未校验空驳回原因,也未将审核原因保存到详情或历史。新增空原因负向 HTTP 断言会在当前实现失败,须业务实现专项修复;原 `Detail.remark` 是申请备注,不能冒充审核原因。
- 已核对专用 `WAREHOUSE_TRANSFER_APPROVE` Controller 注解;本轮 HTTP 增量覆盖客户 Token 拒绝,但“平台仅列表/仅管理无审核权限”的独立角色矩阵仍缺 fixture。不能用管理员成功替代最小权限验证。
- 新到仓转运本轮只验证审核落到 PDA 前置状态;`PdaWarehouseTransferController` 托盘化、客户确认、可选换标与后续预排完整新链尚未编排。不得声称 WAIT_PDA_RECEIVING 就是 PDA 已收货。
- 合并新增退货单换标候选及创建换标接口、换标申请编辑能力,尚需各自独立回归。退货出库需另补当前退货箱 fixture 到 RETURN_OUTBOUND 的完整链,不由普通派送退回覆盖。退货模块本轮已将旧 `sourceBatchNo=MERGED` 断言改为实际扣减来源批次去重、真实来源退货单,并补客户箱号分页与标签 SVG 条码;条码实际扫码可读性仍由人工验收。
- 智能预排跨客户/跨仓候选混选、不同平台操作员锁隔离与容量边界尚缺独立反向 fixture;本次同操作员不同草稿锁冲突不能替代它们。
- UI 专项由人工验收:审核弹窗驳回原因必填、按钮权限、列表状态刷新;排车编辑和移除交互、智能预排拖放/草稿恢复、BOL 排版与打印、请求数量。PDF 签名验证不证明打印样式正确。
所有真实 HTTP 场景待当前轮另行授权后运行;不读取真实客户 Excel、不造历史样本、不执行 SQL 或部署。
| 业务链路 | HTTP 模块/共享前置 | 离线静态合同 |
|---|---|---|
| 商户资质与下单身份 | `merchant-qualification-fixture.mjs` | `merchant-qualification-fixture-contract.test.mjs` |
| 公共主数据与往来单位 | `master-data.mjs` | `master-data-partner-contract.test.mjs` |
| 平台基础、客户、海外仓储费与下载 | `system.mjs`、`customers.mjs`、`overseas-storage-fees.mjs`、`downloads.mjs` | 由 Admin 总入口默认编排;分别覆盖系统能力、客户管理、海外仓阶梯费和下载中心基础能力 |
| 订单创建、可计价主数据、幂等零漂移与审核异步收敛 | `orders.mjs` | `orders-pricing-fixture-contract.test.mjs`、`orders-lifecycle-idempotency-contract.test.mjs`、`orders-approval-convergence-contract.test.mjs` |
| 入库单手工扣货与解除 | `inbound-hold.mjs`(客户隔离、乐观锁、幂等重放/冲突、不可变历史、统一订单投影、智能装柜候选拦截与恢复) | `inbound-hold-contract.test.mjs`;默认全量已启用,定向入口自动展开已审核订单与入库单造数 |
| 费用项目、价格配置与基础 Finance | `fee-items.mjs`、`pricing.mjs`、`finance.mjs` | `fee-items-contract.test.mjs`、`pricing-contract.test.mjs`、`finance-contract.test.mjs` |
| 入库测量、首次打印冻结箱码与墨家扫码 | `inbound-measurement.mjs` | `inbound-measurement-box-code-contract.test.mjs` |
| 入仓自动头程费用、派生详情、人工发布与 MANUAL 其他费用版本 | `inbound-fees.mjs`(前置:`merchant-qualification-fixture,orders,inbound-measurement`) | `inbound-fees-contract.test.mjs` |
| 国内货柜履约模拟柜关联、柜次概览、渠道隔离、装柜模型桥接、PDA、动态增量、国内报关证据、出仓及离仓后目的港资料 | `phase3-container-loading.mjs`、`ocean-booking-fixture.mjs`、`phase3-container-overview.mjs`、`phase3-loading.mjs`、`phase3-loading-model-bridge.mjs`、`phase3-pda-convergence.mjs`、`phase3-evidence-gate.mjs`、`phase3-loading-finalize.mjs`、`phase3-customs.mjs`、`phase3-outbound-dispatch.mjs`、`phase3-container-documents.mjs` | `container-simulation-association-contract.test.mjs`、`container-specification-fixture-contract.test.mjs`、`ocean-booking-channel-contract.test.mjs`、`phase3-container-regression-contract.test.mjs`、`phase3-loading-model-bridge-contract.test.mjs`、`phase3-loading-dynamic-final-contract.test.mjs`、`phase3-container-documents-contract.test.mjs`、`phase3-phase4-departure-pickup-chain-contract.test.mjs`、`phase3-producer-chain-contract.test.mjs`、`manual-state-loading-pda-contract.test.mjs` |
| 头程整柜报关 | `phase3-container-customs-fixture.mjs`、`phase3-container-customs.mjs`;定向入口通过正式客户资格、订单、测量、同柜装载和最终完成 API 生成平台公共订舱下的买单与两客户退税混合柜。第二客户独立登录,凭据只在内存;验证确认/打回隔离、正式申报各类人工异常及剩余 OPEN 门禁、每客户完成文件、自动出仓和唯一船期任务。客户资料只覆盖退税票,买单行由下载中心 XLSX 验证;不复用历史柜、不执行 SQL | `container-customs-acceptance-contract.test.mjs`、`container-customs-acceptance-matrix.mjs` |
| 国内装柜验收作业员选择 | `domestic-pda-operator.mjs`;按本次 PDA 登录 Token 的字符串 subject 匹配目标仓库候选 userId,缺少匹配即停止,不使用首位候选或成员编号 | `domestic-pda-operator-contract.test.mjs` |
| 分柜与父子入库单数量守恒 | `phase3-order-splitting.mjs` | `phase3-order-splitting-contract.test.mjs` |
| 同柜且不可拆组 | `coload-groups.mjs`(可选;前置正式生成至少7票同线路 `WAIT_SPLIT`,另造不同线路反向票;覆盖创建/取消幂等、原子分配/移除、目标组隔离超容拒绝与零漂移、推送防绕过、PDA短拣完成拒绝且无余量子单、足量整组消费、普通单拆分不回归及已有父子单建组拒绝) | `coload-groups-contract.test.mjs` |
| 人工计划分柜准备与只读核验 | `manual-order-splitting-fixture.mjs`、`manual-order-splitting-verify.mjs`(可选,不进入默认全量) | `manual-order-splitting-contract.test.mjs` |
| 人工推送预装前置与推送后只读核验 | `manual-preload-push-fixture.mjs`、`manual-preload-push-verify.mjs`(可选,不进入默认全量) | `manual-preload-push-contract.test.mjs` |
| 人工订舱关联、预装确认与 PDA 待领取核验 | `manual-pda-ready-fixture.mjs`、`manual-pda-ready-verify.mjs`(可选,不进入默认全量) | `manual-pda-ready-contract.test.mjs` |
| PDA 人工领取、逐箱扫码、原子批量提交与待复核核验 | `manual-pda-batch-fixture.mjs`、`manual-pda-batch-verify.mjs`(可选,不进入默认全量) | `manual-pda-batch-contract.test.mjs` |
| 五类装柜证据、PDA 最终完成与 LOADED 终态核验 | `manual-loading-complete-fixture.mjs`、`manual-loading-complete-verify.mjs`(可选,不进入默认全量) | `manual-loading-complete-contract.test.mjs` |
| 订舱共享主数据前置与订舱验收 | `ocean-booking-fixture.mjs`、`ocean-bookings.mjs`、`phase3-port-schedules.mjs`、`phase3-carrier-schedule-queries.mjs`(DRAFT 可编辑;RELEASED 冻结;船司查询只创建并写当前 marker 登记任务) | `ocean-booking-prototype-contract.test.mjs`、`ocean-booking-fixture-contract.test.mjs`、`phase3-carrier-schedule-queries.test.mjs` |
| 订舱级拖车预约完整生命周期 | `truck-appointments.mjs`(自包含创建并放舱,不创建或关联柜次;已有有效或已完成拖车单的订舱不可重复创建;覆盖候选、附件、人民币费用、幂等及 `SUBMIT → DISPATCH → PICKUP → ARRIVE → LOAD`,拒绝手工离仓/完成;自动完成与应付由真实国内离仓链路验证) | `truck-appointments-contract.test.mjs` |
| 订舱与拖车服务中心跨链路 | `service-center-flow.mjs`(依赖 `ocean-bookings,truck-appointments`;复用本轮 `RELEASED` 订舱创建订舱级拖车,验证派车单、离仓前状态链、历史、审计和关联零漂移) | 由入口依赖合同和拖车直接合同共同覆盖;真实 HTTP 缺本轮订舱或承运商时 fail-closed |
| Admin 补充能力与保护边界 | `supplemental.mjs`、`supplemental-boundaries.mjs` | `supplemental-boundaries-contract.test.mjs`;只按本轮资源验证补充能力、负向和保护边界 |
| 装柜清单三备注 | `orders.mjs`、`phase3-loading.mjs`(客户备注、最新内部备注、仓库备注;仓库备注 PATCH/清空/精确重放/旧版本零写) | `loading-list-remarks-contract.test.mjs` |
| 消息中心管理 | `notifications.mjs` | `notifications-contract.test.mjs` |
| Finance 真实前置、对账、结算与下载中心 | `finance-full-fixtures.mjs`、`finance-reconciliation-full.mjs`、`finance-settlement-full.mjs`、`finance-downloads.mjs` | `finance-full-fixtures-contract.test.mjs`、`finance-reconciliation-full-contract.test.mjs`、`finance-settlement-full-contract.test.mjs`、`finance-downloads-contract.test.mjs` |
| Finance 扩展隔离与跨区费用 | `firstleg-container-fee-allocation.mjs`(柜次跨客户分摊)、`finance-direct-paid-isolation.mjs`(海外仓服务直接已付)、`phase4-overseas-finance-cross-region.mjs`(五类海外费用跨区进入 Finance) | 对应同名 `*-contract.test.mjs`;跨区事件持久化链在本轮获授权时另以只读数据库证据核对 |
| 客户钱包与拆柜打托费自动闭环 | `phase4-overseas-wallet-and-pallet-cost.mjs`(授信初始化、平台充值、采购凭证/费用冻结结算、换标冻结结算/释放、Client 余额账本、国内/海外托盘汇总、按体积分摊及跨区金额守恒) | `phase4-overseas-wallet-and-pallet-cost-contract.test.mjs`;默认全量已启用,定向入口自动展开已审核客户与海外 PDA 实收链 |
| 海外仓 HTTP 生命周期 | `phase4-overseas-warehouse.mjs` | `phase4-overseas-warehouse-contract.test.mjs` |
| 海外 PDA 柜号收货与库内操作 HTTP 生命周期 | `phase4-overseas-pda.mjs`(按柜完成签收和实收,成功后仅以内存上下文交接操作员会话和已完成库存事实)、`phase4-overseas-pda-operations.mjs`(紧随收货执行盘点、公共位核对、托盘拆装换绑和换标复核;只复用本轮入仓计划已有空托盘及公共位,不新增托盘或库位;finally 停用双操作员并清空临时 Token;任何真实 fixture 缺失均 fail-closed) | `phase4-overseas-pda-contract.test.mjs`、`phase4-overseas-pda-operations-contract.test.mjs` |
| 海外 PDA 退货入库、计费批次与退货合箱 | `phase4-overseas-return-receipt.mjs`(自包含创建本轮客户退货预报和绑定仓临时 PDA 操作员;覆盖退货单号/SKU 查询、正常空结果、分批签收、核平、超收、幂等、退货箱/SKU 库存、每次成功签收唯一仓储计费批次及合箱;finally 停用操作员) | `phase4-overseas-return-receipt-contract.test.mjs`;`ReturnReceiptServiceTest` 精确核对计费批次客户、仓库、签收单、起算时间和 `PENDING_PRICING` 初态 |
| 尾程单公网控制与人工计划 | `phase4-tail-order-controls.mjs`(PDA 收货前对本轮柜执行整柜接柜仓变更/恢复与幂等冲突、单/批 FBA 目的仓变更、单/批合托标记并取消、CSV 导出、订单费用回查、单票暂扣/解除、八个人工节点和逐票人工计划) | `phase4-tail-order-controls-contract.test.mjs`;只复用现有公共接柜仓/FBA 主档,不新增仓库、托盘或库位;为目标柜全部入仓码创建 `MANUAL` 计划后交给 PDA 继续消费,不借历史订单 |
| 海外入仓扩展、客户服务与排车 | `phase4-overseas-inbound-operations.mjs`、`phase4-overseas-client-services.mjs`、`phase4-overseas-dispatch.mjs` | 对应同名 `*-contract.test.mjs`;只消费本轮前置资源,缺失时 fail-closed |
| 海外仓业务跨区事件与安全门禁 | `phase4-cross-region-events.mjs`(统一平台会话、匿名拒绝、canonical 权限 403、国内装柜完成到 Lastleg 建单、海外柜完成到 Firstleg 回写、轮询与诊断证据;重复 GET 仅验证读取稳定,缺真实投递重放证据仍阻断;缺本轮 marker 前置时阻断) | `phase4-cross-region-events-contract.test.mjs` |
| 国内离仓至海外 PDA 可见人工验收节点 | `phase3-customs.mjs`(国内报关资料与整柜照片)、`phase3-outbound-dispatch.mjs`(柜级离仓)、`phase3-container-documents.mjs`(离仓后目的港清关、DO;PU 使用柜级数字码)、`phase3-carrier-schedule-queries.mjs`、`phase4-carrier-pickup-ready.mjs`、`phase4-overseas-pda.mjs`(同柜候选) | `phase3-phase4-departure-pickup-chain-contract.test.mjs` |
| 国内出仓聚合、门禁、待装柜与仓库权限 | `phase3-outbound-aggregate.mjs`、`phase3-dispatch-gate.mjs`、`phase3-waiting-for-loading.mjs`、`phase3-warehouse-rbac.mjs` | 由容器回归、生产者链和出仓相关合同覆盖;只消费本轮主链资源 |
| 人工状态矩阵 | `manual-state-matrix.mjs` | `manual-state-matrix-contract.test.mjs`;验证装柜完成、报关和订舱相关状态组合 |
| 海外业务 HTTP 生命周期 | `phase4-overseas-business.mjs` | `phase4-overseas-business-contract.test.mjs` |
| 海外主数据 HTTP 生命周期 | `phase4-overseas-master-data.mjs` | `phase4-overseas-master-data-contract.test.mjs` |
| 目的港码头拖车与船节点终态 | `phase5-terminal-drayage.mjs`(PDA 卸柜前复用 `ACTIVE + TRUCKING + truckingScope=OVERSEAS` 主数据完成选车队、预约和实际提柜,卸柜后完成实际还柜,并覆盖四命令幂等/历史)、`phase4-carrier-nodes.mjs`(PDA 前补录至 `PICKUP_READY`;拖车完成后只读核验 `PICKED_UP/EMPTY_RETURNED` 和停止语义) | `phase5-terminal-drayage-contract.test.mjs`、`phase4-carrier-nodes-contract.test.mjs`;不再由船节点脚本直接伪造提柜和还柜 |
| 海外排车、出库、派送、异常与回访 HTTP 生命周期 | `phase5-overseas-fulfillment.mjs`(复用本轮海外仓已收货托盘和预排单,正式创建临时 PDA 操作员并在 `finally` 停用;覆盖排车编辑、按 FBA 目的仓转出库/拆分派送单、PDA 全量拣货/发车、逐单签收资料保存自动完成、头程入仓与订单跨区回推、客户回访、人工异常及派送退回) | `phase5-overseas-fulfillment-contract.test.mjs` |
| 初始化基线(仅离线) | — | `initialization-baseline-contract.test.mjs` |
表中的 `*-fixture.mjs` 是被业务模块复用的测试数据前置,不是新增的独立全量入口。执行 HTTP 时仍从 `../admin-test-env-acceptance.mjs` 进入;`*contract.test.mjs` 只做离线脚本结构和数据归属回归。
海外仓业务 HTTP 验收使用 Auth 统一会话,仅通过 `--gateway` 访问 TEST Gateway;拒绝旧 `--overseas-gateway`、`ADMIN_OVERSEAS_GATEWAY` 和非 test 环境参数。平台、客户与 PDA 各用自己的账号访问令牌,权限、客户隔离及仓绑定仍须验证。海外仓、海外业务和海外主数据模块只对带本轮 marker 的资源执行已确认的新增、编辑、状态与导出,并在结束前按契约停用;PDA 收货模块使用本轮临时 OVERSEAS_WAREHOUSE_PDA_OPERATOR 访问令牌,只调用 `/api/pda/v1/last-leg/receiving-containers/**` 柜号收货入口,不接受 `customerId`、`planNo` 或分配 ID。收货成功后由相邻的 `phase4-overseas-pda-operations` 消费仅存在于进程内存、不会进入 JSON 报告的 Token 与库存事实,执行盘点、公共位核对、托盘操作和换标;库内操作只复用收货计划产生的已有空托盘及当前仓 `VIRTUAL + ACTIVE` 公共位,不调用托盘或库位新增接口。新模块无论成功失败都在 finally 停用两个 picker 并清空临时凭据。两模块均不调用出库、退货出库、派送或内部接口;任何真实柜、箱唛、托盘、库存或换标前置缺失都必须形成 deployment blocker,不能按空场景通过;船节点禁止手工创建任务。
节点全链定向入口为 `--modules phase4-overseas-pda`。依赖展开固定先为本轮 `LOADED` 柜次完成国内 `CUSTOMS_DECLARATION` 与 PDA 装柜证据,再确认国内出仓;离仓后才维护 `DESTINATION_CLEARANCE`、`DELIVERY_ORDER` 两类目的港文件,PU 使用柜级数字码而不是文件,随后核对自动创建的 `OUTBOUND_CONFIRM` 船节点任务、人工补录至实际 `PICKUP_READY`,最后验证海外 PDA 候选可见。资料模块只写本轮 marker 柜次,覆盖上传/完成重放、同键异载荷 `A0409`、冲突后零漂移和聚合回读;任一 fixture 或 Trace 缺失均为 deployment blocker。
尾程单公网控制与目的港码头拖车定向入口为 `--modules phase4-carrier-nodes`。依赖会在海外 PDA 前插入 `phase4-tail-order-controls`,先对本轮柜验证接柜仓变更/恢复、目的仓变更、合托标记、CSV 导出、订单费用、暂扣阻断、解除和八个人工节点,再通过柜级预览与确认自动生成逐票计划和实体托盘;PDA 必须消费这些计划托盘,不得临时另建脱离计划的托盘。货柜到达 `PICKUP_READY` 后先复用公共 `ACTIVE + TRUCKING + truckingScope=OVERSEAS` 供应商完成选车队、预约和实际提柜;PDA 卸柜完成后,有界等待跨区卸柜事件回写国内聚合为 `UNLOADED`,再确认实际还柜。最后的船节点模块仅回读两次业务动作同步生成的 `PICKED_UP/EMPTY_RETURNED`,不得直接补录这两个节点。
```powershell
node --env-file="$env:USERPROFILE\.codex\chongchong-global-test-acceptance.env" scripts/admin-test-env-acceptance.mjs --modules phase4-carrier-nodes
```
海外 PDA 收货统一扫描冻结箱码:`FBA` 与 `OVERSEAS` 都必须由 `POST /api/pda/v1/last-leg/receiving-containers/current/cartons/resolve` 返回 HTTP 200、业务码 `200` 和当前柜唯一 `inboundCode`,不展示、扫描或提交 SKU。仅实收阶段分流:FBA 使用不含 `skuCode` 的 `/current/receipts/bulk`,逐箱接口必须精确返回 `A0409 FBA destination must use bulk count`;OVERSEAS 使用 `/current/receipts/carton`,bulk 必须精确返回 `A0409 OVERSEAS destination must use carton-by-carton scanning; bulk count is forbidden`。实机旧行为反证为 requestId `5e925a3d-8184-41e1-b0d2-f4e1aae86639`、traceId `62fdf603b65fd7f43ec452bb8a6ca185`。跨区广播消费只保留观察证据,不再单独形成 deployment blocker;实际 `PICKUP_READY` 候选门禁仍必须通过。
FBA 无 `ll_inbound_plan_carton` manifest 时,服务端只取完整扫描值的第一个 `#` 前缀,并在当前锁定柜中精确匹配唯一 `inboundCode`;不校验 SKU、`#` 后缀或箱序号,也不能要求前端拆分或自行决定归属。无 `#`、空前缀、未命中、跨柜或同柜多匹配必须拒绝。OVERSEAS 仍按完整箱码精确匹配真实 manifest 行。HTTP 合同使用任意 FBA 后缀验证前缀解析,覆盖上述负向与 OVERSEAS 缺 manifest,并在正负向 resolve 后回查 current 的状态、版本与收货数量零漂移。2026-08-26 最新已部署实机尚返回 `A0404 Carton mark was not found`,requestId `a716e2c2-dc10-4d07-8014-7438afb63090`、traceId `6ab8fcfcd812056ad6570d3b1652157b`;该证据保留为后端 FBA 入仓码前缀解析落盘及重新部署后的回归反证,不据此放宽成功合同。
```powershell
node scripts/admin-test-env-acceptance.mjs --gateway <test-gateway> --modules phase4-overseas-warehouse,phase4-overseas-pda,phase4-overseas-pda-operations,phase4-cross-region-events,phase4-overseas-business,phase4-overseas-master-data,phase4-carrier-nodes,phase4-overseas-wallet-and-pallet-cost
```
只有已登记在 `../admin-test-env-acceptance.mjs` 的 `CONFIGURED_MODULES` 中的名称才能用于 `--modules`;目录中存在同名 `.mjs` 不代表总入口已注册。新增或改名 HTTP 模块时必须同步总入口、依赖展开、离线入口合同和本表;尚未注册的实验脚本不得写成可执行验收入口。
海外仓出库与派送履约链定向入口为 `--modules phase5-overseas-fulfillment`。依赖展开固定从本轮国内货柜履约装柜完成、海外仓业务跨区接柜和海外 PDA 实收入库生成真实库存,再由海外仓业务智能预排创建 marker 专属 `PENDING_DEPARTURE` 排车。海外仓出库与派送模块只消费该本轮排车,先补齐车辆与司机,原子转为一张 `WAIT_OUTBOUND` 出库单和按 FBA 目的仓拆分的 `WAIT_DELIVERY` 派送单,随后使用绑定同一海外仓的临时 PDA 身份执行全量拣货和发车,使出库单进入 `OUTBOUNDED`;最后逐张派送单保存签收文件自动完成,轮询核对头程入仓单与统一订单跨区回推,并覆盖回访、人工异常与退回海外仓。所有幂等重放都核对业务单号或数量不漂移,真实前置不足必须形成 deployment blocker,临时 PDA 身份无论成功失败都由正式 IAM 状态接口停用。
该模块同时核对拣货、发车和重放期间库存及 SHIP 流水只扣一次;同一派送退回异常经接收、证据上传、处理完成后必须生成真实恢复库存及 `RETURN_STOCK_IN` 流水,原键重放不重复入账。PROCESSING 续跑必须保留原异常、原目标托盘、原证据和幂等键,缺失即阻断,不另建异常替代。客户签收文件验证下载真实字节,并通过本轮独立 SIGNED-B 客户验证隔离,凭据不入报告。分片完成门禁只接受同一订单的多个有效入仓分片;不同订单、多目的仓或已经完成的分片不能代替此条件,缺少生产者时仍报告覆盖阻断。
```powershell
node --env-file="$env:USERPROFILE\.codex\chongchong-global-dev-acceptance.env" scripts/admin-test-env-acceptance.mjs --modules phase5-overseas-fulfillment
```
## WAIT_SPLIT 到 LOADED 冻结链
默认 Admin 全量入口已注册并按同一 `context.marker` 串行执行货柜主链。冻结时序为:
`WAIT_SPLIT -> SIMULATION/ACTIVE 内部模拟柜 -> 智能排货 -> 无集装箱号 push-preload -> exact replay/冲突零漂移 -> 订舱 DRAFT 完整登记 containerRequirements -> RELEASED -> 港口取得真实 containerNo -> 按 oceanBookingId + requirementId + containerNo + expectedVersion 原地关联并创建 allocation -> 计划级原子确认 -> 唯一 PDA task -> claim 后 LOADING -> 原子批量拣货 -> AWAITING_REVIEW -> 五类证据 -> LOADING 阶段增量入库单/旧 inventory token A0409/刷新后续拣 -> PDA task complete 先完成 task/plan/inbound -> LOADED -> 提交后独立尝试同步唯一同柜有效拖车`。
其中,无号 push 只冻结装柜计划、建立 bridge 并使预装可见,不得创建 PDA task;订舱放舱也不创建真实货柜或 allocation。港口取得真实柜号后,四字段 link 直接补全原模拟柜并创建 allocation,原 `containerBookingId/cabinetNo/loadingPlan/items` 不变;未关联、订舱未 `RELEASED` 或整份计划未确认时,PDA 查询必须返回业务码 `A0404`。唯一确认入口为 `POST /api/platform/v1/first-leg/loading-plans/{loadingPlanId}/confirm`,请求体只含当前计划 `expectedVersion` 并携带 `Idempotency-Key`;成功必须返回 `confirmationStatus=CONFIRMED`、`readiness.readyForPda=true` 和唯一 `readiness.pdaTaskId`。验收脚本禁止调用旧入库单级 `/preload/confirming`、`/preload/confirm`。
计划在 `EDITING/LOADING` 可通过正式 assignments/PATCH/DELETE 端点增量;计划、任务和明细版本必须递增,PDA 四元身份不变,旧 `inventorySnapshotToken` 必须返回 `A0409 库存已变化,请刷新后重试`。完整国内货柜履约装柜 fixture 与批量待分柜入口都只随机复用初始化的 `TP-001`/`YW-TP-002`,任一缺失即报告部署阻断,不调用托盘新增接口;当普通位不足时由 Warehouse 自然分配到 A0,随后仅使用公开 A0 换绑接口制造库存版本变化,不直连数据库、创建库位或调用内部 Warehouse 接口。模拟柜的 `channelGroupCode` 统一由 `smart-loading-channel-group.mjs` 根据订单渠道映射。主国内货柜履约链强制完成该专项,海外仓业务生产矩阵的附加柜只负责跨区生产,不重复要求 A0;附加柜若自然落入 A0 仍执行同一验证。已拣项不可删或减量,未拣项可删;增量会把全拣的 `AWAITING_REVIEW` 撤回为 `IN_PROGRESS`,刷新 task detail 与 inventory 后续拣才可再次等待最终确认。最终唯一完成入口仍为 `POST /api/platform/v1/first-leg/pda-loading/tasks/{taskId}/complete`:保留同柜 `RELEASED` 订舱、bridge 与五类 ACTIVE 证据门禁;拖车状态和数量不是前置门禁。主事务提交后,零条有效拖车直接跳过,恰有一条时在独立事务尝试推进 `COMPLETED`,多条或并发冲突只记录拖车同步失败,不回滚已完成的 task/plan/inbound。PDA 结算可能先递增来源入库单版本或创建实装分片,完成动作必须在结算后重新锁定实际完成行并使用当前版本;HTTP finalizer 会回查 full/partial 履约分片,失败时保存 `requestId/traceId` 并断言 task/plan/inbound/operation 零漂移。后续模块必须复用 `phase3Loading` 发布的本轮 `taskId + inboundId + loadingPlanId + containerBookingId`,不得回退历史资源。
动态增量还会读取计划明细中的服务端 `totalPackageCount/remainingPackageCount`,断言
`remaining = total - assigned`;随后尝试把箱数调整为权威总数加一,必须得到 `A0400`,并回查
plan/item 版本、分配箱数及总数投影全部零漂移。脚本不从当前已分配数量反推订单总箱数。
`phase3-loading` 复用本轮双托一件代发 fixture,逐托核对 task items 与 inventory units 的 `unitType=SEALED_PALLET/palletId/palletNo/indivisible`,两托统一通过同一次 `/batch` 提交各自的 `PICK_PALLET + palletNo`。合法整托行混入非法普通行必须整批零写;普通 `PICK/PARTIAL/SKIP` 不得绕过整托限制。同参同键重放不得增加版本或审计,同键更换托盘码必须冲突。以上接入现有全量链,不建立独立 HTTP 入口。
`phase3-pda-convergence` 同时回查 `/tasks/pending` 与稳定 task detail:两者的 `workflowStatus`、`itemCount`、`pendingItemCount` 必须来自同一任务明细事实。全拣任务必须在两处均为 `AWAITING_REVIEW`,可执行证据 GET,但派生 `actions=[]`,不得重复发送 batch;操作历史必须恰有一次有效 `BATCH`。若 pending 仍按 assignment 返回 `IN_PROGRESS`,该轮以真实 HTTP 失败阻断,不由脚本或前端改写状态。
部署后需要定向验证该完整链时,模块顺序固定为:
```powershell
node scripts/admin-test-env-acceptance.mjs --modules merchant-qualification-fixture,orders,inbound-measurement,phase3-container-loading,phase3-loading,phase3-container-overview,phase3-pda-convergence,phase3-evidence-gate,phase3-customs,phase3-loading-finalize
```
整票库位块专项可在只跑 `orders,inbound-measurement` 时追加
`--verify-pallet-location-guide true`。它在测量仍可编辑、正式提交前核对
`palletLocationGuide` 计数、每槽 `blockId/slotNo/reservationId/locationCode/slotStatus`、
称重结果按 `weightResultId` 显式绑定槽位;每确认一张称重图片都会回查一次,后续扩容只能追加槽位,
既有 `blockId/slotNo/reservationId/locationId/sharedOverflow` 不得漂移。脚本还会真实验证删除图片后原 reservation/location
保留且转为 `RESERVED_EMPTY`,再上传替代图片并确认复用原槽后继续提交与审核。脚本只观测自然出现的共享 A0;
不会为制造普通位不足批量停用库位。
只验证真实集装箱号晚补门禁时,使用正式可选参数 `LATE_CONTAINER_GATE_ONLY=1` 并仍从总入口执行 `phase3-loading`。该模式使用本轮 marker 独立造数,固定验证无号 push、订舱关联、整份预装确认、PDA claim/batch、无号 complete `A0409`、LOADING 阶段首次补号和补号后 complete 受理;随后允许后台命令停在 `CABINET_EVIDENCE/A0409`,以证明柜号门禁已经消失且下一门禁来自未上传的五类柜级证据。该模式不继续完整报关或 LOADED 链,也不得与完整链同时解释为同一终态验收。
```powershell
$env:LATE_CONTAINER_GATE_ONLY='1'
node --env-file="$env:USERPROFILE\.codex\chongchong-global-test-acceptance.env" scripts/admin-test-env-acceptance.mjs --modules phase3-loading
Remove-Item Env:LATE_CONTAINER_GATE_ONLY
```
该命令会写测试环境,必须另行获得当前对话授权。离线入口合同为 `../full-regression-entry-contract.test.mjs`,生产者与状态合同为 `phase3-producer-chain-contract.test.mjs`。
## 消息中心模块
`notifications.mjs` 覆盖平台消息模板的查询、新增、编辑、版本冲突、激活与最终停用,以及未来定时消息任务的创建、幂等重放、列表查询、取消和非法重试。模块只创建未来定时任务并在结束前取消,不实际投递验收消息。定向 HTTP 验收需要当前对话明确授权:
```powershell
node scripts/admin-test-env-acceptance.mjs --modules notifications
```
离线静态合同可安全执行:
```powershell
node --test scripts/admin-test-env-modules/notifications-contract.test.mjs
```
## 供应商模块
`suppliers.mjs` 覆盖平台公共供应商的列表、统计、新增、详情、编辑、启停及主要错误边界。执行:
```powershell
node scripts/admin-test-env-acceptance.mjs --modules suppliers
```
该命令会调用测试环境写 API,只有当前对话明确授权后才允许执行。验收供应商最终停用但不删除;静态合同可安全离线运行:
```powershell
node --test scripts/admin-test-env-modules/suppliers-contract.test.mjs
```
## Finance 全链前置
`finance-full-fixtures` 会通过正式供应商 API 创建本轮隔离的 ACTIVE 供应商,并按费用项目类别校验后再生成 PAYABLE;不会使用历史供应商 ID。只请求 `finance-full-fixtures,finance-reconciliation-full,finance-settlement-full,finance-downloads` 时,总入口会自动补齐 `merchant-qualification-fixture -> orders -> inbound-measurement -> phase3-container-loading`,确保 Finance 能消费本轮真实已完成柜次,并在结算链完成后验证八类 XLSX 下载任务。若这些前置仍未产出同 marker 的完成柜次,Finance 会 fail-closed,不能把 finance-only 前置不足计为 Finance 业务成功。单独请求 `finance-downloads` 只执行最小部署能力探测,不借历史 Finance 数据。
## 国内整柜与客户运营统计
- `domestic-container.mjs`:整柜入库、出库、库存列表和详情,并覆盖字段边界、组合筛选与分页汇总、柜号标准化、同柜追加入库、货名冲突、完成出库强制库存版本、并发版本竞争和幂等重放;静态契约为 `domestic-container-contract.test.mjs`。
- `customer-operating-statistics.mjs`:客户详情在途柜量/TEU 运营指标,复用 `platform:firstleg:container:list` 权限。
- 两者由总入口 `admin-test-env-acceptance.mjs` 的默认模块列表编排;接口验收会写入测试数据,静态合同可离线执行。
```powershell
node --test scripts/admin-test-env-modules/domestic-container-contract.test.mjs
```
## 货柜履约列表字段合同
`fulfillment-list-field-contract.mjs` 统一校验货柜、预装/装柜清单、订舱、船期、拖车、报关协同和国内出仓正式响应中的稳定 ID、非空展示字段、非负数量/重量/体积及 ISO 时间格式。各生产模块在已取得的本轮 marker 响应上执行断言,不额外借用历史数据;未冻结的原型字段只登记在 `docs/国内货柜履约/货柜履约原型字段验收矩阵-2026-08-17.md` 的 `UNKNOWN`,不得由 fixture 伪造。
离线合同:
```powershell
node --test scripts/admin-test-env-modules/fulfillment-prototype-field-matrix-contract.test.mjs
```
## 清库后的商户下单前置
`merchant-qualification-fixture.mjs` 是默认全量验收的首个模块。它通过平台正式接口创建本轮隔离客户,经 File 上传真实营业执照和法人身份证文件,再走 IAM 提交审核和平台审核通过;审核完成后把本轮动态加载模块使用的商户账号切换到该客户。
依赖商户下单资格的模块不要单独运行。定向排查时至少保留前置模块,例如:
```powershell
node scripts/admin-test-env-acceptance.mjs --modules merchant-qualification-fixture,orders
```
该前置不会向初始化 SQL 写入伪造资质,也不会绕过订单服务的企业资格校验。静态契约可离线执行:
```powershell
node --test scripts/admin-test-env-modules/merchant-qualification-fixture-contract.test.mjs
```
国内拖车自动完成与应付回归由 `phase3-outbound-dispatch.mjs` 在真实离仓后只读核验:订舱全部柜数、逐柜离仓、唯一 `AUTO_COMPLETE`、按拖车编号追溯柜次应付、金额守恒及 Finance 来源入池(有界等待 Outbox)。该模块的原有确认/撤销边界操作仍会写目标环境,执行须获得对应环境授权。`manual-state-ocean-trucking.mjs` 只构造可人工操作的状态,不伪造已完成拖车;自动终态由上述离仓链路覆盖。
`event-bridge-pending-recovery.mjs` 为纯离线证据校验器,文件名保留为索引入口;无事件桥调用或历史事件常量。合同覆盖 Compose DNS、三服务内部凭据版本一致、有限重试/DEAD、原事件摘要、ACK 丢失后 DUPLICATE 与单次业务效果。合成合同通过不代表环境故障演练通过;`phase4-cross-region-events` 保留真实重放证据阻断项。环境验收需本轮 marker 事件逐次投递记录、Inbox 与业务计数;仅使用受保护 `event-outbox-operations.mjs` 对 DEAD 原事件执行另行授权重试,不重放 SENT,不改表或伪造新事件。