fix(firstleg): filter truck booking candidates

This commit is contained in:
2026-09-01 15:41:36 +08:00
parent 8b2a964bfb
commit df1ffbc6bc
9 changed files with 120 additions and 7 deletions
@@ -30,6 +30,16 @@ paths:
responses:
'200': {description: 'Created appointment', content: {application/json: {schema: {$ref: '#/components/schemas/DetailEnvelope'}}}}
'409': {description: 'A0409 - this container already has a non-terminal appointment; message includes its appointment number and asks the operator to continue editing'}
/api/platform/v1/truck-appointments/candidates:
get:
summary: Query authoritative create-time ocean-booking and internal-container candidates
description: Requires platform:firstleg:truck-appointment:list. Returns only RELEASED bookings with an active booking-owned confirmation or bill file and allocated ACTIVE internal containers that have no non-terminal truck appointment and whose loading plan is absent or not COMPLETED. A missing containerNo remains eligible. Completed/LOADED containers, occupied containers and bookings without any remaining eligible allocated container are absent. Edit pages must display their current binding from appointment detail rather than injecting it into this create-only candidate result.
parameters:
- {name: keyword, in: query, required: false, schema: {type: string, maxLength: 64}, description: Matches booking number, bill of lading, cabinet number or real container number}
- {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: Paged flat booking-container candidates, content: {application/json: {schema: {$ref: '#/components/schemas/CandidatePageEnvelope'}}}}
/api/platform/v1/truck-appointments/{id}:
parameters: [{$ref: '#/components/parameters/AppointmentId'}]
get:
@@ -138,6 +148,45 @@ components:
IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}}
RequestHash: {name: X-Request-Hash, in: header, required: false, schema: {type: string, pattern: '^[0-9a-fA-F]{64}$'}}
schemas:
CandidatePageEnvelope:
type: object
required: [code, message, data, timestamp]
properties:
code: {type: string, example: '200'}
message: {type: string}
data:
type: object
required: [records, page, size, total, pages]
properties:
records: {type: array, items: {$ref: '#/components/schemas/Candidate'}}
page: {type: integer, format: int64}
size: {type: integer, format: int64}
total: {type: integer, format: int64}
pages: {type: integer, format: int64}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
timestamp: {type: string, format: date-time}
Candidate:
type: object
required: [oceanBookingId, oceanBookingNo, warehouseId, requirementId, containerType, requirementQuantity, containerBookingId, cabinetNo, bookingDocumentReady]
properties:
oceanBookingId: {type: integer, format: int64}
oceanBookingNo: {type: string}
billOfLadingNo: {type: string, nullable: true}
warehouseId: {type: integer, format: int64}
warehouseName: {type: string, nullable: true}
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
requirementId: {type: integer, format: int64}
containerType: {type: string}
requirementQuantity: {type: integer, minimum: 1}
containerBookingId: {type: integer, format: int64}
cabinetNo: {type: string}
containerNo: {type: string, nullable: true, description: Optional until PICKUP or preload correction; absence does not make the candidate unavailable}
loadingPlanId: {type: integer, format: int64, nullable: true}
loadingPlanNo: {type: string, nullable: true}
loadingPlanStatus: {type: string, nullable: true}
bookingDocumentReady: {type: boolean, enum: [true]}
DetailEnvelope:
type: object
required: [code, message, data, timestamp]