Files
baiyue-firstleg/firstleg/src/main/resources/openapi/truck-appointments-v1.yaml
T

207 lines
12 KiB
YAML
Raw Normal View History

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}