2170 lines
70 KiB
JSON
2170 lines
70 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 LTJT core-lifecycle operation contract. It accepts a complete set of recognized user-visible update fields; live ERP execution remains capability-tiered and only the browser adapter's verified subset may be written automatically.",
|
||
"$comment": "ltjt-lifecycle-v2.9-roster-leader-contact-2026-08: passenger_list.leader_contact may only mirror the unique canonical passenger row whose trimmed remark is exactly 领队. Ordinary lifecycle execution still requires ERP-enriched exact references; unvalidated update targets are retained for manual review and must not be written automatically.",
|
||
"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",
|
||
"shared_child_order_batch_create",
|
||
"order_update",
|
||
"passenger_list_import",
|
||
"arrangement_guide",
|
||
"arrangement_vehicle",
|
||
"arrangement_hotel",
|
||
"arrangement_transport",
|
||
"arrangement_other",
|
||
"order_update_independent",
|
||
"order_update_shared_plan",
|
||
"order_update_shared_child",
|
||
"order_cancel",
|
||
"order_restore",
|
||
"order_delete",
|
||
"confirmation_export"
|
||
]
|
||
},
|
||
"order_nature": {
|
||
"type": "string",
|
||
"description": "All active operations are production/formal operations.",
|
||
"enum": ["formal"]
|
||
},
|
||
"submit_mode": {
|
||
"type": "string",
|
||
"description": "All Agent-produced operations enter the host in dry-run mode; the host owns the later confirmed write gate.",
|
||
"enum": ["dry_run"]
|
||
},
|
||
"source": {
|
||
"type": "object",
|
||
"description": "Reserved only for explicit historical TEST-202609 execution context. Platform task/session/execution/receipt/batch metadata stays outside the business operation.",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"test_context": { "$ref": "#/$defs/testContext" }
|
||
}
|
||
},
|
||
"data": {
|
||
"$ref": "#/$defs/operationData"
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": { "properties": { "data": { "properties": { "arrangement": { "required": ["vehicle_type"] } }, "required": ["arrangement"] } }, "required": ["data"] },
|
||
"then": { "properties": { "action": { "const": "arrangement_vehicle" }, "data": { "properties": { "arrangement": { "properties": { "mode": { "enum": ["create", "update"] } } } } } } }
|
||
},
|
||
{
|
||
"if": { "properties": { "data": { "properties": { "arrangement": { "required": ["ticket_description"] } }, "required": ["arrangement"] } }, "required": ["data"] },
|
||
"then": { "properties": { "action": { "const": "arrangement_transport" }, "data": { "properties": { "arrangement": { "properties": { "mode": { "enum": ["create", "update"] } } } } } } }
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "team_order_create" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": [
|
||
"customer",
|
||
"product",
|
||
"departure_dates",
|
||
"passenger_counts",
|
||
"room_counts"
|
||
],
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["prices"] },
|
||
{ "required": ["op_user"] },
|
||
{ "required": ["sales_user"] }
|
||
]
|
||
},
|
||
"properties": {
|
||
"room_counts": { "$ref": "#/$defs/teamRoomCounts" },
|
||
"departure_dates": {
|
||
"minItems": 1,
|
||
"maxItems": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "team_order_batch_create" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": [
|
||
"customer",
|
||
"product",
|
||
"departure_dates",
|
||
"recurrence",
|
||
"passenger_counts",
|
||
"room_counts"
|
||
],
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["prices"] },
|
||
{ "required": ["op_user"] },
|
||
{ "required": ["sales_user"] }
|
||
]
|
||
},
|
||
"properties": {
|
||
"room_counts": { "$ref": "#/$defs/teamRoomCounts" },
|
||
"departure_dates": {
|
||
"minItems": 2
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "shared_plan_create" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["product", "planned_capacity", "room_counts"],
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["prices"] },
|
||
{ "required": ["op_user"] },
|
||
{ "required": ["sales_user"] }
|
||
]
|
||
},
|
||
"properties": {
|
||
"room_counts": { "$ref": "#/$defs/teamRoomCounts" }
|
||
},
|
||
"anyOf": [
|
||
{
|
||
"required": ["departure_dates"],
|
||
"properties": {
|
||
"departure_dates": { "minItems": 1 }
|
||
}
|
||
},
|
||
{ "required": ["recurrence"] }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "const": "shared_plan_create" },
|
||
"data": {
|
||
"required": ["departure_dates"],
|
||
"properties": {
|
||
"departure_dates": { "minItems": 2 }
|
||
},
|
||
"anyOf": [
|
||
{ "required": ["split_order"] },
|
||
{ "required": ["customer"] },
|
||
{ "required": ["passenger_counts"] }
|
||
]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"required": ["source"],
|
||
"properties": {
|
||
"source": {
|
||
"required": ["test_context"],
|
||
"properties": {
|
||
"test_context": {
|
||
"allOf": [
|
||
{ "$ref": "#/$defs/testContext" },
|
||
{
|
||
"required": ["run_id", "marker", "account", "native_baseline_id", "live_window", "target_dates", "phase"],
|
||
"properties": {
|
||
"phase": { "const": "shared_batch_split_order_probe" },
|
||
"live_window": { "const": "2026-09" },
|
||
"target_dates": { "minItems": 2 }
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "shared_child_order_create" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": [
|
||
"customer",
|
||
"passenger_counts"
|
||
],
|
||
"anyOf": [
|
||
{ "required": ["existing_refs"] },
|
||
{ "required": ["product", "departure_dates"] }
|
||
],
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"properties": {
|
||
"parent_group_no": { "type": "string", "pattern": "TEST-202609" }
|
||
},
|
||
"required": ["parent_group_no"]
|
||
}
|
||
},
|
||
"required": ["existing_refs"]
|
||
},
|
||
"then": {
|
||
"required": ["special_requests"],
|
||
"properties": {
|
||
"special_requests": { "type": "string", "pattern": "TEST-202609" }
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "shared_child_order_batch_create" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["customer", "product", "recurrence", "passenger_counts"]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "order_update" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["existing_refs", "updates"]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"enum": [
|
||
"passenger_list_import",
|
||
"arrangement_guide",
|
||
"arrangement_vehicle",
|
||
"arrangement_hotel",
|
||
"arrangement_transport",
|
||
"arrangement_other",
|
||
"order_update_independent",
|
||
"order_update_shared_plan",
|
||
"order_update_shared_child",
|
||
"order_cancel",
|
||
"order_restore",
|
||
"order_delete"
|
||
]
|
||
}
|
||
},
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["existing_refs"],
|
||
"properties": {
|
||
"existing_refs": {
|
||
"required": ["kind", "tid"]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"required": ["source"],
|
||
"properties": {
|
||
"source": { "required": ["test_context"] }
|
||
}
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"required": ["departure_date", "owner_account", "marker"],
|
||
"properties": {
|
||
"departure_date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"owner_account": { "type": "string", "minLength": 1 },
|
||
"marker": { "const": "TEST-202609" }
|
||
}
|
||
},
|
||
"passenger_list": {
|
||
"required": ["marker"]
|
||
},
|
||
"transition": {
|
||
"required": ["marker"]
|
||
},
|
||
"arrangement": {
|
||
"properties": {
|
||
"date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"start_date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"end_date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"remark": { "type": "string", "pattern": "TEST-202609" },
|
||
"changes": {
|
||
"properties": {
|
||
"date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"start_date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"end_date": { "type": "string", "format": "date", "pattern": "^2026-09-" },
|
||
"remark": { "type": "string", "pattern": "TEST-202609" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"else": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"required": ["resolved", "resolution_source"],
|
||
"properties": {
|
||
"resolved": { "const": true },
|
||
"resolution_source": { "const": "erp_unique_match" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "passenger_list_import" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["passenger_list"],
|
||
"properties": {
|
||
"existing_refs": {
|
||
"required": ["kind", "expected_passenger_count"],
|
||
"properties": { "kind": { "enum": ["independent_order", "shared_child_order"] } }
|
||
},
|
||
"passenger_list": {
|
||
"properties": {
|
||
"rows": {
|
||
"items": { "$ref": "#/$defs/canonicalPassengerRow" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"enum": [
|
||
"arrangement_guide",
|
||
"arrangement_vehicle",
|
||
"arrangement_hotel",
|
||
"arrangement_transport",
|
||
"arrangement_other"
|
||
]
|
||
}
|
||
},
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": { "required": ["arrangement"] }
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "enum": ["arrangement_guide", "arrangement_vehicle", "arrangement_hotel", "arrangement_transport", "arrangement_other"] } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"properties": { "kind": { "enum": ["independent_order", "shared_plan"] } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"enum": [
|
||
"order_update_independent",
|
||
"order_update_shared_plan",
|
||
"order_update_shared_child"
|
||
]
|
||
}
|
||
},
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"anyOf": [
|
||
{ "required": ["updates"] },
|
||
{
|
||
"required": ["receivable_fixture"],
|
||
"properties": {
|
||
"receivable_fixture": {
|
||
"properties": { "operation": { "enum": ["add", "clear", "clear_generated_zero"] } },
|
||
"required": ["operation"]
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"properties": {
|
||
"updates": { "$ref": "#/$defs/lifecycleUpdates" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "enum": ["order_cancel", "order_restore"] } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": { "required": ["transition"] }
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "order_delete" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"required": ["source"],
|
||
"properties": {
|
||
"source": {
|
||
"required": ["test_context"],
|
||
"properties": {
|
||
"test_context": { "required": ["allowlist_id"] }
|
||
}
|
||
},
|
||
"data": { "required": ["delete_guard"] }
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "passenger_list_import" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["existing_refs", "passenger_list"]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "enum": ["arrangement_guide", "arrangement_hotel"] } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": { "required": ["resource"] }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "arrangement_vehicle" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": { "required": ["supplier", "item", "start_date", "end_date", "quantity"] }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "arrangement_transport" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": { "required": ["supplier", "item", "date", "quantity"] }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "arrangement_other" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": { "required": ["supplier", "item", "date"] }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "arrangement_hotel" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": { "required": ["resource", "room_type", "start_date", "end_date", "room_count"] }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "enum": ["arrangement_vehicle", "arrangement_hotel", "arrangement_transport", "arrangement_other"] },
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": { "mode": { "enum": ["update", "clear"] } },
|
||
"required": ["mode"]
|
||
}
|
||
},
|
||
"required": ["arrangement"]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": { "target": { "required": ["row_id"] } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "enum": ["arrangement_guide", "arrangement_vehicle", "arrangement_hotel", "arrangement_transport", "arrangement_other"] },
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": { "mode": { "const": "update" } },
|
||
"required": ["mode"]
|
||
}
|
||
},
|
||
"required": ["arrangement"]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": { "required": ["target", "changes"] }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "enum": ["arrangement_guide", "arrangement_vehicle", "arrangement_transport", "arrangement_other"] }
|
||
},
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"mode": {
|
||
"enum": [
|
||
"create",
|
||
"update",
|
||
"clear"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "const": "arrangement_hotel" },
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": { "mode": { "const": "update" } },
|
||
"required": ["mode"]
|
||
}
|
||
},
|
||
"required": ["arrangement"]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"changes": {
|
||
"type": "object",
|
||
"minProperties": 1,
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"resource": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"room_type": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"end_date": {
|
||
"type": "string",
|
||
"format": "date"
|
||
},
|
||
"room_count": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
},
|
||
"remark": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "const": "arrangement_other" },
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": { "mode": { "const": "clear" } },
|
||
"required": ["mode"]
|
||
}
|
||
},
|
||
"required": ["arrangement"]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"required": ["filing", "preserve_filing"],
|
||
"properties": { "preserve_filing": { "const": true } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "order_update_independent" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"oneOf": [
|
||
{
|
||
"required": ["updates"],
|
||
"not": { "required": ["receivable_fixture"] },
|
||
"properties": {
|
||
"updates": {
|
||
"properties": {
|
||
"actions": {
|
||
"items": {
|
||
"properties": {
|
||
"target": { "$ref": "#/$defs/lifecycleUpdateTarget" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"required": ["receivable_fixture"],
|
||
"not": { "required": ["updates"] },
|
||
"properties": {
|
||
"receivable_fixture": {
|
||
"required": ["operation"],
|
||
"properties": { "operation": { "const": "clear_generated_zero" } }
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"properties": {
|
||
"existing_refs": { "required": ["kind"], "properties": { "kind": { "const": "independent_order" } } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "order_update_shared_plan" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["updates"],
|
||
"properties": {
|
||
"existing_refs": { "required": ["kind"], "properties": { "kind": { "const": "shared_plan" } } },
|
||
"updates": { "properties": { "actions": { "items": { "properties": { "target": { "$ref": "#/$defs/lifecycleUpdateTarget" } } } } } },
|
||
"receivable_fixture": { "properties": { "operation": { "const": "none" } } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "order_update_shared_child" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"oneOf": [
|
||
{
|
||
"required": ["updates"],
|
||
"properties": {
|
||
"receivable_fixture": { "properties": { "operation": { "const": "none" } } }
|
||
}
|
||
},
|
||
{
|
||
"required": ["receivable_fixture"],
|
||
"not": { "required": ["updates"] },
|
||
"properties": {
|
||
"receivable_fixture": {
|
||
"required": ["operation"],
|
||
"properties": { "operation": { "enum": ["add", "clear"] } }
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"properties": {
|
||
"existing_refs": { "required": ["kind"], "properties": { "kind": { "const": "shared_child_order" } } },
|
||
"updates": { "properties": { "actions": { "items": { "properties": { "target": { "$ref": "#/$defs/lifecycleUpdateTarget" } } } } } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "order_restore" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"transition": { "properties": { "mode": { "const": "edit" } } }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": { "action": { "const": "confirmation_export" } },
|
||
"required": ["action"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["existing_refs"],
|
||
"properties": {
|
||
"existing_refs": {
|
||
"required": ["kind"],
|
||
"properties": { "kind": { "enum": ["independent_order", "shared_plan", "shared_child_order"] } }
|
||
},
|
||
"confirmation": {
|
||
"not": { "required": ["format"] }
|
||
}
|
||
},
|
||
"anyOf": [
|
||
{ "required": ["confirmation"] },
|
||
{ "required": ["export_types"] }
|
||
]
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"required": ["source"],
|
||
"properties": {
|
||
"source": { "required": ["test_context"] }
|
||
}
|
||
},
|
||
"else": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"required": ["resolved", "resolution_source"],
|
||
"properties": {
|
||
"resolved": { "const": true },
|
||
"resolution_source": { "const": "erp_unique_match" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "const": "confirmation_export" },
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"properties": { "kind": { "const": "shared_child_order" } },
|
||
"required": ["kind"]
|
||
}
|
||
},
|
||
"required": ["existing_refs"]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"allOf": [
|
||
{
|
||
"anyOf": [
|
||
{ "required": ["child_order_no"] },
|
||
{ "required": ["ddid"] },
|
||
{ "required": ["child_did"] }
|
||
]
|
||
},
|
||
{
|
||
"anyOf": [
|
||
{ "required": ["parent_group_no"] },
|
||
{ "required": ["parent_plan_no"] },
|
||
{ "required": ["plan_no"] }
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": { "const": "confirmation_export" },
|
||
"data": {
|
||
"properties": {
|
||
"existing_refs": {
|
||
"properties": { "kind": { "const": "shared_plan" } },
|
||
"required": ["kind"]
|
||
}
|
||
},
|
||
"required": ["existing_refs"]
|
||
}
|
||
},
|
||
"required": ["action", "data"]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"required": ["confirmation"],
|
||
"not": { "required": ["export_types"] },
|
||
"properties": {
|
||
"confirmation": {
|
||
"required": ["type"],
|
||
"properties": { "type": { "const": "visitor-list" } }
|
||
},
|
||
"existing_refs": {
|
||
"required": ["tid"],
|
||
"allOf": [
|
||
{
|
||
"anyOf": [
|
||
{ "required": ["identifier"] },
|
||
{ "required": ["parent_group_no"] },
|
||
{ "required": ["parent_plan_no"] },
|
||
{ "required": ["plan_no"] }
|
||
]
|
||
},
|
||
{
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["ddid"] },
|
||
{ "required": ["child_did"] },
|
||
{ "required": ["ltjt_ddid"] },
|
||
{ "required": ["ltjt_child_id"] }
|
||
]
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"const": "arrangement_guide"
|
||
},
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"mode": {
|
||
"const": "update"
|
||
}
|
||
},
|
||
"required": [
|
||
"mode"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"arrangement"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"action",
|
||
"data"
|
||
]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"changes": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"resource": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"remark": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
}
|
||
}
|
||
},
|
||
"target": {
|
||
"properties": {
|
||
"slot_index": {
|
||
"const": 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"const": "arrangement_vehicle"
|
||
},
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"mode": {
|
||
"const": "update"
|
||
}
|
||
},
|
||
"required": [
|
||
"mode"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"arrangement"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"action",
|
||
"data"
|
||
]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"changes": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"supplier": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"remark": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"item": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"quantity": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"const": "arrangement_transport"
|
||
},
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"mode": {
|
||
"const": "update"
|
||
}
|
||
},
|
||
"required": [
|
||
"mode"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"arrangement"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"action",
|
||
"data"
|
||
]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"changes": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"supplier": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"remark": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"item": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"quantity": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"action": {
|
||
"const": "arrangement_other"
|
||
},
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"mode": {
|
||
"const": "update"
|
||
}
|
||
},
|
||
"required": [
|
||
"mode"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"arrangement"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"action",
|
||
"data"
|
||
]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"changes": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"supplier": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"remark": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"item": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"quantity": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
},
|
||
"filing": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"number": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"entry_port": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"exit_port": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": {
|
||
"properties": {
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"quantity": {
|
||
"const": 0
|
||
}
|
||
},
|
||
"required": [
|
||
"quantity"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"arrangement"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"data"
|
||
]
|
||
},
|
||
"then": {
|
||
"properties": {
|
||
"action": {
|
||
"const": "arrangement_other"
|
||
},
|
||
"data": {
|
||
"properties": {
|
||
"arrangement": {
|
||
"properties": {
|
||
"mode": {
|
||
"const": "update"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"$defs": {
|
||
"operationData": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"order_mode": { "type": "string" },
|
||
"customer": { "$ref": "#/$defs/namedRef" },
|
||
"product": { "$ref": "#/$defs/namedRef" },
|
||
"leader": { "$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,
|
||
"required": ["start_date", "end_date"],
|
||
"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" },
|
||
"split_order": { "$ref": "#/$defs/splitOrder" },
|
||
"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" },
|
||
"batch_targets": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"maxItems": 500,
|
||
"uniqueItems": true,
|
||
"items": { "$ref": "#/$defs/sharedPlanBatchTarget" }
|
||
},
|
||
"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
|
||
},
|
||
"arrangement": { "$ref": "#/$defs/arrangement" },
|
||
"transition": { "$ref": "#/$defs/transition" },
|
||
"delete_guard": { "$ref": "#/$defs/deleteGuard" },
|
||
"receivable_fixture": { "$ref": "#/$defs/receivableFixture" },
|
||
"visitor_name": { "type": "string" },
|
||
"export_types": {
|
||
"type": "array",
|
||
"uniqueItems": true,
|
||
"items": {
|
||
"type": "string",
|
||
"enum": [
|
||
"xingyou-confirm",
|
||
"liantai-confirm",
|
||
"job-order",
|
||
"visitor-list",
|
||
"guide-confirm",
|
||
"hotel-preorder",
|
||
"transport-preorder",
|
||
"filing-current",
|
||
"filing-history",
|
||
"pickup-sign"
|
||
]
|
||
}
|
||
},
|
||
"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": [
|
||
"xingyou-confirm",
|
||
"liantai-confirm",
|
||
"job-order",
|
||
"visitor-list",
|
||
"guide-confirm",
|
||
"hotel-preorder",
|
||
"transport-preorder",
|
||
"filing-current",
|
||
"filing-history",
|
||
"pickup-sign"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"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"]
|
||
}
|
||
},
|
||
"stage": { "const": "erp_readonly" },
|
||
"target": { "type": "string", "enum": ["unique", "batch"] },
|
||
"candidate_count": { "type": "integer", "minimum": 1, "maximum": 500 },
|
||
"target_kind": { "type": "string", "enum": ["independent_order", "shared_plan", "shared_child_order"] },
|
||
"write_attempted": { "const": false }
|
||
}
|
||
},
|
||
"sharedPlanBatchTarget": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["parent_group_no", "tid", "departure_date"],
|
||
"properties": {
|
||
"parent_group_no": { "type": "string", "minLength": 1 },
|
||
"tid": { "type": "string", "pattern": "^\\d+$" },
|
||
"departure_date": { "type": "string", "format": "date" }
|
||
}
|
||
},
|
||
"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" },
|
||
"source_region": {
|
||
"type": "string",
|
||
"minLength": 1,
|
||
"description": "Optional explicit customer/product source-market keyword. When omitted, the plugin derives a conservative region token from the resolved names."
|
||
},
|
||
"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": ["suffix"] },
|
||
{ "required": ["full"] }
|
||
]
|
||
},
|
||
"passengerCounts": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"description": "Required sparse passenger-count object. Only categories present in the user input need to be emitted.",
|
||
"minProperties": 1,
|
||
"anyOf": [
|
||
{ "required": ["adult"] },
|
||
{ "required": ["child_bed"] },
|
||
{ "required": ["child_no_bed"] },
|
||
{ "required": ["infant"] },
|
||
{ "required": ["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 }
|
||
}
|
||
},
|
||
"splitOrder": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"description": "Optional shared-plan child information. Each field is independently optional for one date. Multi-date customer/passenger facts were repeated in E2E3/E2E4 but still require the explicit TEST-202609 shared_batch_split_order_probe until business release approval.",
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"customer": { "$ref": "#/$defs/namedRef" },
|
||
"passenger_counts": { "$ref": "#/$defs/passengerCounts" }
|
||
}
|
||
},
|
||
"roomCounts": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"description": "Required sparse room-count object. Team create/batch uses SGL, TWN, TRP, and DBL; HNM/TL remain compatibility keys for other operation types.",
|
||
"minProperties": 1,
|
||
"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" }
|
||
}
|
||
},
|
||
"teamRoomCounts": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"description": "Required sparse team room-count object. Only SGL, TWN, TRP, and DBL are accepted for active newbooking operations.",
|
||
"minProperties": 1,
|
||
"properties": {
|
||
"SGL": { "type": "integer", "minimum": 0 },
|
||
"TWN": { "type": "integer", "minimum": 0 },
|
||
"TRP": { "type": "integer", "minimum": 0 },
|
||
"DBL": { "type": "integer", "minimum": 0 }
|
||
}
|
||
},
|
||
"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" }
|
||
}
|
||
},
|
||
"passengerLeaderContact": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["sequence", "name", "phone"],
|
||
"properties": {
|
||
"sequence": { "type": "integer", "minimum": 1, "maximum": 5000 },
|
||
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
|
||
"phone": { "type": "string", "minLength": 1, "maxLength": 200 }
|
||
}
|
||
},
|
||
"passengerList": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["operation"],
|
||
"properties": {
|
||
"operation": {
|
||
"type": "string",
|
||
"description": "first_import 按明确序号补录空白行;full_replace 仅在确认后覆盖用户提供的序号。",
|
||
"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 },
|
||
"row_count": { "type": "integer", "minimum": 0, "description": "本次提供的游客行数,可少于 ERP 当前游客位数量。" },
|
||
"rows": {
|
||
"type": "array",
|
||
"items": { "type": "object" }
|
||
},
|
||
"text": { "type": "string", "description": "Explicit synthetic import text; the adapter never reads an unreferenced real file implicitly." },
|
||
"leader_contact": { "$ref": "#/$defs/passengerLeaderContact" },
|
||
"file_count": { "type": "integer", "minimum": 0 },
|
||
"file_refs": {
|
||
"type": "array",
|
||
"items": { "$ref": "#/$defs/attachment" }
|
||
},
|
||
"notes": { "type": "string" },
|
||
"marker": { "const": "TEST-202609" }
|
||
}
|
||
},
|
||
"canonicalPassengerRow": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["序号", "姓名", "NAME", "性别", "出生日期", "出生地", "证件类型", "证件号码", "签发地", "签发日", "有效期", "电话", "备注"],
|
||
"properties": {
|
||
"序号": { "type": "integer", "minimum": 1 },
|
||
"姓名": { "type": "string" },
|
||
"NAME": { "type": "string" },
|
||
"性别": { "type": "string" },
|
||
"出生日期": { "type": "string" },
|
||
"出生地": { "type": "string" },
|
||
"证件类型": { "const": "护照" },
|
||
"证件号码": { "type": "string" },
|
||
"签发地": { "type": "string" },
|
||
"签发日": { "type": "string" },
|
||
"有效期": { "type": "string" },
|
||
"电话": { "type": "string" },
|
||
"备注": { "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": {
|
||
"kind": {
|
||
"type": "string",
|
||
"enum": ["independent_order", "shared_plan", "shared_child_order"]
|
||
},
|
||
"identifier": { "type": "string" },
|
||
"order_no": { "type": "string" },
|
||
"group_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" },
|
||
"visitor_name": { "type": "string" },
|
||
"departure_date": { "type": "string", "format": "date" },
|
||
"expected_passenger_count": { "type": "integer", "minimum": 0 },
|
||
"arrangement_history": { "type": "boolean" },
|
||
"owner_account": { "type": "string" },
|
||
"marker": { "type": "string" },
|
||
"resolved": { "type": "boolean" },
|
||
"resolution_source": { "type": "string", "enum": ["erp_unique_match"] }
|
||
}
|
||
},
|
||
"testContext": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["run_id", "marker", "account", "native_baseline_id"],
|
||
"properties": {
|
||
"run_id": { "type": "string", "minLength": 1 },
|
||
"marker": { "const": "TEST-202609" },
|
||
"account": { "type": "string", "minLength": 1 },
|
||
"native_baseline_id": { "type": "string", "minLength": 1 },
|
||
"allow_live_write": { "type": "boolean" },
|
||
"allowlist_id": { "type": "string", "minLength": 1 },
|
||
"live_window": { "const": "2026-09" },
|
||
"target_dates": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"uniqueItems": true,
|
||
"items": {
|
||
"type": "string",
|
||
"format": "date",
|
||
"pattern": "^2026-09-"
|
||
}
|
||
},
|
||
"created_refs": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"items": { "$ref": "#/$defs/createdRef" }
|
||
},
|
||
"phase": { "type": "string" },
|
||
"operator": { "type": "string" }
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": { "allow_live_write": { "const": true } },
|
||
"required": ["allow_live_write"]
|
||
},
|
||
"then": { "required": ["live_window", "target_dates", "created_refs"] }
|
||
}
|
||
]
|
||
},
|
||
"createdRef": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["marker", "kind"],
|
||
"anyOf": [
|
||
{ "required": ["identifier"] },
|
||
{ "required": ["order_no"] },
|
||
{ "required": ["plan_no"] },
|
||
{ "required": ["child_order_no"] },
|
||
{ "required": ["parent_group_no"] },
|
||
{ "required": ["ddid"] },
|
||
{ "required": ["tid"] }
|
||
],
|
||
"properties": {
|
||
"identifier": { "type": "string", "minLength": 1 },
|
||
"kind": { "type": "string", "enum": ["independent_order", "shared_plan", "shared_child_order"] },
|
||
"order_no": { "type": "string" },
|
||
"group_no": { "type": "string" },
|
||
"plan_no": { "type": "string" },
|
||
"parent_group_no": { "type": "string" },
|
||
"parent_plan_no": { "type": "string" },
|
||
"child_order_no": { "type": "string" },
|
||
"ddid": { "type": "string" },
|
||
"tid": { "type": "string" },
|
||
"child_did": { "type": "string" },
|
||
"ltjt_ddid": { "type": "string" },
|
||
"ltjt_tdid": { "type": "string" },
|
||
"ltjt_child_id": { "type": "string" },
|
||
"marker": { "const": "TEST-202609" }
|
||
}
|
||
},
|
||
"arrangement": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["mode", "status", "remark", "side_effect_policy"],
|
||
"properties": {
|
||
"mode": { "type": "string", "enum": ["create", "update", "clear"] },
|
||
"target": { "$ref": "#/$defs/arrangementTarget" },
|
||
"changes": { "$ref": "#/$defs/arrangementChanges" },
|
||
"resource": { "$ref": "#/$defs/namedRef" },
|
||
"supplier": { "$ref": "#/$defs/namedRef" },
|
||
"vehicle_type": { "type": "string", "minLength": 1, "pattern": "\\S" },
|
||
"ticket_description": { "type": "string", "minLength": 1, "pattern": "\\S" },
|
||
"item": { "type": "string", "minLength": 1 },
|
||
"room_type": { "type": "string", "minLength": 1 },
|
||
"date": { "type": "string", "format": "date" },
|
||
"start_date": { "type": "string", "format": "date" },
|
||
"end_date": { "type": "string", "format": "date" },
|
||
"quantity": { "type": "integer", "minimum": 0 },
|
||
"room_count": { "type": "integer", "minimum": 1 },
|
||
"status": { "enum": ["未安排", "未确认"] },
|
||
"remark": { "type": "string" },
|
||
"side_effect_policy": { "const": "no_external" },
|
||
"marker": { "const": "TEST-202609" },
|
||
"filing": { "$ref": "#/$defs/filingDetails" },
|
||
"preserve_filing": { "type": "boolean" }
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": {
|
||
"properties": { "mode": { "enum": ["update", "clear"] } },
|
||
"required": ["mode"]
|
||
},
|
||
"then": { "required": ["target"] }
|
||
},
|
||
{
|
||
"if": { "properties": { "mode": { "const": "clear" } }, "required": ["mode"] },
|
||
"then": { "properties": { "target": { "properties": { "slot_index": { "const": 0 } } } } }
|
||
}
|
||
]
|
||
},
|
||
"arrangementChanges": {
|
||
"type": "object",
|
||
"minProperties": 1,
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"resource": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"item": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"room_type": {
|
||
"type": "string",
|
||
"minLength": 1
|
||
},
|
||
"date": {
|
||
"type": "string",
|
||
"format": "date"
|
||
},
|
||
"start_date": {
|
||
"type": "string",
|
||
"format": "date"
|
||
},
|
||
"end_date": {
|
||
"type": "string",
|
||
"format": "date"
|
||
},
|
||
"quantity": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
},
|
||
"room_count": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
},
|
||
"remark": {
|
||
"type": "string"
|
||
},
|
||
"supplier": {
|
||
"$ref": "#/$defs/namedRef"
|
||
},
|
||
"filing": {
|
||
"$ref": "#/$defs/filingDetails"
|
||
}
|
||
}
|
||
},
|
||
"arrangementTarget": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["slot_index"],
|
||
"properties": {
|
||
"slot_index": { "type": "integer", "minimum": 0 },
|
||
"row_id": { "type": "string", "minLength": 1 }
|
||
}
|
||
},
|
||
"transition": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["mode", "target_kind", "from_status", "to_status"],
|
||
"properties": {
|
||
"mode": { "type": "string", "enum": ["edit", "list"] },
|
||
"target_kind": { "type": "string", "enum": ["independent_order", "shared_plan", "shared_child_order"] },
|
||
"from_status": { "type": "string" },
|
||
"to_status": { "type": "string", "enum": ["预订", "已确认", "已取消", "收客中"] },
|
||
"receivables_cleared": { "type": "boolean" },
|
||
"arrangements_cleared": { "type": "boolean" },
|
||
"expected_passenger_count": { "type": "integer", "minimum": 0 },
|
||
"marker": { "const": "TEST-202609" },
|
||
"remark": { "type": "string" }
|
||
}
|
||
},
|
||
"filingDetails": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"number": { "type": "string" },
|
||
"date": { "type": "string", "format": "date" },
|
||
"entry_port": { "type": "string" },
|
||
"exit_port": { "type": "string" },
|
||
"guide": { "$ref": "#/$defs/namedRef" },
|
||
"driver": { "$ref": "#/$defs/namedRef" },
|
||
"remark": { "type": "string" }
|
||
}
|
||
},
|
||
"deleteGuard": {
|
||
"type": "object",
|
||
"description": "Host-supplied deletion authorization and evidence. For shared-plan deletion, child_refs_deleted is only an upstream assertion: the browser adapter must independently prove child_count=0 from a fresh native list response during preflight and repeat that proof immediately before the delete write.",
|
||
"additionalProperties": false,
|
||
"required": ["marker", "allowlist_id", "account", "run_id", "created_refs", "post_delete_requery", "export_evidence_frozen", "delete_authorized"],
|
||
"properties": {
|
||
"marker": { "const": "TEST-202609" },
|
||
"allowlist_id": { "type": "string", "minLength": 1 },
|
||
"account": { "type": "string", "minLength": 1 },
|
||
"run_id": { "type": "string", "minLength": 1 },
|
||
"created_refs": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/createdRef" } },
|
||
"post_delete_requery": { "const": true },
|
||
"export_evidence_frozen": { "const": true },
|
||
"delete_authorized": { "const": true },
|
||
"child_refs_deleted": { "type": "boolean" },
|
||
"delete_sequence": { "type": "string", "enum": ["child_before_parent"] }
|
||
}
|
||
},
|
||
"receivableGeneratedZeroRow": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["row_id", "name", "quantity", "unit_price", "amount", "currency", "paid", "settled"],
|
||
"properties": {
|
||
"row_id": { "type": "string", "pattern": "^[1-9][0-9]*$" },
|
||
"name": { "type": "string", "enum": ["成人团费", "单人房差"] },
|
||
"quantity": { "type": "integer", "minimum": 1 },
|
||
"unit_price": { "const": 0 },
|
||
"amount": { "const": 0 },
|
||
"currency": { "const": "CNY" },
|
||
"paid": { "const": false },
|
||
"settled": { "const": false }
|
||
}
|
||
},
|
||
"receivableFixture": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["operation", "marker"],
|
||
"properties": {
|
||
"operation": { "type": "string", "enum": ["add", "clear", "clear_generated_zero", "none"] },
|
||
"row_id": { "type": "string", "pattern": "^[1-9][0-9]*$" },
|
||
"rows": {
|
||
"type": "array",
|
||
"minItems": 2,
|
||
"maxItems": 2,
|
||
"uniqueItems": true,
|
||
"items": { "$ref": "#/$defs/receivableGeneratedZeroRow" }
|
||
},
|
||
"name": { "const": "其他费用" },
|
||
"quantity": { "const": 1 },
|
||
"unit_price": { "const": 0.01 },
|
||
"currency": { "const": "CNY" },
|
||
"remark": { "type": "string", "maxLength": 100, "pattern": "TEST-202609" },
|
||
"paid": { "const": false },
|
||
"settled": { "const": false },
|
||
"marker": { "const": "TEST-202609" }
|
||
},
|
||
"allOf": [
|
||
{
|
||
"if": { "properties": { "operation": { "const": "add" } }, "required": ["operation"] },
|
||
"then": {
|
||
"required": ["name", "quantity", "unit_price", "currency", "remark", "paid", "settled"],
|
||
"not": { "required": ["row_id"] }
|
||
}
|
||
},
|
||
{
|
||
"if": { "properties": { "operation": { "const": "clear" } }, "required": ["operation"] },
|
||
"then": { "required": ["row_id", "name", "quantity", "unit_price", "currency", "remark", "paid", "settled"] }
|
||
},
|
||
{
|
||
"if": { "properties": { "operation": { "const": "clear_generated_zero" } }, "required": ["operation"] },
|
||
"then": {
|
||
"required": ["rows"],
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["row_id"] }, { "required": ["name"] }, { "required": ["quantity"] },
|
||
{ "required": ["unit_price"] }, { "required": ["currency"] }, { "required": ["remark"] },
|
||
{ "required": ["paid"] }, { "required": ["settled"] }
|
||
]
|
||
}
|
||
}
|
||
},
|
||
{
|
||
"if": { "properties": { "operation": { "const": "none" } }, "required": ["operation"] },
|
||
"then": {
|
||
"not": {
|
||
"anyOf": [
|
||
{ "required": ["row_id"] }, { "required": ["name"] }, { "required": ["quantity"] },
|
||
{ "required": ["unit_price"] }, { "required": ["currency"] }, { "required": ["remark"] },
|
||
{ "required": ["paid"] }, { "required": ["settled"] }, { "required": ["rows"] }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"lifecycleUpdateTarget": {
|
||
"type": "string",
|
||
"pattern": "^(twin_room_count|planned_capacity|lodging_note|departure_date|trip_days|customer|product|leader|route|status|remark|xiadanbeizhu|booking_note|pax\\.(adult|child_bed|child_no_bed|infant|leader|expected_total)|rooms\\.(SGL|TWN|TRP|DBL|HNM|TL)|prices\\.(adult|child_bed|child_no_bed|infant|leader))$"
|
||
},
|
||
"lifecycleUpdateAction": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["target", "operation"],
|
||
"properties": {
|
||
"target": {
|
||
"type": "string",
|
||
"$ref": "#/$defs/lifecycleUpdateTarget"
|
||
},
|
||
"operation": { "type": "string", "enum": ["set", "delta", "append", "clear", "traveler_upsert"] },
|
||
"value": {}
|
||
}
|
||
},
|
||
"lifecycleUpdates": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["actions"],
|
||
"properties": {
|
||
"actions": {
|
||
"type": "array",
|
||
"minItems": 1,
|
||
"maxItems": 32,
|
||
"items": { "$ref": "#/$defs/lifecycleUpdateAction" }
|
||
}
|
||
}
|
||
},
|
||
"updateAction": {
|
||
"type": "object",
|
||
"additionalProperties": false,
|
||
"required": ["target", "operation"],
|
||
"properties": {
|
||
"target": { "type": "string", "minLength": 1 },
|
||
"operation": {
|
||
"type": "string",
|
||
"enum": ["set", "delta", "append", "clear", "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.",
|
||
"An HTTP 200 response without an explicit success signal and a matching fresh requery is never a completed lifecycle write.",
|
||
"For shared-plan order_cancel, the adapter must discover every concrete child from a fresh SP_OrderList response, fetch every child detail afresh, and require every child status to equal 已取消 before completion.",
|
||
"Shared-plan order_restore restores only the parent; every child status must be re-read and no child may be reported restored without its own order_restore operation.",
|
||
"Update parsing preserves all recognized business-visible targets and allows multiple actions; the browser adapter automatically submits only its live-validated target map (currently independent twin_room_count, rooms.SGL, rooms.TWN and the mapped passenger counts, shared-plan planned_capacity and shared-child lodging_note), while other recognized targets require manual review. Exact clear_generated_zero receivable cleanup remains a separate internal operation on the same route.",
|
||
"Arrangement create uses status 未安排 for hotels and 未确认 for other arrangement types. Arrangement update targets one exact existing hotel row, status 未安排 or 未确认. Legacy updates change end_date/room_count at slot 0; Program date-selected updates may replace resource and its ERP-linked room_type plus room_count at the resolved slot. Program-only guide/vehicle/transport/other replacements now target a unique existing record; dates only locate it. Native selection supplies linked fields, optional fields remain unchanged when omitted, payment/audit/confirmed/realized guards and historical test-context restrictions still apply.",
|
||
"A multi-date shared_plan_create carrying customer/passenger split facts remains restricted to the explicit shared_batch_split_order_probe test context; E2E3/E2E4 established the ERP behavior, but ordinary release still requires business approval and every date must retain native response plus object-level requery.",
|
||
"confirmation_export reads and validates the ERP source; visitor-list retains the original ERP XLS as a platform archive artifact and generates a real XLSX delivery artifact, with AgentBus/WeChat limited to the XLSX. If XLSX conversion fails, external attachment delivery is blocked instead of returning the raw XLS. Other types are converted to PDF before attachment delivery and fall back to their source file if conversion fails. It must not accept a requested output format or claim scheduling or external delivery."
|
||
]
|
||
}
|