feat(firstleg): confirm domestic departure by container
This commit is contained in:
@@ -1,85 +1,116 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Phase 3 Domestic Outbound Dispatch API
|
||||
version: 1.0.0
|
||||
title: Phase 3 Container-level Domestic Outbound Dispatch API
|
||||
version: 2.0.0
|
||||
paths:
|
||||
/api/platform/v1/first-leg/outbound-dispatches:
|
||||
get:
|
||||
summary: Query outbound aggregates by order, inbound or container
|
||||
summary: Query the outbound aggregate for one container booking
|
||||
description: Returns one container-level aggregate containing every real inbound binding. No per-inbound partial outbound aggregate is exposed.
|
||||
x-permission: platform:firstleg:outbound-dispatch:list
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/OrderId'}
|
||||
- {$ref: '#/components/parameters/InboundId'}
|
||||
- {$ref: '#/components/parameters/ContainerBookingId'}
|
||||
- {$ref: '#/components/parameters/ContainerBookingIdQuery'}
|
||||
responses:
|
||||
'200':
|
||||
description: Business envelope containing matching aggregates, each with stable cabinetNo and real containerNo
|
||||
description: Business envelope containing a single matching aggregate in a list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data: {type: array, items: {$ref: '#/components/schemas/Aggregate'}}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/detail:
|
||||
/api/platform/v1/first-leg/outbound-dispatches/{containerBookingId}:
|
||||
get:
|
||||
summary: Query one aggregate and its unified timeline
|
||||
summary: Query one container-level aggregate and unified timeline
|
||||
x-permission: platform:firstleg:outbound-dispatch:view
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/OrderId'}
|
||||
- {$ref: '#/components/parameters/InboundId'}
|
||||
- {$ref: '#/components/parameters/ContainerBookingId'}
|
||||
- {$ref: '#/components/parameters/ContainerBookingIdPath'}
|
||||
responses:
|
||||
'200':
|
||||
description: Business envelope containing aggregate detail
|
||||
description: Business envelope containing all inbound bindings and one visible dispatch version
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
aggregate: {$ref: '#/components/schemas/Aggregate'}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/check-gate:
|
||||
data: {$ref: '#/components/schemas/Detail'}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/{containerBookingId}/gate:
|
||||
get:
|
||||
summary: Evaluate the fail-closed domestic outbound gate
|
||||
summary: Evaluate every inbound binding in the fail-closed container outbound gate
|
||||
x-permission: platform:firstleg:outbound-dispatch:check
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/OrderId'}
|
||||
- {$ref: '#/components/parameters/InboundId'}
|
||||
- {$ref: '#/components/parameters/ContainerBookingId'}
|
||||
- {$ref: '#/components/parameters/ContainerBookingIdPath'}
|
||||
responses:
|
||||
'200': {description: Business envelope containing every gate item}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/confirm-dispatch:
|
||||
'200': {description: Business envelope containing the container gate and per-inbound gate results}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/{containerBookingId}/confirm:
|
||||
post:
|
||||
summary: Confirm domestic dispatch and enter WAITING_FOR_LOADING
|
||||
summary: Atomically confirm domestic departure for the entire container
|
||||
description: Locks every real inbound binding, requires every gate to pass, advances all technical rows in one transaction, records one visible history, and creates the CarrierScheduleQuery/DEPARTED_WAREHOUSE fact once. No partial success is possible.
|
||||
x-permission: platform:firstleg:outbound-dispatch:confirm
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/ContainerBookingIdPath'}
|
||||
- {$ref: '#/components/parameters/IdempotencyKey'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json: {schema: {$ref: '#/components/schemas/ActionRequest'}}
|
||||
responses:
|
||||
'200': {description: Business envelope; gate or version failures use business error code}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/reverse-dispatch:
|
||||
'200': {description: Same key and same payload replays the single container-level result; stale version or changed payload returns A0409}
|
||||
/api/platform/v1/first-leg/outbound-dispatches/{containerBookingId}/reverse:
|
||||
post:
|
||||
summary: Reverse WAITING_FOR_LOADING only before maritime tracking starts
|
||||
description: Once an actual DEPARTED_WAREHOUSE node exists, reversal is rejected with business code A0409 so READY_FOR_DISPATCH cannot coexist with maritime tracking.
|
||||
summary: Atomically reverse the entire container before any actual shipping node exists
|
||||
description: Once an actual DEPARTED_WAREHOUSE node exists, reversal is rejected with business code A0409 so an outbound fact can never coexist with READY_FOR_DISPATCH.
|
||||
x-permission: platform:firstleg:outbound-dispatch:reverse
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/ContainerBookingIdPath'}
|
||||
- {$ref: '#/components/parameters/IdempotencyKey'}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json: {schema: {$ref: '#/components/schemas/ActionRequest'}}
|
||||
responses:
|
||||
'200': {description: Business envelope containing reverted aggregate}
|
||||
'200': {description: Business envelope containing the reverted container aggregate}
|
||||
components:
|
||||
parameters:
|
||||
OrderId: {name: orderId, in: query, schema: {type: integer, format: int64, minimum: 1}}
|
||||
InboundId: {name: inboundId, in: query, schema: {type: integer, format: int64, minimum: 1}}
|
||||
ContainerBookingId: {name: containerBookingId, in: query, schema: {type: integer, format: int64, minimum: 1}}
|
||||
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
|
||||
ContainerBookingIdQuery:
|
||||
name: containerBookingId
|
||||
in: query
|
||||
required: true
|
||||
schema: {type: integer, format: int64, minimum: 1}
|
||||
ContainerBookingIdPath:
|
||||
name: containerBookingId
|
||||
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:
|
||||
Aggregate:
|
||||
type: object
|
||||
required: [orderId, orderNo, inboundId, inboundCode, tenantId, inboundStatus, containerBookingId, cabinetNo, loadingPlanId, loadingPlanStatus, dispatchStatus, version, gate]
|
||||
required: [containerBookingId, cabinetNo, loadingPlanId, loadingPlanStatus, dispatchStatus, version, inbounds, gate]
|
||||
properties:
|
||||
containerBookingId: {type: integer, format: int64}
|
||||
cabinetNo: {type: string, description: Stable cabinet number}
|
||||
containerNo: {type: string, nullable: true, description: Real container number}
|
||||
loadingPlanId: {type: integer, format: int64}
|
||||
loadingPlanStatus: {type: string}
|
||||
oceanBookingId: {type: integer, format: int64, nullable: true}
|
||||
oceanBookingStatus: {type: string, nullable: true}
|
||||
truckAppointmentId: {type: integer, format: int64, nullable: true}
|
||||
truckAppointmentStatus: {type: string, nullable: true}
|
||||
dispatchStatus: {type: string, description: One visible container-level status}
|
||||
version: {type: integer, minimum: 0, description: One optimistic-lock version shared by all technical inbound rows}
|
||||
inbounds:
|
||||
type: array
|
||||
minItems: 1
|
||||
items: {$ref: '#/components/schemas/InboundBinding'}
|
||||
gate: {$ref: '#/components/schemas/ContainerGateResult'}
|
||||
InboundBinding:
|
||||
type: object
|
||||
required: [orderId, orderNo, inboundId, inboundCode, tenantId, inboundStatus]
|
||||
properties:
|
||||
orderId: {type: integer, format: int64}
|
||||
orderNo: {type: string}
|
||||
@@ -89,25 +120,35 @@ components:
|
||||
customerId: {type: integer, format: int64, nullable: true}
|
||||
customerName: {type: string, nullable: true}
|
||||
inboundStatus: {type: string}
|
||||
containerBookingId: {type: integer, format: int64}
|
||||
cabinetNo: {type: string, description: 稳定柜次号}
|
||||
containerNo: {type: string, nullable: true, description: 真实集装箱号}
|
||||
loadingPlanId: {type: integer, format: int64}
|
||||
loadingPlanStatus: {type: string}
|
||||
pickTaskId: {type: integer, format: int64, nullable: true}
|
||||
pickTaskStatus: {type: string, nullable: true}
|
||||
oceanBookingId: {type: integer, format: int64, nullable: true}
|
||||
oceanBookingStatus: {type: string, nullable: true}
|
||||
truckAppointmentId: {type: integer, format: int64, nullable: true}
|
||||
truckAppointmentStatus: {type: string, nullable: true}
|
||||
dispatchStatus: {type: string}
|
||||
version: {type: integer, minimum: 0}
|
||||
gate: {type: object}
|
||||
ContainerGateResult:
|
||||
type: object
|
||||
required: [passed, inbounds, checkedAt]
|
||||
properties:
|
||||
passed: {type: boolean}
|
||||
inbounds:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required: [inboundId, inboundCode, gate]
|
||||
properties:
|
||||
inboundId: {type: integer, format: int64}
|
||||
inboundCode: {type: string}
|
||||
gate: {type: object}
|
||||
checkedAt: {type: string, format: date-time}
|
||||
Detail:
|
||||
type: object
|
||||
required: [aggregate, timeline]
|
||||
properties:
|
||||
aggregate: {$ref: '#/components/schemas/Aggregate'}
|
||||
timeline:
|
||||
type: array
|
||||
description: Unified immutable facts; a container confirm or reverse contributes one visible history item.
|
||||
items: {type: object}
|
||||
ActionRequest:
|
||||
type: object
|
||||
required: [inboundId, containerBookingId, expectedVersion]
|
||||
required: [expectedVersion]
|
||||
properties:
|
||||
inboundId: {type: integer, format: int64, minimum: 1}
|
||||
containerBookingId: {type: integer, format: int64, minimum: 1}
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
remark: {type: string, maxLength: 500}
|
||||
|
||||
Reference in New Issue
Block a user