import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' const read = (path) => readFileSync(new URL(path, import.meta.url), 'utf8') const loading = read('phase3-loading.mjs') const openapi = read('../../firstleg/src/main/resources/openapi/firstleg-v1.yaml') const service = read('../../firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java') const outbox = read('../../firstleg/src/main/java/com/baiyue/firstleg/service/LoadingCompletedOutboxService.java') const event = read('../../common-event-contract/src/main/java/com/baiyue/common/event/FirstLegLoadingPlanCompletedV2.java') const eventV3 = read('../../common-event-contract/src/main/java/com/baiyue/common/event/FirstLegLoadingPlanCompletedV3.java') const admin = read('../../../apps/admin-web/src/modules/loading-lists/components/LoadingListDetailDrawer.vue') test('fixture locks customer and latest internal note sources without cargoRemark leakage', () => { assert.match(loading, /assignedItem\?\.customerRemark === orderRemarks\.customerRemark/) assert.match(loading, /assignedItem\?\.internalRemark === orderRemarks\.internalRemark/) assert.match(loading, /assignedItem\?\.internalRemark !== orderRemarks\.cargoRemark/) assert.match(service, /i\.setCustomerRemark\(cargo\.customerRemark\(\)\)/) assert.match(service, /i\.setInternalRemark\(cargo\.latestInternalNote\(\)\)/) }) test('warehouse remark PATCH covers save clear stale version and source preservation', () => { assert.match(openapi, /items\/\{itemId\}\/remarks/) assert.match(openapi, /expectedPlanVersion/) assert.match(openapi, /expectedItemVersion/) assert.match(openapi, /null\/空字符串均表示清空/) assert.match(openapi, /COMPLETED、计划\/明细版本冲突返回 A0409 且事务零写入/) assert.match(openapi, /数量调整或动态增量不会覆盖已有协作备注/) assert.match(loading, /EDITING 装柜明细保存仓库备注/) assert.match(loading, /仓库备注相同 operationId 与原请求精确重放/) assert.match(loading, /仓库备注精确重放不重复递增版本或历史事实/) assert.match(loading, /仓库备注旧版本 A0409 且零写入/) assert.match(loading, /仓库备注旧版本冲突后版本与备注事实零漂移/) assert.match(loading, /EDITING 装柜明细空白仓库备注归一化为 null/) assert.match(loading, /恢复真实仓库备注供装柜完成事件下发/) assert.match(loading, /preservedRemarkItem\?\.warehouseRemark === warehouseRemark/) }) test('completed event V3 retains V2 order remarks with stable event payload', () => { assert.match(outbox, /FirstLegLoadingPlanCompletedV2/) assert.match(outbox, /FirstLegLoadingPlanCompletedV3/) assert.match(eventV3, /List orders/) for (const field of ['customerRemark', 'internalRemark', 'warehouseRemark']) assert.match(event, new RegExp(field)) assert.match(outbox, /row\.getCustomerRemark\(\)/) assert.match(outbox, /row\.getInternalRemark\(\)/) assert.match(outbox, /row\.getWarehouseRemark\(\)/) assert.match(outbox, /HANDOVER_VERSION = 3L/) assert.match(outbox, /EventPayloadCanonicalizer\.canonicalize\(payloadNode\)/) assert.match(outbox, /FIRSTLEG_LOADING_COMPLETED:[^\n]*HANDOVER_VERSION/) assert.match(outbox, /EventTypes\.FIRST_LEG_LOADING_PLAN_COMPLETED, 3/) }) test('Admin exposes only warehouse remark editing and keeps completed rows read-only', () => { assert.match(admin, /备注(客户)/) assert.match(admin, /备注(内部)/) assert.match(admin, /备注(仓库)/) assert.match(admin, /编辑备注/) assert.match(admin, /COMPLETED/) assert.doesNotMatch(admin, /v-model="[^\"]*customerRemark|v-model="[^\"]*internalRemark/) })