This commit is contained in:
2026-09-14 20:03:22 +08:00
parent d53de922db
commit ebc299d58a
28 changed files with 756 additions and 95 deletions
@@ -2,7 +2,7 @@ openapi: 3.0.3
info:
title: Truck Appointment API
version: 2.0.0
description: A truck appointment belongs to one RELEASED ocean booking, independently of when or how that booking's internal containers are linked. Each booking may have at most one non-terminal appointment. The bill-of-lading number and warehouse are frozen from the booking, which must own at least one active BOOKING_CONFIRMATION or BILL_OF_LADING file. Container identities and real container numbers remain in the container/loading modules and are not part of this API. PDA loading completion does not change a booking-level truck appointment.
description: A truck appointment belongs to one RELEASED ocean booking, independently of when or how that booking's internal containers are linked. Each booking may have at most one non-terminal appointment. The bill-of-lading number and warehouse are frozen from the booking, which must own at least one active BOOKING_CONFIRMATION or BILL_OF_LADING file. Container identities and real container numbers remain in the container/loading modules and are not part of this API. PDA loading completion alone does not complete the appointment. All required containers must be allocated and confirmed departed from the domestic warehouse. Completion atomically creates approved ON_ACCOUNT container payable fees allocated by loaded volume and publishes their immutable snapshots through the existing Finance Outbox. Create, edit, submit and reschedule also recheck departure facts, covering late appointments. Zero amounts create no fee. Cancelled and exception appointments are excluded. RMB is the only appointment currency and maps to CNY in Finance.
paths:
/api/platform/v1/truck-appointments:
get:
@@ -21,7 +21,7 @@ paths:
records: {type: array, items: {$ref: '#/components/schemas/DetailStableReferences'}}
post:
summary: Create a truck appointment for a released booking
description: If the booking already has a non-terminal appointment, the server returns A0409 with the existing appointment number and instructs the operator to continue editing. The database booking-level unique key provides the same guarantee for concurrent creates.
description: If the booking already has an active or completed appointment, the server returns A0409 with the existing appointment number and instructs the operator to continue editing. The database booking-level unique key provides the same guarantee for concurrent creates.
requestBody:
required: true
content:
@@ -29,11 +29,11 @@ paths:
schema: {$ref: '#/components/schemas/SaveRequest'}
responses:
'200': {description: 'Created appointment', content: {application/json: {schema: {$ref: '#/components/schemas/DetailEnvelope'}}}}
'409': {description: 'A0409 - this booking already has a non-terminal appointment; message includes its appointment number and asks the operator to continue editing'}
'409': {description: 'A0409 - this booking already has an active or completed appointment; message includes its appointment number and asks the operator to continue editing'}
/api/platform/v1/truck-appointments/candidates:
get:
summary: Query authoritative create-time ocean-booking candidates
description: Requires platform:firstleg:truck-appointment:list. Returns one row per RELEASED booking with a bill of lading and an active booking-owned confirmation or bill file, excluding bookings that already have a non-terminal truck appointment. Container allocation and loading status do not affect eligibility. Edit pages display their current booking from appointment detail rather than injecting it into this create-only result.
description: Requires platform:firstleg:truck-appointment:list. Returns one row per RELEASED booking with a bill of lading and an active booking-owned confirmation or bill file, excluding bookings that already have an active or completed truck appointment. Container allocation and loading status do not affect eligibility. Edit pages display their current booking from appointment detail rather than injecting it into this create-only result.
parameters:
- {name: keyword, in: query, required: false, schema: {type: string, maxLength: 64}, description: Matches booking number or bill of lading}
- {name: page, in: query, required: false, schema: {type: integer, format: int64, minimum: 1, default: 1}}
@@ -63,7 +63,7 @@ paths:
- {$ref: '#/components/parameters/RequestHash'}
post:
summary: Apply an idempotent appointment lifecycle action
description: All actions transition the booking-level appointment as one aggregate. PICKUP does not accept or write a container number. ARRIVE, LOAD and DEPART persist their actual event timestamps atomically with the status transition.
description: All actions transition the booking-level appointment as one aggregate. PICKUP does not accept or write a container number. ARRIVE and LOAD persist their actual event timestamps. Manual DEPART and COMPLETE actions are not supported; confirmation of all required containers departing the domestic warehouse completes the appointment automatically.
requestBody:
required: true
content:
@@ -144,7 +144,7 @@ components:
required: true
schema:
type: string
enum: [SUBMIT, DISPATCH, PICKUP, ARRIVE, LOAD, DEPART, COMPLETE, EXCEPTION, CANCEL]
enum: [SUBMIT, DISPATCH, PICKUP, ARRIVE, LOAD, EXCEPTION, CANCEL]
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
RequestHash: {name: X-Request-Hash, in: header, required: false, schema: {type: string, pattern: '^[0-9a-fA-F]{64}$'}}
schemas:
@@ -227,8 +227,8 @@ components:
carrierName: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint only; the persisted snapshot comes from Warehouse supplier master data.}
billOfLadingNo: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint; the persisted snapshot is always frozen from the selected RELEASED booking.}
plannedLoadingAt: {type: string, format: date-time}
payableAmount: {type: number, format: double, minimum: 0, nullable: true, description: Amount payable to the trucking supplier.}
currency: {type: string, enum: [RMB, USD], default: RMB, description: Payable amount currency.}
payableAmount: {type: number, format: double, minimum: 0, nullable: true, description: 应付拖车费,最多两位小数;全部订舱需求货柜确认国内离仓后按实装体积分摊生成应付来源;零金额不生成费用。}
currency: {type: string, enum: [RMB], default: RMB, description: 人民币拖车费;完成时以CNY进入应付费用来源。}
expectedVersion: {type: integer, minimum: 0, description: Must be 0 on create; current version on edit.}
DetailStableReferences:
type: object
@@ -248,5 +248,5 @@ components:
carrierName: {type: string}
billOfLadingNo: {type: string, maxLength: 128, nullable: true, description: Frozen bill of lading snapshot used by dispatch readiness.}
payableAmount: {type: number, format: double, minimum: 0, nullable: true}
currency: {type: string, enum: [RMB, USD]}
currency: {type: string, enum: [RMB]}
attachmentCount: {type: integer, format: int64, minimum: 0, description: Number of attachment references owned by this appointment}