71 lines
3.9 KiB
YAML
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}
|