Files
baiyue-firstleg/firstleg/src/main/resources/openapi/direct-delivery-v1.yaml
T

71 lines
3.9 KiB
YAML

openapi: 3.0.3
info: {title: Direct destination unloading evidence, version: 1.0.0}
paths:
/api/platform/v1/terminal-drayages/{containerBookingId}/direct-deliveries:
get:
summary: Physical loaded inbound sources and immutable direct unloading evidence
x-permission: platform:firstleg:terminal-drayage:list
parameters: [{$ref: '#/components/parameters/Container'}]
responses:
'200':
description: ApiResponse
content:
application/json:
schema:
type: object
properties: {data: {type: array, items: {$ref: '#/components/schemas/View'}}}
'403': {description: Requires platform identity and list permission}
/api/platform/v1/terminal-drayages/{containerBookingId}/direct-deliveries/{inboundId}:
post:
summary: Record actual unloading for one complete physically loaded source
description: Locks the physical container. Requires Lastleg's persisted confirmed DIRECT route, actual pickup, a real recipient and receipt reference, an unambiguous IANA local time, and no warehouse unloading or empty-return fact. Route source failure returns 503. Exact retries replay; changed retries conflict. Does not create warehouse stock. Every loaded source must complete before manual empty return. Unzoned pickup/return timestamps are not compared to destination wall-clock times; cross-location chronology cannot be proven without the source zone. Direct completion and its 72-hour reminder use the latest evidence Instant.
x-permission: platform:firstleg:terminal-drayage:direct-unload:confirm
parameters:
- {$ref: '#/components/parameters/Container'}
- {name: inboundId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
- {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [expectedVersion, actualAt, timezone, receivedBy, evidenceNo]
properties:
expectedVersion: {type: integer, minimum: 0}
actualAt: {type: string, description: Local YYYY-MM-DDTHH:mm:ss without offset}
timezone: {type: string, description: Explicit destination IANA zone}
receivedBy: {type: string, minLength: 1, maxLength: 128}
evidenceNo: {type: string, minLength: 1, maxLength: 128}
remark: {type: string, maxLength: 1000, nullable: true}
responses:
'200':
description: ApiResponse
content:
application/json:
schema:
type: object
properties: {data: {$ref: '#/components/schemas/View'}}
'400': {description: Invalid source, time or evidence}
'403': {description: Requires platform identity and independent unloading permission}
'409': {description: Invalid business prerequisites, version or replay content}
'503': {description: Cannot verify authoritative route}
components:
parameters:
Container: {name: containerBookingId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
schemas:
View:
type: object
properties:
requirementKey: {type: string, description: 'INBOUND:<id>, association only, not a visible business number'}
inboundCode: {type: string, nullable: true}
orderNo: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
packageCount: {type: integer}
version: {type: integer, description: Zero until first actual unloading}
actualAt: {type: string, nullable: true}
timezone: {type: string, nullable: true}
receivedBy: {type: string, nullable: true}
evidenceNo: {type: string, nullable: true}
remark: {type: string, nullable: true}