test(firstleg): seed booking file before loading release

This commit is contained in:
2026-09-01 14:31:01 +08:00
parent d2092bf0b6
commit 2ccfc38cdf
2 changed files with 64 additions and 1 deletions
@@ -440,8 +440,52 @@ export async function run(context) {
const bookingDraftResponse = context.apiSuccess(MODULE, '创建三期 DRAFT 订舱(不生成真实柜)', bookingCreateResponse, '', OPTIONS)
const bookingId = id(bookingDraftResponse?.oceanBooking?.id)
const draftVersion = Number(bookingDraftResponse?.oceanBooking?.version)
context.assert(MODULE, '三期 DRAFT 订舱返回稳定身份和初始版本', bookingCreateResponse,
Boolean(bookingId) && bookingDraftResponse?.oceanBooking?.status === 'DRAFT'
&& Number.isInteger(draftVersion) && draftVersion >= 0,
`bookingId=${bookingId || 'missing'}, status=${bookingDraftResponse?.oceanBooking?.status || 'missing'}, version=${bookingDraftResponse?.oceanBooking?.version ?? 'missing'}`, OPTIONS)
if (!bookingId || !Number.isInteger(draftVersion) || draftVersion < 0) return
const bookingDocumentKey = `${context.marker}-p3-booking-document`.slice(0, 128)
const bookingDocumentForm = () => {
const form = new FormData()
form.append('expectedVersion', String(draftVersion))
form.append('documentType', 'BOOKING_CONFIRMATION')
form.append('file', new Blob([`${context.marker}-BOOKING_CONFIRMATION`], { type: 'text/plain' }),
`booking-confirmation-${context.marker}.txt`)
return form
}
const bookingDocumentResponse = await context.requestMultipart('POST',
`/api/platform/v1/ocean-bookings/${bookingId}/documents/upload`, bookingDocumentForm(), context.token,
{ 'Idempotency-Key': bookingDocumentKey })
const bookingDocument = context.apiSuccess(MODULE, '三期订舱上传当前有效订舱确认文件', bookingDocumentResponse, '', OPTIONS)
const releaseVersion = Number(bookingDocument?.bookingVersion)
context.assert(MODULE, '订舱文件归属当前订舱且上传递增版本', bookingDocumentResponse,
Boolean(bookingDocument?.document?.id) && id(bookingDocument?.document?.oceanBookingId) === bookingId
&& bookingDocument?.document?.documentType === 'BOOKING_CONFIRMATION'
&& bookingDocument?.document?.valid === true && Number.isInteger(releaseVersion)
&& releaseVersion > draftVersion,
`documentId=${id(bookingDocument?.document?.id) || 'missing'}, oceanBookingId=${id(bookingDocument?.document?.oceanBookingId) || 'missing'}, draftVersion=${draftVersion}, bookingVersion=${bookingDocument?.bookingVersion ?? 'missing'}`, OPTIONS)
if (!bookingId || !Number.isInteger(releaseVersion) || releaseVersion <= draftVersion) return
const bookingDocumentReplayResponse = await context.requestMultipart('POST',
`/api/platform/v1/ocean-bookings/${bookingId}/documents/upload`, bookingDocumentForm(), context.token,
{ 'Idempotency-Key': bookingDocumentKey })
const bookingDocumentReplay = context.apiSuccess(MODULE, '订舱文件同键同载荷重放', bookingDocumentReplayResponse, '', OPTIONS)
context.assert(MODULE, '订舱文件精确重放不新增文件或版本', bookingDocumentReplayResponse,
id(bookingDocumentReplay?.document?.id) === id(bookingDocument?.document?.id)
&& id(bookingDocumentReplay?.document?.oceanBookingId) === bookingId
&& Number(bookingDocumentReplay?.bookingVersion) === releaseVersion,
`firstDocumentId=${id(bookingDocument?.document?.id) || 'missing'}, replayDocumentId=${id(bookingDocumentReplay?.document?.id) || 'missing'}, firstVersion=${releaseVersion}, replayVersion=${bookingDocumentReplay?.bookingVersion ?? 'missing'}`, OPTIONS)
const bookingAfterDocumentResponse = await context.request('GET', `/api/platform/v1/ocean-bookings/${bookingId}`)
const bookingAfterDocument = context.apiSuccess(MODULE, '回查订舱文件有效归属', bookingAfterDocumentResponse, '', OPTIONS)
const activeBookingDocuments = (bookingAfterDocument?.documents || []).filter((document) => document?.valid === true)
context.assert(MODULE, '同键重放后当前订舱仅保留一条目标有效文件', bookingAfterDocumentResponse,
activeBookingDocuments.filter((document) => id(document?.id) === id(bookingDocument?.document?.id)
&& id(document?.oceanBookingId) === bookingId && document?.documentType === 'BOOKING_CONFIRMATION').length === 1,
`activeDocuments=${activeBookingDocuments.length}, targetDocumentId=${id(bookingDocument?.document?.id) || 'missing'}`, OPTIONS)
const releaseResponse = await request(context, 'POST', `/api/platform/v1/ocean-bookings/${bookingId}/release`,
{ expectedVersion: draftVersion, reason: context.marker },
{ expectedVersion: releaseVersion, reason: context.marker },
{ 'Idempotency-Key': `${context.marker}-p3-booking-release`.slice(0, 128) })
const bookingConfirmed = context.apiSuccess(MODULE, '三期订舱 RELEASED 冻结运输快照', releaseResponse, '', OPTIONS)
const transportFields = ['billOfLadingNo', 'vesselName', 'voyageNo', 'estimatedSailingAt', 'estimatedArrivalAt']