171 lines
11 KiB
YAML
171 lines
11 KiB
YAML
openapi: 3.0.3
|
|
info: {title: Ocean Booking API, version: 2.0.0}
|
|
paths:
|
|
/api/platform/v1/ocean-bookings:
|
|
get:
|
|
summary: List DRAFT and RELEASED bookings
|
|
description: containerCount is the sum of quantity across all container requirements for the booking. It is zero when no requirement exists and never represents linked or ACTIVE containers.
|
|
responses:
|
|
'200':
|
|
description: Booking page; each row uses the frozen requirement-total containerCount semantic
|
|
post:
|
|
summary: Create an editable DRAFT
|
|
description: Creates only the booking aggregate and container requirements; no containerNo, container row, or allocation is created.
|
|
parameters: [{$ref: '#/components/parameters/IdempotencyKey'}]
|
|
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateRequest'}}}}
|
|
responses: {'200': {description: DRAFT detail}}
|
|
/api/platform/v1/ocean-bookings/{oceanBookingId}:
|
|
get: {summary: Get booking detail, parameters: [{$ref: '#/components/parameters/OceanBookingId'}], responses: {'200': {description: Detail}}}
|
|
put:
|
|
summary: Replace a DRAFT
|
|
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
|
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/UpdateRequest'}}}}
|
|
responses: {'200': {description: Updated DRAFT}}
|
|
delete:
|
|
summary: Delete a DRAFT; RELEASED is immutable
|
|
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
|
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ActionRequest'}}}}
|
|
responses: {'200': {description: Deleted}}
|
|
/api/platform/v1/ocean-bookings/{oceanBookingId}/release:
|
|
post:
|
|
summary: Validate and permanently release a DRAFT
|
|
description: Release validates the persisted aggregate and never requires or creates a real container number.
|
|
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
|
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ReleaseRequest'}}}}
|
|
responses: {'200': {description: RELEASED detail}}
|
|
/api/platform/v1/ocean-bookings/link-candidates:
|
|
get:
|
|
summary: Page released booking requirement candidates for one container
|
|
description: Requires platform:firstleg:ocean-booking:list. Returns only linkable requirement candidates: RELEASED, remainingQuantity greater than zero, and exact warehouseId, channelCode and containerType. Capacity and max weight are derived display snapshots and never eligibility fields. Allocated quantity counts only ACTIVE containers still pointing to the same booking requirement and is calculated by one bounded set query; booking detail calls are not used. An empty result is a normal successful page. Final target-container mutability is revalidated by the link command.
|
|
x-permission: platform:firstleg:ocean-booking:list
|
|
parameters:
|
|
- {name: warehouseId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
|
- {name: channelCode, in: query, required: true, schema: {type: string, maxLength: 64}}
|
|
- {name: containerType, in: query, required: true, schema: {type: string, maxLength: 32}}
|
|
- {name: page, in: query, required: false, schema: {type: integer, format: int64, minimum: 1, default: 1}}
|
|
- {name: size, in: query, required: false, schema: {type: integer, format: int64, minimum: 1, maximum: 200, default: 20}}
|
|
responses:
|
|
'200':
|
|
description: Business envelope containing a bounded candidate page
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/LinkCandidateResponse'}
|
|
/api/platform/v1/ocean-bookings/channels:
|
|
get:
|
|
summary: List ACTIVE channels for an origin warehouse
|
|
description: Requires platform:firstleg:ocean-booking:list. Channel names are resolved from the current ACTIVE price book and frozen by the server on save.
|
|
parameters:
|
|
- {name: originWarehouseId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
|
responses:
|
|
'200':
|
|
description: Channel options
|
|
content:
|
|
application/json:
|
|
schema: {type: array, items: {$ref: '#/components/schemas/ChannelOption'}}
|
|
components:
|
|
parameters:
|
|
OceanBookingId: {name: oceanBookingId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
|
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
|
|
schemas:
|
|
CreateRequest: {type: object, required: [expectedVersion, data], properties: {expectedVersion: {type: integer, enum: [0]}, data: {$ref: '#/components/schemas/DraftData'}}}
|
|
UpdateRequest: {type: object, required: [expectedVersion, data], properties: {expectedVersion: {type: integer, minimum: 0}, data: {$ref: '#/components/schemas/DraftData'}}}
|
|
DraftData:
|
|
type: object
|
|
description: Fields may be incomplete in DRAFT. RELEASE validates the complete persisted aggregate.
|
|
properties:
|
|
customerId: {type: integer, format: int64, nullable: true}
|
|
customerName: {type: string, nullable: true}
|
|
channelCode: {type: string, nullable: true}
|
|
warehouseId: {type: integer, format: int64, nullable: true}
|
|
billOfLadingNo: {type: string, nullable: true}
|
|
shippingCompanyId: {type: integer, format: int64, nullable: true}
|
|
shippingCompanyName: {type: string, nullable: true}
|
|
bookingAgentId:
|
|
type: integer
|
|
format: int64
|
|
nullable: true
|
|
description: Warehouse supplier ID; release validates ACTIVE category BOOKING; booking suppliers do not use domestic/international scope.
|
|
bookingAgentName:
|
|
type: string
|
|
nullable: true
|
|
description: Read-only consistency hint; the persisted snapshot always comes from Warehouse.
|
|
vesselName: {type: string, nullable: true}
|
|
voyageNo: {type: string, nullable: true}
|
|
departurePortCode: {type: string, nullable: true}
|
|
departurePortName: {type: string, nullable: true}
|
|
destinationPortCode: {type: string, nullable: true}
|
|
destinationPortName: {type: string, nullable: true}
|
|
placeOfDelivery: {type: string, nullable: true}
|
|
serviceTerm: {type: string, nullable: true}
|
|
freightTerm: {type: string, nullable: true}
|
|
estimatedSailingAt: {type: string, format: date-time, nullable: true}
|
|
estimatedArrivalAt: {type: string, format: date-time, nullable: true}
|
|
remark: {type: string, nullable: true}
|
|
parties: {type: array, nullable: true, items: {$ref: '#/components/schemas/PartyRequest'}}
|
|
containerRequirements: {type: array, nullable: true, items: {$ref: '#/components/schemas/ContainerRequirementRequest'}}
|
|
PartyRequest: {type: object, required: [partyType, partyName], properties: {partyType: {type: string, enum: [SHIPPER, CONSIGNEE, NOTIFY_PARTY]}, partyName: {type: string}, address: {type: string, nullable: true}, contactName: {type: string, nullable: true}, contactPhone: {type: string, nullable: true}}}
|
|
ContainerRequirementRequest: {type: object, required: [containerType, containerKind, quantity, capacityCbm, maxWeightKg], properties: {containerType: {type: string}, containerKind: {type: string}, quantity: {type: integer, minimum: 1}, capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0}, maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0}}}
|
|
ReleaseRequest: {type: object, required: [expectedVersion], properties: {expectedVersion: {type: integer, minimum: 0}, reason: {type: string, nullable: true}}}
|
|
ActionRequest: {type: object, required: [expectedVersion], properties: {expectedVersion: {type: integer, minimum: 0}, reason: {type: string, nullable: true}}}
|
|
ChannelOption:
|
|
type: object
|
|
required: [priceBookVersionId, channelCode, channelName, priceModel, pricingTaxModes]
|
|
properties:
|
|
priceBookVersionId: {type: integer, format: int64}
|
|
channelCode: {type: string}
|
|
channelName: {type: string}
|
|
priceModel: {type: string}
|
|
pricingTaxModes: {type: array, items: {type: string}}
|
|
LinkCandidate:
|
|
type: object
|
|
required: [oceanBookingId, bookingNo, requirementId, containerType, capacityCbm, maxWeightKg, requiredQuantity, allocatedQuantity, remainingQuantity, customerName, warehouseName, channelName]
|
|
properties:
|
|
oceanBookingId: {type: string, pattern: '^[0-9]+$'}
|
|
bookingNo: {type: string}
|
|
requirementId: {type: string, pattern: '^[0-9]+$'}
|
|
containerType: {type: string}
|
|
capacityCbm: {type: number}
|
|
maxWeightKg: {type: number}
|
|
requiredQuantity: {type: integer, minimum: 1}
|
|
allocatedQuantity: {type: integer, format: int64, minimum: 0}
|
|
remainingQuantity: {type: integer, format: int64, minimum: 1}
|
|
customerName: {type: string}
|
|
warehouseName: {type: string}
|
|
channelName: {type: string}
|
|
LinkCandidatePage:
|
|
type: object
|
|
required: [records, page, size, total, pages]
|
|
properties:
|
|
records: {type: array, items: {$ref: '#/components/schemas/LinkCandidate'}}
|
|
page: {type: integer, format: int64, minimum: 1}
|
|
size: {type: integer, format: int64, minimum: 1}
|
|
total: {type: integer, format: int64, minimum: 0}
|
|
pages: {type: integer, format: int64, minimum: 0}
|
|
LinkCandidateResponse:
|
|
type: object
|
|
required: [code, data]
|
|
properties:
|
|
code: {type: string, example: '200'}
|
|
message: {type: string, nullable: true}
|
|
data: {$ref: '#/components/schemas/LinkCandidatePage'}
|
|
OceanBookingListRow:
|
|
type: object
|
|
properties:
|
|
containerCount:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
description: Sum of all container requirement quantities; independent of allocation, linking or unlinking.
|
|
Detail:
|
|
type: object
|
|
required: [oceanBooking, parties, containerRequirements, containers, histories]
|
|
properties:
|
|
oceanBooking:
|
|
type: object
|
|
properties:
|
|
bookingNo: {type: string, pattern: '^OB-[0-9]{6}-[0-9]{4}$', example: OB-260818-0001, description: 平台订舱号;按北京时间创建日逐日编号}
|
|
parties: {type: array}
|
|
containerRequirements: {type: array}
|
|
containers: {type: array, description: Existing containers allocated after port pickup linking}
|
|
histories: {type: array}
|