Files
LWLT-AI/schemas/standard_system_operation.schema.json
2026-07-13 19:57:46 +08:00

572 lines
17 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://local.lwltapi/schemas/standard_system_operation.schema.json",
"title": "Standard LTJT System Operation",
"description": "Deterministic task operation contract for LTJT. Team create/batch may defer ERP-derived fields through data.resolution; browser-form mapping remains responsible for ERP readiness.",
"type": "object",
"additionalProperties": false,
"required": ["action", "order_nature", "submit_mode", "data"],
"properties": {
"action": {
"type": "string",
"enum": [
"team_order_create",
"team_order_batch_create",
"shared_plan_create",
"shared_child_order_create",
"order_update",
"passenger_list_import",
"confirmation_export"
]
},
"order_nature": {
"type": "string",
"enum": ["test", "formal"]
},
"submit_mode": {
"type": "string",
"description": "Production should start with dry_run. submit must be explicitly enabled by the owner.",
"enum": ["dry_run", "submit"]
},
"source": {
"type": "object",
"additionalProperties": false,
"properties": {
"instruction_id": { "type": "string" },
"operator": { "type": "string" },
"received_at": { "type": "string", "format": "date-time" },
"notes": { "type": "string" }
}
},
"data": {
"$ref": "#/$defs/operationData"
}
},
"allOf": [
{
"if": {
"properties": { "action": { "const": "team_order_create" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": [
"product",
"departure_dates",
"passenger_counts",
"room_counts",
"prices",
"op_user",
"sales_user"
],
"properties": {
"departure_dates": {
"minItems": 1,
"maxItems": 1
}
}
}
}
}
},
{
"if": {
"properties": { "action": { "const": "team_order_batch_create" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": [
"product",
"departure_dates",
"passenger_counts",
"room_counts",
"prices",
"op_user",
"sales_user"
],
"properties": {
"departure_dates": {
"minItems": 2
}
}
}
}
}
},
{
"if": {
"properties": { "action": { "const": "shared_plan_create" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": [
"product",
"departure_dates",
"planned_capacity",
"op_user"
],
"properties": {
"departure_dates": {
"minItems": 1
}
}
}
}
}
},
{
"if": {
"properties": { "action": { "const": "shared_child_order_create" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": [
"customer",
"passenger_counts",
"prices",
"op_user",
"sales_user"
],
"anyOf": [
{ "required": ["existing_refs"] },
{ "required": ["product", "departure_dates"] }
]
}
}
}
},
{
"if": {
"properties": { "action": { "const": "order_update" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": ["existing_refs", "updates"]
}
}
}
},
{
"if": {
"properties": { "action": { "const": "passenger_list_import" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": ["existing_refs"],
"anyOf": [
{ "required": ["passenger_list"] },
{ "required": ["attachments"] },
{ "required": ["updates"] }
]
}
}
}
},
{
"if": {
"properties": { "action": { "const": "confirmation_export" } },
"required": ["action"]
},
"then": {
"properties": {
"data": {
"required": ["existing_refs"],
"anyOf": [
{ "required": ["confirmation"] },
{ "required": ["export_types"] }
]
}
}
}
}
],
"$defs": {
"operationData": {
"type": "object",
"additionalProperties": false,
"properties": {
"order_mode": { "type": "string" },
"test_marker": { "type": "string" },
"customer": { "$ref": "#/$defs/namedRef" },
"product": { "$ref": "#/$defs/namedRef" },
"route": { "$ref": "#/$defs/namedRef" },
"departure_dates": {
"type": "array",
"items": { "type": "string", "format": "date" },
"uniqueItems": true
},
"trip": { "$ref": "#/$defs/trip" },
"order_number": { "$ref": "#/$defs/orderNumber" },
"recurrence": {
"type": "object",
"additionalProperties": false,
"properties": {
"start_date": { "type": "string", "format": "date" },
"end_date": { "type": "string", "format": "date" },
"pattern": {
"type": "string",
"enum": ["daily", "weekly", "odd_days", "even_days", "specified_dates"]
},
"weekday": {
"type": "array",
"items": {
"type": "integer",
"minimum": 1,
"maximum": 7
},
"uniqueItems": true
}
}
},
"planned_capacity": {
"type": "integer",
"minimum": 1
},
"cycle": { "type": "string" },
"groups_per_date": {
"type": "integer",
"minimum": 1,
"default": 1
},
"plans_per_date": {
"type": "integer",
"minimum": 1,
"default": 1
},
"parent_group_no": { "type": "string" },
"child_order_no": { "type": "string" },
"passenger_counts": { "$ref": "#/$defs/passengerCounts" },
"room_counts": { "$ref": "#/$defs/roomCounts" },
"prices": { "$ref": "#/$defs/prices" },
"op_user": { "$ref": "#/$defs/namedRef" },
"sales_user": { "$ref": "#/$defs/namedRef" },
"logistics": { "$ref": "#/$defs/logistics" },
"special_requests": { "type": "string" },
"passenger_list": { "$ref": "#/$defs/passengerList" },
"attachments": {
"type": "array",
"items": { "$ref": "#/$defs/attachment" }
},
"existing_refs": { "$ref": "#/$defs/existingRefs" },
"updates": {
"type": "object",
"description": "Structured update actions. The browser adapter narrows targets again before any write.",
"properties": {
"status": { "type": "string" },
"actions": {
"type": "array",
"items": { "$ref": "#/$defs/updateAction" }
}
},
"additionalProperties": true
},
"export_types": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"enum": ["xingyou-confirm", "liantai-confirm", "job-order"]
}
},
"recovery": {
"type": "object",
"additionalProperties": false,
"properties": {
"export_only": { "type": "boolean" },
"never_resave": { "type": "boolean" }
}
},
"confirmation": {
"type": "object",
"additionalProperties": false,
"required": ["type"],
"properties": {
"type": {
"type": "string",
"enum": ["default", "confirmation", "xingyou", "xingyou-confirm", "liantai", "liantai-confirm", "job", "job-order"]
},
"language": { "type": "string" },
"format": {
"type": "string",
"enum": ["pdf", "doc", "docx", "xls", "xlsx", "html"]
}
}
},
"system_defaults": {
"type": "object",
"additionalProperties": false,
"properties": {
"fabudanwei": { "type": "string" },
"currency": { "type": "string" },
"business_status": { "type": "string" },
"filing_required": {
"type": "boolean",
"description": "Maps to LTJT yaobeian checkbox. The current add form serializes checked value as 要备案."
}
}
},
"validation_notes": {
"type": "array",
"items": { "type": "string" }
},
"resolution": {
"$ref": "#/$defs/fieldResolution"
}
}
},
"fieldResolution": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["task_ready", "erp_ready"]
},
"deferred_fields": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"enum": ["customer", "route", "trip", "order_number"]
}
}
}
},
"namedRef": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"id": { "type": "string" },
"cpid": { "type": "string" },
"keyword": { "type": "string" },
"ltjt_id": { "type": "string" },
"contact": { "type": "string" },
"origin": { "type": "string" },
"resolved": {
"type": "boolean",
"description": "true only after deterministic lookup found exactly one accepted LTJT record."
}
}
},
"trip": {
"type": "object",
"additionalProperties": false,
"required": ["days"],
"properties": {
"days": { "type": "integer", "minimum": 1, "maximum": 15 },
"nights": { "type": "integer", "minimum": 0, "maximum": 14 },
"label": {
"type": "string",
"description": "LTJT TianShu display value such as 1D, 2D1N, or 4D3N."
}
}
},
"orderNumber": {
"type": "object",
"additionalProperties": false,
"properties": {
"prefix": {
"type": "string",
"description": "LTJT tuanxuhao1 value, normally resolved from route lookup."
},
"suffix": {
"type": "string",
"description": "LTJT tuanxuhao2 value maintained by the user's business system/database."
},
"full": {
"type": "string",
"description": "Optional complete order number when the upstream system stores it as one value."
}
},
"anyOf": [
{ "required": ["prefix", "suffix"] },
{ "required": ["full"] }
]
},
"passengerCounts": {
"type": "object",
"additionalProperties": false,
"required": ["adult", "child_bed", "child_no_bed", "infant", "leader"],
"properties": {
"adult": { "type": "integer", "minimum": 0 },
"child_bed": { "type": "integer", "minimum": 0 },
"child_no_bed": { "type": "integer", "minimum": 0 },
"infant": { "type": "integer", "minimum": 0 },
"leader": { "type": "integer", "minimum": 0 },
"expected_total": { "type": "integer", "minimum": 1 }
}
},
"roomCounts": {
"type": "object",
"additionalProperties": false,
"properties": {
"SGL": { "type": "integer", "minimum": 0 },
"TWN": { "type": "integer", "minimum": 0 },
"TRP": { "type": "integer", "minimum": 0 },
"DBL": { "type": "integer", "minimum": 0 },
"HNM": { "type": "integer", "minimum": 0 },
"TL": { "type": "integer", "minimum": 0 },
"notes": { "type": "string" }
}
},
"prices": {
"type": "object",
"additionalProperties": false,
"properties": {
"currency": { "type": "string" },
"adult": { "type": "number", "minimum": 0 },
"child_bed": { "type": "number", "minimum": 0 },
"child_no_bed": { "type": "number", "minimum": 0 },
"infant": { "type": "number", "minimum": 0 },
"leader": { "type": "number", "minimum": 0 },
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "quantity", "unit_price"],
"properties": {
"name": { "type": "string" },
"unit": { "type": "string" },
"quantity": { "type": "number", "minimum": 0 },
"unit_price": { "type": "number", "minimum": 0 },
"currency": { "type": "string" },
"remark": { "type": "string" }
}
}
}
}
},
"logistics": {
"type": "object",
"additionalProperties": false,
"properties": {
"flights": {
"type": "array",
"items": { "$ref": "#/$defs/textBlock" }
},
"hotels": {
"type": "array",
"items": { "$ref": "#/$defs/textBlock" }
},
"transfers": {
"type": "array",
"items": { "$ref": "#/$defs/textBlock" }
},
"itinerary_notes": {
"type": "array",
"items": { "$ref": "#/$defs/textBlock" }
}
}
},
"textBlock": {
"type": "object",
"additionalProperties": false,
"required": ["text"],
"properties": {
"date": { "type": "string", "format": "date" },
"day_no": { "type": "integer", "minimum": 1 },
"text": { "type": "string" }
}
},
"passengerList": {
"type": "object",
"additionalProperties": false,
"required": ["operation"],
"properties": {
"operation": {
"type": "string",
"enum": [
"none",
"first_import",
"append",
"modify",
"delete",
"replace",
"full_replace",
"reduce"
]
},
"confirmed": {
"type": "boolean",
"description": "Required true for modify/delete/replace/full_replace/reduce before submit."
},
"passenger_count": { "type": "integer", "minimum": 0 },
"file_count": { "type": "integer", "minimum": 0 },
"file_refs": {
"type": "array",
"items": { "$ref": "#/$defs/attachment" }
},
"notes": { "type": "string" }
}
},
"attachment": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": { "type": "string" },
"path": { "type": "string" },
"mime_type": { "type": "string" },
"ltjt_file_ref": { "type": "string" }
}
},
"existingRefs": {
"type": "object",
"additionalProperties": false,
"properties": {
"identifier": { "type": "string" },
"order_no": { "type": "string" },
"plan_no": { "type": "string" },
"parent_group_no": { "type": "string" },
"parent_plan_no": { "type": "string" },
"child_order_no": { "type": "string" },
"ltjt_ddid": { "type": "string" },
"ltjt_tdid": { "type": "string" },
"ltjt_child_id": { "type": "string" },
"ddid": { "type": "string" },
"tid": { "type": "string" },
"parent_tid": { "type": "string" },
"child_did": { "type": "string" }
}
}
,
"updateAction": {
"type": "object",
"additionalProperties": false,
"required": ["target", "operation"],
"properties": {
"target": { "type": "string", "minLength": 1 },
"operation": {
"type": "string",
"enum": ["set", "delta", "append", "traveler_upsert"]
},
"value": {}
}
}
},
"x-runtime_validation": [
"For all write operations, passenger_counts adult + child_bed + child_no_bed + infant + leader must be greater than zero.",
"For order create/update with passenger_list, passenger_list.passenger_count must not exceed passenger_counts.expected_total or computed passenger total.",
"For passenger-list modify/delete/replace/full_replace/reduce, passenger_list.confirmed must be true.",
"All namedRef values used in LTJT hidden fields must be resolved exactly once before submit.",
"Dry-run serialization must match the versioned LTJT form mapping before any submit."
]
}