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:, 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}