2026-08-08 20:39:49 +08:00
openapi : 3.0.3
info :
2026-08-10 09:11:56 +08:00
title : Truck Appointment API
2026-08-18 09:09:28 +08:00
version : 1.2.0
2026-08-18 15:43:58 +08:00
description : Truck appointments are independent operational records. Ocean booking, container booking and loading plan are optional links. Draft creation/editing does not require a bill of lading or attachment; DISPATCH requires a nonblank billOfLadingNo and at least one active BILL_OF_LADING attachment owned by the appointment customer. When linked to a RELEASED booking, the server freezes and validates the booking bill of lading snapshot. After a PDA loading transaction commits, the server best-effort completes the unique active appointment explicitly linked to that container in an isolated transaction; absence, duplicates or concurrent truck edits never roll back loading completion.
2026-08-08 20:39:49 +08:00
paths :
2026-08-10 09:11:56 +08:00
/api/platform/v1/truck-appointments :
get :
summary : Query truck appointments
2026-08-14 12:50:37 +08:00
parameters :
- {name : customerId, in : query, description : Filter by customer, schema : {type : string, pattern : '^[1-9][0-9]*$' }}
2026-08-10 09:11:56 +08:00
responses :
2026-08-17 19:51:54 +08:00
'200' :
description : Paged truck appointments with stable booking/container snapshots and attachment count
content :
application/json :
schema :
type : object
properties :
data :
type : object
properties :
records : {type : array, items : {$ref : '#/components/schemas/DetailStableReferences' }}
2026-08-10 09:11:56 +08:00
post :
2026-08-18 09:09:28 +08:00
summary : Create an independent truck appointment with optional fulfillment links
2026-08-10 09:11:56 +08:00
requestBody :
required : true
content :
application/json :
schema : {$ref : '#/components/schemas/SaveRequest' }
responses :
2026-08-19 09:14:30 +08:00
'200' : {description : Created appointment, content : {application/json : {schema : {$ref : '#/components/schemas/DetailStableReferences' }}}}
2026-08-10 09:11:56 +08:00
/api/platform/v1/truck-appointments/{id}:
parameters : [ {$ref : '#/components/parameters/AppointmentId' }]
get :
summary : Query a truck appointment
responses :
2026-08-14 14:26:56 +08:00
'200' : {description : Appointment detail, content : {application/json : {schema : {$ref : '#/components/schemas/DetailStableReferences' }}}}
2026-08-10 09:11:56 +08:00
put :
summary : Update an editable truck appointment with optimistic locking
requestBody :
required : true
content :
application/json :
schema : {$ref : '#/components/schemas/SaveRequest' }
responses :
'200' : {description : Updated appointment}
/api/platform/v1/truck-appointments/{id}/{action}:
parameters :
- {$ref : '#/components/parameters/AppointmentId' }
- {$ref : '#/components/parameters/Action' }
- {$ref : '#/components/parameters/IdempotencyKey' }
- {$ref : '#/components/parameters/RequestHash' }
post :
summary : Apply an idempotent appointment lifecycle action
description : ARRIVE, LOAD and DEPART persist their actual event timestamps atomically with the status transition.
requestBody :
required : true
content :
application/json :
schema : {$ref : '#/components/schemas/ActionRequest' }
responses :
'200' : {description : Updated or replayed appointment}
/api/platform/v1/truck-appointments/{id}/reschedule:
parameters :
- {$ref : '#/components/parameters/AppointmentId' }
- {$ref : '#/components/parameters/IdempotencyKey' }
- {$ref : '#/components/parameters/RequestHash' }
- name : plannedLoadingAt
in : query
required : true
schema : {type : string, format : date-time}
post :
summary : Idempotently reschedule an appointment
requestBody :
required : true
content :
application/json :
schema : {$ref : '#/components/schemas/ActionRequest' }
responses :
'200' : {description : Rescheduled or replayed appointment}
2026-08-08 20:39:49 +08:00
/api/platform/v1/truck-appointments/{id}/history:
parameters : [ {$ref : '#/components/parameters/AppointmentId' }]
get :
summary : Query immutable appointment status history
responses :
'200' : {description : History entries including action, from/to status, operator, reason and time}
/api/platform/v1/truck-appointments/{id}/attachments:
parameters : [ {$ref : '#/components/parameters/AppointmentId' }]
get :
summary : Query attachment references owned by the appointment
2026-08-14 14:26:56 +08:00
description : 'Requires platform:firstleg:truck-appointment:list.'
2026-08-08 20:39:49 +08:00
responses :
2026-08-14 14:26:56 +08:00
'200' : {description : Attachment references, content : {application/json : {schema : {type : array, items : {$ref : '#/components/schemas/Attachment' }}}}}
2026-08-08 20:39:49 +08:00
post :
summary : Reference a file already owned by the appointment customer and business scope
2026-08-14 14:26:56 +08:00
description : 'Requires platform:firstleg:truck-appointment:edit. The file must belong to customerId + TRUCK_APPOINTMENT_ATTACHMENT + appointmentId.'
requestBody : {required : true, content : {application/json : {schema : {$ref : '#/components/schemas/AttachmentRequest' }}}}
2026-08-08 20:39:49 +08:00
responses :
2026-08-14 14:26:56 +08:00
'200' : {description : Created attachment reference, content : {application/json : {schema : {$ref : '#/components/schemas/Attachment' }}}}
2026-08-08 20:39:49 +08:00
/api/platform/v1/truck-appointments/{id}/attachments/upload:
parameters : [ {$ref : '#/components/parameters/AppointmentId' }]
post :
summary : Upload and reference a truck appointment attachment
2026-08-14 14:26:56 +08:00
description : 'Requires platform:firstleg:truck-appointment:edit.'
2026-08-08 20:39:49 +08:00
requestBody :
required : true
content :
multipart/form-data :
schema :
type : object
2026-08-18 15:43:58 +08:00
required : [ attachmentType, file]
2026-08-08 20:39:49 +08:00
properties :
2026-08-18 15:43:58 +08:00
attachmentType : {type : string, enum : [BILL_OF_LADING, DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER], description : Attachment classification; BILL_OF_LADING is required before DISPATCH}
2026-08-08 20:39:49 +08:00
file : {type : string, format : binary}
responses :
'200' : {description : Uploaded attachment reference}
/api/platform/v1/truck-appointments/{id}/attachments/{attachmentId}:
parameters :
- {$ref : '#/components/parameters/AppointmentId' }
- {$ref : '#/components/parameters/AttachmentId' }
delete :
summary : Delete an attachment reference owned by the appointment
2026-08-14 14:26:56 +08:00
description : 'Requires platform:firstleg:truck-appointment:edit. Deletes the appointment reference only; the File object is retained.'
2026-08-08 20:39:49 +08:00
responses :
'200' : {description : Reference deleted}
components :
parameters :
AppointmentId : {name : id, in : path, required : true, schema : {type : string, pattern : '^[1-9][0-9]*$' }}
AttachmentId : {name : attachmentId, in : path, required : true, schema : {type : string, pattern : '^[1-9][0-9]*$' }}
2026-08-10 09:11:56 +08:00
Action :
name : action
in : path
required : true
schema :
type : string
enum : [ SUBMIT, DISPATCH, PICKUP, ARRIVE, LOAD, DEPART, COMPLETE, 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 :
2026-08-14 14:26:56 +08:00
AttachmentRequest :
type : object
2026-08-18 15:43:58 +08:00
required : [ fileId, attachmentType]
2026-08-14 14:26:56 +08:00
properties :
fileId : {type : integer, format : int64, minimum : 1 }
2026-08-18 15:43:58 +08:00
attachmentType : {type : string, enum : [BILL_OF_LADING, DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER], description : Attachment classification; BILL_OF_LADING is required before DISPATCH}
2026-08-14 14:26:56 +08:00
fileName : {type : string, maxLength : 255, description : Ignored; authoritative metadata comes from File service}
fileHash : {type : string, maxLength : 128, description : Ignored; authoritative metadata comes from File service}
Attachment :
type : object
properties :
id : {type : integer, format : int64}
appointmentId : {type : integer, format : int64}
fileId : {type : integer, format : int64}
2026-08-18 15:43:58 +08:00
attachmentType : {type : string, enum : [ BILL_OF_LADING, DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER]}
2026-08-14 14:26:56 +08:00
fileName : {type : string}
fileHash : {type : string}
visibility : {type : string, enum : [ PLATFORM]}
uploadedBy : {type : integer, format : int64}
uploadedAt : {type : string, format : date-time}
2026-08-10 09:11:56 +08:00
ActionRequest :
type : object
required : [ expectedVersion]
properties :
expectedVersion : {type : integer, minimum : 0 }
reason : {type : string, maxLength : 500 }
SaveRequest :
type : object
2026-08-18 09:09:28 +08:00
required : [ customerId, carrierId, plannedLoadingAt, expectedVersion]
2026-08-10 09:11:56 +08:00
properties :
2026-08-18 09:09:28 +08:00
outboundOrderId : {type : integer, format : int64, minimum : 1, nullable : true }
oceanBookingId : {type : integer, format : int64, minimum : 1, nullable : true, description : Optional booking association; no RELEASED-state prerequisite. When supplied, customer and warehouse must match.}
containerBookingId : {type : integer, format : int64, minimum : 1, nullable : true, description : Optional ACTIVE container association. When supplied, customer and warehouse must match.}
loadingPlanId : {type : integer, format : int64, minimum : 1, nullable : true, description : Optional loading-plan association. It may be supplied only with containerBookingId and must be that container's current plan.}
warehouseId : {type : integer, format : int64, minimum : 1, nullable : true, description : Optional warehouse scope. Linked booking/container warehouse facts must agree; when omitted the linked fact is frozen if available.}
customerId : {type : integer, format : int64, minimum : 1, description : Required ACTIVE IAM customer used for isolation and attachment ownership.}
customerName : {type : string, maxLength : 128, nullable : true, description : Optional consistency hint only; persisted value is resolved from IAM customer master data.}
carrierId : {type : integer, format : int64, minimum : 1, description : Required ACTIVE Warehouse supplier ID validated as TRUCKING.}
carrierName : {type : string, maxLength : 128, nullable : true, description : Optional consistency hint only; the persisted snapshot comes from Warehouse supplier master data.}
2026-08-18 15:43:58 +08:00
billOfLadingNo : {type : string, maxLength : 128, nullable : true, description : Optional on draft; required before DISPATCH and server-frozen from a linked RELEASED booking when present.}
2026-08-10 09:11:56 +08:00
plannedLoadingAt : {type : string, format : date-time}
2026-08-18 09:09:28 +08:00
expectedVersion : {type : integer, minimum : 0, description : Must be 0 on create; current version on edit.}
2026-08-14 14:26:56 +08:00
DetailStableReferences :
type : object
2026-08-19 09:14:30 +08:00
required : [ appointmentNo, customerId, customerName, carrierId, carrierName, attachmentCount]
2026-08-18 09:09:28 +08:00
description : Stable IDs plus server-resolved saved resource names returned by appointment detail. Fulfillment associations remain null for an independently created appointment.
2026-08-14 14:26:56 +08:00
properties :
2026-08-19 09:14:30 +08:00
appointmentNo : {type : string, pattern : '^TA-[0-9]{6}-[0-9]{4}$' , example : TA-260818-0001, description : 派车单号;按北京时间创建日逐日编号}
2026-08-18 09:09:28 +08:00
oceanBookingId : {type : integer, format : int64, nullable : true }
2026-08-19 09:14:30 +08:00
oceanBookingNo : {type : string, nullable : true, pattern : '^OB-[0-9]{6}-[0-9]{4}$' , example : OB-260818-0001}
2026-08-18 09:09:28 +08:00
containerBookingId : {type : integer, format : int64, nullable : true }
2026-08-19 09:14:30 +08:00
cabinetNo : {type : string, nullable : true, pattern : '^CAB-[0-9]{6}-[0-9]{4}$' , example : CAB-260818-0001}
2026-08-14 14:26:56 +08:00
containerNo : {type : string, nullable : true }
2026-08-18 09:09:28 +08:00
loadingPlanId : {type : integer, format : int64, nullable : true }
warehouseId : {type : integer, format : int64, nullable : true }
warehouseName : {type : string, nullable : true }
2026-08-14 14:26:56 +08:00
customerId : {type : integer, format : int64}
2026-08-18 09:09:28 +08:00
customerName : {type : string, description : Frozen from ACTIVE IAM customer master data; request input cannot override it}
shippingCompanyId : {type : integer, format : int64, nullable : true }
shippingCompanyName : {type : string, nullable : true }
bookingAgentId : {type : integer, format : int64, nullable : true }
bookingAgentName : {type : string, nullable : true }
2026-08-14 14:26:56 +08:00
carrierId : {type : integer, format : int64}
carrierName : {type : string}
2026-08-18 15:43:58 +08:00
billOfLadingNo : {type : string, maxLength : 128, nullable : true, description : Frozen bill of lading snapshot used by dispatch readiness.}
2026-08-17 19:51:54 +08:00
attachmentCount : {type : integer, format : int64, minimum : 0, description : Number of attachment references owned by this appointment}