feat(firstleg): enforce booking-owned truck workflow
This commit is contained in:
@@ -139,6 +139,30 @@ CREATE TABLE IF NOT EXISTS fl_ocean_booking_container_allocation (
|
||||
CONSTRAINT fk_ocean_allocation_container FOREIGN KEY (container_booking_id) REFERENCES fl_container_booking(id)
|
||||
) ENGINE=InnoDB COMMENT='订舱需求与现有柜次的唯一分配关系';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_ocean_booking_document (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '订舱文件关联ID',
|
||||
ocean_booking_id BIGINT UNSIGNED NOT NULL COMMENT '所属海运订舱ID',
|
||||
file_id BIGINT UNSIGNED NOT NULL COMMENT 'File服务文件逻辑ID',
|
||||
document_type VARCHAR(32) NOT NULL COMMENT '文件类型:BOOKING_CONFIRMATION订舱确认、BILL_OF_LADING提单',
|
||||
file_name VARCHAR(255) NOT NULL COMMENT 'File返回的原始文件名快照',
|
||||
file_hash CHAR(64) NULL COMMENT 'File返回的SHA-256快照',
|
||||
size_bytes BIGINT UNSIGNED NULL COMMENT 'File返回的文件大小快照',
|
||||
content_type VARCHAR(128) NULL COMMENT 'File返回的内容类型快照',
|
||||
valid TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否为有效文件关联',
|
||||
uploaded_by BIGINT UNSIGNED NOT NULL COMMENT '上传或关联操作人ID',
|
||||
uploaded_by_name VARCHAR(64) NULL COMMENT '上传或关联操作人姓名快照',
|
||||
uploaded_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '上传或关联时间',
|
||||
invalidated_by BIGINT UNSIGNED NULL COMMENT '作废操作人ID',
|
||||
invalidated_by_name VARCHAR(64) NULL COMMENT '作废操作人姓名快照',
|
||||
invalidated_at DATETIME(3) NULL COMMENT '作废时间',
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_ocean_document_booking (ocean_booking_id,valid,uploaded_at,id),
|
||||
KEY idx_ocean_document_file (file_id),
|
||||
CONSTRAINT fk_ocean_document_booking FOREIGN KEY (ocean_booking_id) REFERENCES fl_ocean_booking(id) ON DELETE CASCADE,
|
||||
CONSTRAINT chk_ocean_document_type CHECK (document_type IN ('BOOKING_CONFIRMATION','BILL_OF_LADING')),
|
||||
CONSTRAINT chk_ocean_document_valid CHECK (valid IN (0,1))
|
||||
) ENGINE=InnoDB COMMENT='订舱聚合拥有的订舱确认与提单文件关联';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fl_ocean_booking_status_history (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '订舱状态历史ID',
|
||||
ocean_booking_id BIGINT UNSIGNED NOT NULL COMMENT '所属海运订舱ID',
|
||||
@@ -227,6 +251,9 @@ DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS trg_ocean_history_before_update;
|
||||
DROP TRIGGER IF EXISTS trg_ocean_history_before_delete;
|
||||
DROP TRIGGER IF EXISTS trg_ocean_document_before_insert;
|
||||
DROP TRIGGER IF EXISTS trg_ocean_document_before_update;
|
||||
DROP TRIGGER IF EXISTS trg_ocean_document_before_delete;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER trg_ocean_history_before_update BEFORE UPDATE ON fl_ocean_booking_status_history FOR EACH ROW
|
||||
BEGIN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='订舱状态历史不可修改'; END$$
|
||||
@@ -234,6 +261,28 @@ CREATE TRIGGER trg_ocean_history_before_delete BEFORE DELETE ON fl_ocean_booking
|
||||
BEGIN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='订舱状态历史不可删除'; END$$
|
||||
DELIMITER ;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER trg_ocean_document_before_insert BEFORE INSERT ON fl_ocean_booking_document FOR EACH ROW
|
||||
BEGIN
|
||||
IF (SELECT status FROM fl_ocean_booking WHERE id=NEW.ocean_booking_id) <> 'DRAFT' THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='已放舱订舱文件永久只读';
|
||||
END IF;
|
||||
END$$
|
||||
CREATE TRIGGER trg_ocean_document_before_update BEFORE UPDATE ON fl_ocean_booking_document FOR EACH ROW
|
||||
BEGIN
|
||||
IF (SELECT status FROM fl_ocean_booking WHERE id=OLD.ocean_booking_id) <> 'DRAFT' THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='已放舱订舱文件永久只读';
|
||||
END IF;
|
||||
IF NEW.ocean_booking_id <> OLD.ocean_booking_id OR NEW.file_id <> OLD.file_id
|
||||
OR NEW.document_type <> OLD.document_type OR NEW.uploaded_by <> OLD.uploaded_by
|
||||
OR NEW.uploaded_at <> OLD.uploaded_at OR NEW.valid > OLD.valid THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='订舱文件只允许在草稿期作废';
|
||||
END IF;
|
||||
END$$
|
||||
CREATE TRIGGER trg_ocean_document_before_delete BEFORE DELETE ON fl_ocean_booking_document FOR EACH ROW
|
||||
BEGIN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='订舱文件关联不可物理删除'; END$$
|
||||
DELIMITER ;
|
||||
|
||||
USE baiyue_iam;
|
||||
DELETE rp FROM iam_role_permission rp WHERE rp.permission_id IN (5102141,5102143,5102144,5102145);
|
||||
DELETE FROM iam_permission WHERE id IN (5102141,5102143,5102144,5102145);
|
||||
|
||||
@@ -53,9 +53,9 @@ CREATE TABLE IF NOT EXISTS fl_truck_appointment_history (
|
||||
operator_name VARCHAR(64) NULL COMMENT '操作人姓名快照', request_id VARCHAR(128) NULL COMMENT '请求链路中的请求ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '历史记录创建时间', PRIMARY KEY(id), KEY idx_truck_history(appointment_id,revision)
|
||||
) ENGINE=InnoDB COMMENT='拖车状态与改约历史';
|
||||
CREATE TABLE IF NOT EXISTS fl_truck_appointment_attachment (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '拖车附件关系ID', appointment_id BIGINT UNSIGNED NOT NULL COMMENT '所属拖车预约ID', file_id BIGINT UNSIGNED NOT NULL COMMENT 'File服务文件逻辑ID', attachment_type VARCHAR(32) NOT NULL COMMENT '附件类型:BILL_OF_LADING提单、DISPATCH_ORDER派车单、DRIVER_DOCUMENT司机证件、VEHICLE_DOCUMENT车辆证件、OTHER其他',
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '拖车附件关系ID', appointment_id BIGINT UNSIGNED NOT NULL COMMENT '所属拖车预约ID', file_id BIGINT UNSIGNED NOT NULL COMMENT 'File服务文件逻辑ID', attachment_type VARCHAR(32) NOT NULL COMMENT '附件类型:DISPATCH_ORDER派车单、DRIVER_DOCUMENT司机证件、VEHICLE_DOCUMENT车辆证件、OTHER其他;订舱确认与提单归订舱聚合',
|
||||
file_name VARCHAR(255) NULL COMMENT '上传时文件名快照', file_hash CHAR(64) NULL COMMENT '文件内容SHA-256摘要', visibility VARCHAR(24) NOT NULL DEFAULT 'INTERNAL' COMMENT '可见范围:INTERNAL仅平台内部、CLIENT客户可见', uploaded_by BIGINT UNSIGNED NOT NULL COMMENT '上传操作人ID',
|
||||
uploaded_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '附件上传时间', PRIMARY KEY(id), UNIQUE KEY uk_truck_attachment(appointment_id,file_id), KEY idx_truck_attachment(appointment_id), CONSTRAINT chk_truck_attachment_type CHECK(attachment_type IN ('BILL_OF_LADING','DISPATCH_ORDER','DRIVER_DOCUMENT','VEHICLE_DOCUMENT','OTHER'))
|
||||
uploaded_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '附件上传时间', PRIMARY KEY(id), UNIQUE KEY uk_truck_attachment(appointment_id,file_id), KEY idx_truck_attachment(appointment_id), CONSTRAINT chk_truck_attachment_type CHECK(attachment_type IN ('DISPATCH_ORDER','DRIVER_DOCUMENT','VEHICLE_DOCUMENT','OTHER'))
|
||||
) ENGINE=InnoDB COMMENT='拖车附件文件引用';
|
||||
CREATE TABLE IF NOT EXISTS fl_truck_appointment_operation (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '拖车写操作幂等记录ID', appointment_id BIGINT UNSIGNED NOT NULL COMMENT '所属拖车预约ID', idempotency_key VARCHAR(128) NOT NULL COMMENT '客户端写操作幂等键', request_hash CHAR(64) NOT NULL COMMENT '规范化请求内容SHA-256摘要;用于识别同键不同请求',
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
openapi: 3.0.3
|
||||
info: {title: Ocean Booking API, version: 2.0.0}
|
||||
info:
|
||||
title: Ocean Booking API
|
||||
version: 2.1.0
|
||||
description: Booking-owned files use File businessType OCEAN_BOOKING_DOCUMENT and businessId=oceanBookingId. Release requires at least one active BOOKING_CONFIRMATION or BILL_OF_LADING file. Released bookings and their file links are permanently read-only.
|
||||
paths:
|
||||
/api/platform/v1/ocean-bookings:
|
||||
get:
|
||||
@@ -29,10 +32,76 @@ paths:
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/release:
|
||||
post:
|
||||
summary: Validate and permanently release a DRAFT
|
||||
description: Release validates the persisted aggregate and never requires or creates a real container number.
|
||||
description: Release validates the persisted aggregate plus at least one active booking-owned BOOKING_CONFIRMATION or BILL_OF_LADING file. It never requires or creates a real container number.
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ReleaseRequest'}}}}
|
||||
responses: {'200': {description: RELEASED detail}}
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/documents:
|
||||
get:
|
||||
summary: List current and invalidated booking-owned file references
|
||||
x-permission: platform:firstleg:ocean-booking:list
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}]
|
||||
responses:
|
||||
'200': {description: Booking document history, content: {application/json: {schema: {$ref: '#/components/schemas/DocumentListResponse'}}}}
|
||||
post:
|
||||
summary: Reference an existing File object in a DRAFT booking
|
||||
description: File scope must be customerId + OCEAN_BOOKING_DOCUMENT + oceanBookingId. The booking version is incremented atomically.
|
||||
x-permission: platform:firstleg:ocean-booking:edit
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/DocumentRequest'}}}}
|
||||
responses:
|
||||
'200': {description: Created reference and latest booking version, content: {application/json: {schema: {$ref: '#/components/schemas/DocumentMutationResponse'}}}}
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/documents/upload:
|
||||
post:
|
||||
summary: Upload and associate a file with a DRAFT booking
|
||||
description: Uploads through File businessType OCEAN_BOOKING_DOCUMENT and increments the booking version atomically.
|
||||
x-permission: platform:firstleg:ocean-booking:edit
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
required: [expectedVersion, documentType, file]
|
||||
properties:
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
documentType: {$ref: '#/components/schemas/DocumentType'}
|
||||
file: {type: string, format: binary}
|
||||
responses:
|
||||
'200': {description: Created reference and latest booking version, content: {application/json: {schema: {$ref: '#/components/schemas/DocumentMutationResponse'}}}}
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/documents/{documentId}:
|
||||
delete:
|
||||
summary: Logically invalidate a booking file reference while DRAFT
|
||||
description: The File object and immutable reference history are retained; RELEASED bookings are read-only.
|
||||
x-permission: platform:firstleg:ocean-booking:edit
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/DocumentId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/DocumentActionRequest'}}}}
|
||||
responses:
|
||||
'200': {description: Invalidation result and latest booking version, content: {application/json: {schema: {$ref: '#/components/schemas/DocumentInvalidationResponse'}}}}
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/documents/{documentId}/download:
|
||||
get:
|
||||
summary: Download an active booking-owned file
|
||||
x-permission: platform:firstleg:ocean-booking:list
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}, {$ref: '#/components/parameters/DocumentId'}]
|
||||
responses:
|
||||
'200': {description: Original file bytes, content: {application/octet-stream: {schema: {type: string, format: binary}}}}
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/prints/shipping-instruction:
|
||||
get:
|
||||
summary: Render the released booking as an export shipping instruction PDF
|
||||
description: Firstleg maps the authoritative released aggregate to SEA_FREIGHT_SHIPPING_INSTRUCTION_A4_V1 and synchronously proxies the generated PDF.
|
||||
x-permission: platform:firstleg:ocean-booking:list
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}]
|
||||
responses:
|
||||
'200': {description: PDF or a business-error JSON envelope, content: {application/pdf: {schema: {type: string, format: binary}}, application/json: {schema: {type: object}}}}
|
||||
/api/platform/v1/ocean-bookings/{oceanBookingId}/prints/bill-of-lading-confirmation:
|
||||
get:
|
||||
summary: Render the released booking as a bill-of-lading confirmation PDF
|
||||
description: Firstleg maps the authoritative released aggregate to BILL_OF_LADING_CONFIRMATION_A4_V1 and synchronously proxies the generated PDF.
|
||||
x-permission: platform:firstleg:ocean-booking:list
|
||||
parameters: [{$ref: '#/components/parameters/OceanBookingId'}]
|
||||
responses:
|
||||
'200': {description: PDF or a business-error JSON envelope, content: {application/pdf: {schema: {type: string, format: binary}}, application/json: {schema: {type: object}}}}
|
||||
/api/platform/v1/ocean-bookings/link-candidates:
|
||||
get:
|
||||
summary: Page released booking requirement candidates for one container
|
||||
@@ -84,6 +153,7 @@ paths:
|
||||
components:
|
||||
parameters:
|
||||
OceanBookingId: {name: oceanBookingId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
DocumentId: {name: documentId, 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:
|
||||
CreateRequest: {type: object, required: [expectedVersion, data], properties: {expectedVersion: {type: integer, enum: [0]}, data: {$ref: '#/components/schemas/DraftData'}}}
|
||||
@@ -131,6 +201,55 @@ components:
|
||||
ContainerRequirementRequest: {type: object, required: [containerType, containerKind, quantity, capacityCbm, maxWeightKg], properties: {containerType: {type: string}, containerKind: {type: string}, quantity: {type: integer, minimum: 1}, capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0}, maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0}}}
|
||||
ReleaseRequest: {type: object, required: [expectedVersion], properties: {expectedVersion: {type: integer, minimum: 0}, reason: {type: string, nullable: true}}}
|
||||
ActionRequest: {type: object, required: [expectedVersion], properties: {expectedVersion: {type: integer, minimum: 0}, reason: {type: string, nullable: true}}}
|
||||
DocumentType: {type: string, enum: [BOOKING_CONFIRMATION, BILL_OF_LADING]}
|
||||
DocumentRequest:
|
||||
type: object
|
||||
required: [expectedVersion, fileId, documentType]
|
||||
properties:
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
fileId: {type: integer, format: int64, minimum: 1}
|
||||
documentType: {$ref: '#/components/schemas/DocumentType'}
|
||||
DocumentActionRequest: {type: object, required: [expectedVersion], properties: {expectedVersion: {type: integer, minimum: 0}}}
|
||||
OceanBookingDocument:
|
||||
type: object
|
||||
required: [id, oceanBookingId, fileId, documentType, fileName, valid, uploadedBy, uploadedAt]
|
||||
properties:
|
||||
id: {type: integer, format: int64}
|
||||
oceanBookingId: {type: integer, format: int64}
|
||||
fileId: {type: integer, format: int64}
|
||||
documentType: {$ref: '#/components/schemas/DocumentType'}
|
||||
fileName: {type: string}
|
||||
fileHash: {type: string, nullable: true}
|
||||
sizeBytes: {type: integer, format: int64, nullable: true}
|
||||
contentType: {type: string, nullable: true}
|
||||
valid: {type: boolean}
|
||||
uploadedBy: {type: integer, format: int64}
|
||||
uploadedByName: {type: string, nullable: true}
|
||||
uploadedAt: {type: string, format: date-time}
|
||||
invalidatedBy: {type: integer, format: int64, nullable: true}
|
||||
invalidatedByName: {type: string, nullable: true}
|
||||
invalidatedAt: {type: string, format: date-time, nullable: true}
|
||||
DocumentMutation:
|
||||
type: object
|
||||
required: [document, bookingVersion]
|
||||
properties:
|
||||
document: {$ref: '#/components/schemas/OceanBookingDocument'}
|
||||
bookingVersion: {type: integer, minimum: 1}
|
||||
DocumentInvalidation:
|
||||
type: object
|
||||
required: [documentId, bookingVersion]
|
||||
properties:
|
||||
documentId: {type: integer, format: int64}
|
||||
bookingVersion: {type: integer, minimum: 1}
|
||||
DocumentListResponse:
|
||||
type: object
|
||||
properties: {code: {type: string, example: '200'}, data: {type: array, items: {$ref: '#/components/schemas/OceanBookingDocument'}}}
|
||||
DocumentMutationResponse:
|
||||
type: object
|
||||
properties: {code: {type: string, example: '200'}, data: {$ref: '#/components/schemas/DocumentMutation'}}
|
||||
DocumentInvalidationResponse:
|
||||
type: object
|
||||
properties: {code: {type: string, example: '200'}, data: {$ref: '#/components/schemas/DocumentInvalidation'}}
|
||||
ChannelOption:
|
||||
type: object
|
||||
required: [priceBookVersionId, channelCode, channelName, priceModel, pricingTaxModes]
|
||||
@@ -189,7 +308,7 @@ components:
|
||||
description: Sum of all container requirement quantities; independent of allocation, linking or unlinking.
|
||||
Detail:
|
||||
type: object
|
||||
required: [oceanBooking, parties, containerRequirements, containers, histories]
|
||||
required: [oceanBooking, parties, containerRequirements, containers, documents, histories]
|
||||
properties:
|
||||
oceanBooking:
|
||||
type: object
|
||||
@@ -198,4 +317,5 @@ components:
|
||||
parties: {type: array}
|
||||
containerRequirements: {type: array}
|
||||
containers: {type: array, description: Existing containers allocated after port pickup linking}
|
||||
documents: {type: array, items: {$ref: '#/components/schemas/OceanBookingDocument'}, description: Current and invalidated booking-owned file references}
|
||||
histories: {type: array}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Truck Appointment API
|
||||
version: 1.2.0
|
||||
description: Truck appointments are independent operational records. Ocean booking, container booking and loading plan are optional links. Draft creation/editing does not require a bill of lading or attachment; DISPATCH requires a nonblank billOfLadingNo and at least one active BILL_OF_LADING attachment owned by the appointment customer. When linked to a RELEASED booking, the server freezes and validates the booking bill of lading snapshot. After a PDA loading transaction commits, the server best-effort completes the unique active appointment explicitly linked to that container in an isolated transaction; absence, duplicates or concurrent truck edits never roll back loading completion.
|
||||
version: 1.3.0
|
||||
description: Every truck appointment must select one RELEASED ocean booking and one ACTIVE real-numbered container already allocated to that booking. The bill-of-lading number is frozen from the booking, and the booking must own at least one active BOOKING_CONFIRMATION or BILL_OF_LADING file under OCEAN_BOOKING_DOCUMENT. Booking and bill files are not owned by truck appointments. After a PDA loading transaction commits, the server best-effort completes the unique active appointment explicitly linked to that container in an isolated transaction; absence, duplicates or concurrent truck edits never roll back loading completion.
|
||||
paths:
|
||||
/api/platform/v1/truck-appointments:
|
||||
get:
|
||||
@@ -22,7 +22,7 @@ paths:
|
||||
properties:
|
||||
records: {type: array, items: {$ref: '#/components/schemas/DetailStableReferences'}}
|
||||
post:
|
||||
summary: Create an independent truck appointment with optional fulfillment links
|
||||
summary: Create a truck appointment for a released booking and its allocated real container
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
@@ -88,7 +88,7 @@ paths:
|
||||
/api/platform/v1/truck-appointments/{id}/attachments:
|
||||
parameters: [{$ref: '#/components/parameters/AppointmentId'}]
|
||||
get:
|
||||
summary: Query attachment references owned by the appointment
|
||||
summary: Query non-booking operational attachment references owned by the appointment
|
||||
description: 'Requires platform:firstleg:truck-appointment:list.'
|
||||
responses:
|
||||
'200': {description: 'Attachment references', content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/Attachment'}}}}}
|
||||
@@ -111,7 +111,7 @@ paths:
|
||||
type: object
|
||||
required: [attachmentType, file]
|
||||
properties:
|
||||
attachmentType: {type: string, enum: [BILL_OF_LADING, DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER], description: Attachment classification; BILL_OF_LADING is required before DISPATCH}
|
||||
attachmentType: {type: string, enum: [DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER], description: Booking confirmations and bills of lading belong to the ocean-booking aggregate}
|
||||
file: {type: string, format: binary}
|
||||
responses:
|
||||
'200': {description: Uploaded attachment reference}
|
||||
@@ -155,7 +155,7 @@ components:
|
||||
required: [fileId, attachmentType]
|
||||
properties:
|
||||
fileId: {type: integer, format: int64, minimum: 1}
|
||||
attachmentType: {type: string, enum: [BILL_OF_LADING, DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER], description: Attachment classification; BILL_OF_LADING is required before DISPATCH}
|
||||
attachmentType: {type: string, enum: [DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER]}
|
||||
fileName: {type: string, maxLength: 255, description: Ignored; authoritative metadata comes from File service}
|
||||
fileHash: {type: string, maxLength: 128, description: Ignored; authoritative metadata comes from File service}
|
||||
Attachment:
|
||||
@@ -164,7 +164,7 @@ components:
|
||||
id: {type: integer, format: int64}
|
||||
appointmentId: {type: integer, format: int64}
|
||||
fileId: {type: integer, format: int64}
|
||||
attachmentType: {type: string, enum: [BILL_OF_LADING, DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER]}
|
||||
attachmentType: {type: string, enum: [DISPATCH_ORDER, DRIVER_DOCUMENT, VEHICLE_DOCUMENT, OTHER]}
|
||||
fileName: {type: string}
|
||||
fileHash: {type: string}
|
||||
visibility: {type: string, enum: [PLATFORM]}
|
||||
@@ -178,24 +178,24 @@ components:
|
||||
reason: {type: string, maxLength: 500}
|
||||
SaveRequest:
|
||||
type: object
|
||||
required: [customerId, carrierId, plannedLoadingAt, expectedVersion]
|
||||
required: [oceanBookingId, containerBookingId, customerId, carrierId, plannedLoadingAt, expectedVersion]
|
||||
properties:
|
||||
outboundOrderId: {type: integer, format: int64, minimum: 1, nullable: true}
|
||||
oceanBookingId: {type: integer, format: int64, minimum: 1, nullable: true, description: 'Optional booking association; no RELEASED-state prerequisite. When supplied, customer and warehouse must match.'}
|
||||
containerBookingId: {type: integer, format: int64, minimum: 1, nullable: true, description: 'Optional ACTIVE container association. When supplied, customer and warehouse must match.'}
|
||||
oceanBookingId: {type: integer, format: int64, minimum: 1, description: Required RELEASED booking; must own an active BOOKING_CONFIRMATION or BILL_OF_LADING file.}
|
||||
containerBookingId: {type: integer, format: int64, minimum: 1, description: Required ACTIVE container already allocated to oceanBookingId and carrying a valid unique ISO 6346 container number.}
|
||||
loadingPlanId: {type: integer, format: int64, minimum: 1, nullable: true, description: Optional loading-plan association. It may be supplied only with containerBookingId and must be that container's current plan.}
|
||||
warehouseId: {type: integer, format: int64, minimum: 1, nullable: true, description: Optional warehouse scope. Linked booking/container warehouse facts must agree; when omitted the linked fact is frozen if available.}
|
||||
customerId: {type: integer, format: int64, minimum: 1, description: Required ACTIVE IAM customer used for isolation and attachment ownership.}
|
||||
customerName: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint only; persisted value is resolved from IAM customer master data.}
|
||||
carrierId: {type: integer, format: int64, minimum: 1, description: Required ACTIVE Warehouse supplier ID validated as TRUCKING.}
|
||||
carrierName: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint only; the persisted snapshot comes from Warehouse supplier master data.}
|
||||
billOfLadingNo: {type: string, maxLength: 128, nullable: true, description: Optional on draft; required before DISPATCH and server-frozen from a linked RELEASED booking when present.}
|
||||
billOfLadingNo: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint; the persisted snapshot is always frozen from the selected RELEASED booking.}
|
||||
plannedLoadingAt: {type: string, format: date-time}
|
||||
expectedVersion: {type: integer, minimum: 0, description: Must be 0 on create; current version on edit.}
|
||||
DetailStableReferences:
|
||||
type: object
|
||||
required: [appointmentNo, customerId, customerName, carrierId, carrierName, attachmentCount]
|
||||
description: Stable IDs plus server-resolved saved resource names returned by appointment detail. Fulfillment associations remain null for an independently created appointment.
|
||||
description: Stable IDs plus server-resolved saved resource names returned by appointment detail. Ocean booking and container associations are always present.
|
||||
properties:
|
||||
appointmentNo: {type: string, pattern: '^TA-[0-9]{6}-[0-9]{4}$', example: TA-260818-0001, description: 派车单号;按北京时间创建日逐日编号}
|
||||
oceanBookingId: {type: integer, format: int64, nullable: true}
|
||||
|
||||
Reference in New Issue
Block a user