实现 M002 V4 入站解析基线

This commit is contained in:
andy
2026-07-18 17:32:07 +07:00
parent b949177feb
commit 6be14f2b40
9 changed files with 1445 additions and 31 deletions

View File

@@ -45,7 +45,7 @@
| `requirements/M002-order-task-workflow-v2.md` | 阶段记录 | M002 订单任务主流程 V2记录当前已阶段实现的 AI 过渡层、S000/S999 兼容、订单任务流转、任务确认和 OPERA 模拟骨架。 |
| `requirements/M002-order-task-workflow-v3.md` | 当前有效 | M002 订单任务主流程 V3基于 2026-07-11 P0 冻结基线和 2026-07-12 P0.1 Parent Group 修订,记录 S10/S99、40 路由、方案 C、type-known manual review 同卡解阻和 fail-closed 边界。 |
| `requirements/M002-task-field-control-contract-v1.md` | 当前有效 | M002 任务卡字段控件契约 V1记录任务详情 `fields[]` 控件元数据、人工复核控件复用和前后端开发边界。 |
| `requirements/M002-v4-agent-callback-field-contract.md` | 当前有效 | M002 V4 Agent 回调字段契约,基于 2026-07-18 业务基线和最新答复,冻结 `source_message``order_contexts``message_events`、订单级 Basic Information、六类 Event、S10 和校验口径;当前代码尚未按 V4 改造。 |
| `requirements/M002-v4-agent-callback-field-contract.md` | 当前有效 | M002 V4 Agent 回调字段契约,基于 2026-07-18 业务基线和最新答复,冻结 `source_message``order_contexts``message_events`、订单级 Basic Information、六类 Event、S10 和校验口径;后端已完成 V4 入站解析 CP1完整 V4 多卡主流程仍待后续实现。 |
| `requirements/M002-superagent-task-result-api-contract.md` | 阶段记录 | M002 SuperAgent 任务结果入站接口契约阶段记录;对外总契约以 `integrations/superagent-api-contract.md` 为准。 |
| `requirements/M002-ai-query-minimal-fields.md` | 阶段记录 | M002 SuperAgent 查询上下文接口 1、2 最小字段落地记录;对外总契约以 `integrations/superagent-api-contract.md` 为准。 |
| `requirements/M002-backend-data-model-design.md` | 阶段记录 | M002 后端数据模型设计,记录 AI 过渡层、订单、任务、任务卡、审计和 OPERA 模拟结果表。 |
@@ -90,6 +90,6 @@
- 接口暴露、权限、酒店隔离和审计边界以 `security-access-control-boundary.md` 为总检查清单;具体 SuperAgent / MCP / AgentBus 请求响应契约仍以 `integrations/` 下对应文档为准。
- AI-NSES 的通用标准以 `../import/reusable/ai-native-software-engineering-standard.md` 为复用来源;本项目采用方式以 `ai-native-adoption.md` 为准。
- M002 V1 只作为历史参考V2 记录当前阶段实现;后续 M002 新开发以 `requirements/M002-order-task-workflow-v3.md` 为开发基线。
- 2026-07-18 导入的业务基线已形成 `requirements/M002-v4-agent-callback-field-contract.md` 字段契约M002 V4 主流程、后端数据模型和接口改造尚未落地,开发前需要继续形成 V4 主流程方案
- 2026-07-18 导入的业务基线已形成 `requirements/M002-v4-agent-callback-field-contract.md` 字段契约M002 V4 入站解析 CP1 已落地V4 订单任务 + 多卡领域模型、前端页面模型和完整主流程仍需继续形成 checkpoint
- 前端展示 / 编辑字段以 2026-07-11 P0 冻结基线中的前端字段表、0712 字段控件说明和 `requirements/M002-task-field-control-contract-v1.md` 为白名单和控件契约基线;后端完整校验和 OPERA 映射仍以任务卡完整矩阵、0711 runtime 契约和后端规则为准。
- 时间点语义以 `backend-time-design.md` 为准;数据库时间点按 UTC 理解API 返回带 `Z` 的 UTC 时间,页面再按酒店或用户时区展示。

View File

@@ -445,6 +445,7 @@ RESERVATION_ROOMING_LIST_GENERATE
- `POST /api/system/reservation/demo-data` 只用于 dev/test 联调造数,不是生产业务页面接口;访问口令不能进入前端代码。
- `POST /api/system/debug/eml-superagent-runs` 只用于 dev/test Debug 页面,不是生产普通业务页面接口;访问口令不能进入前端代码或构建产物。
- `POST /api/integrations/superagent/task-results` 是 SuperAgent 到后端的服务到服务入站接口。
- `POST /api/integrations/superagent/task-results` 已支持 M002 V4 入站解析基线;这是第三方回调能力,不是前端页面接口,前端只通过任务列表 / 任务详情观察后端派生后的结果。
- `POST /api/ai-query/v1/case-context``POST /api/ai-query/v1/object-detail` 是 SuperAgent 查询上下文接口,不是前端页面接口。
- `GET /api/source-message-conversations/{externalConversationId}` 是历史讨论过的候选路径,当前后端不提供,前端不要接入。
- AgentBus probe、fixture、replay、system 类接口不应放到普通业务前端页面。
@@ -452,6 +453,9 @@ RESERVATION_ROOMING_LIST_GENERATE
## 7. 需要持续提醒的后置事项
- 普通任务切换订单接口继续后置。
- M002 V4 入站解析与数据模型基线已完成第一版:后端可接收 `source_message + order_contexts[] + message_events[]`,识别 `NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``TRACE_RESERVATION_NOTES``ROOMING_LIST``PAYMENT`,并保存 V4 原始 payload、`route_code`、系统处理分类和 `field_contract_version=20260718-v4`。前端暂不需要直接调用 V4 回调接口。
- V4 可映射 event 现阶段仍复用现有任务详情结构;任务详情中若出现 `field_contract_version=20260718-v4` 或 AI payload 内的 `v4_source_message``v4_order_context``v4_message_event`,前端第一版只读展示即可,不要据此假定完整 V4 多卡页面已经完成。
- V4 `PAYMENT.attachment_ids[]` 不匹配、`UPDATE_BOOKING` 携带 `rate_code` 等问题会出现在任务详情同批次的 `adapter_contract_errors[]` 只读诊断块中,不展示保存、确认、执行或重试按钮。
- M002 V3 的结构化 `S10/S99` 入站、40 条 P0.1 路由枚举 / 稳定配置、`UNHANDLED_CURRENT_INTENT``adapter_contract_error` transition 最小落库、任务列表 / 订单时间线 / 任务详情 V3 路由字段和只读诊断块透出、type-known manual review 同卡解阻第一版、typed infrastructure error、P0 fixtures 回归基线和 Parent Group / Cancel Allotment 路由修订均已完成。
- 系统管理后台 V1 已完成后续若要做用户搜索更多筛选、批量操作、密码策略增强、MFA、登录设备管理应单独开需求。
- 现有 Reservation / SourceMessage 业务接口的强制登录、强制权限和业务审计 actor 全量迁移仍后置。

View File

@@ -4,9 +4,9 @@
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 0.7 |
| 日期 | 2026-07-11 |
| 状态 | 当前代码契约已支持 V2 `ai_task_results[]` 兼容、结构化 S10/S99、V3 业务根基础解析、旧 S000/S999 兼容和单酒店 hotel_id 后端解析 |
| 文档版本 | 0.8 |
| 日期 | 2026-07-18 |
| 状态 | 当前代码契约已支持 V4 入站解析基线、V2 `ai_task_results[]` 兼容、结构化 S10/S99、V3 业务根基础解析、旧 S000/S999 兼容和单酒店 hotel_id 后端解析 |
| 适用范围 | SuperAgent 调用本系统查询上下文、查询邮件会话、提交 AI 任务结果 |
| 主要读者 | SuperAgent 对接方、后端、测试、运维 |
@@ -88,7 +88,7 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
6. 使用共享 secret 重新计算 HMAC。
7. 常量时间比较签名。
8. 校验并记录 `client_id + nonce`,防止重放。
9. 鉴权和协议校验通过后再解析业务 JSON、结构化 S10/S99、V3 业务根或 S000/S999 文本结果。
9. 鉴权和协议校验通过后再解析业务 JSON、V4 包、结构化 S10/S99、V3 业务根或 S000/S999 文本结果。
## 3. SourceMessage ID 口径
@@ -455,9 +455,124 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID也不需要为
| URL | `{TH_HOTEL_API_BASE_URL}/api/integrations/superagent/task-results` |
| request_path | `/api/integrations/superagent/task-results` |
| Content-Type | `application/json``text/plain` |
| 业务动作 | 接收 AI 任务结果V3 JSON 支持结构化 S10/S99 和业务根V2 JSON 继续兼容,旧 S000/S999 文本创建只读特殊任务 |
| 业务动作 | 接收 AI 任务结果V4 JSON 支持 S10/S99 和业务根入站基线V3 / V2 JSON 继续兼容,旧 S000/S999 文本创建只读特殊任务 |
### 8.2 V3 S10/S99 结构化请求体
### 8.2 V4 JSON 请求体(当前推荐)
V4 普通业务包示例:
```json
{
"route_code": null,
"source_message": {
"source_message_id": "mail-20260718-0001",
"conversation_id": "thread-001",
"subject": "Group booking and payment",
"sender": "agent@example.test",
"sent_at": "2026-07-18T02:10:00Z",
"body": "Please create group GRP-001 and note payment attached.",
"body_content_type": "text/plain",
"attachments": [
{
"id": "att-pay-1",
"name": "payment-slip.jpg",
"content_type": "image/jpeg",
"url": "https://oss.example.test/payment-slip.jpg",
"size": 251524
}
]
},
"order_contexts": [
{
"order_ref": "order-1",
"basic_information": {
"account_code": "QBD_TRAVEL",
"manual_review": null
}
}
],
"message_events": [
{
"order_ref": "order-1",
"event_type": "NEW_BOOKING",
"target_order": {
"booking_type": "GROUP",
"locator_type": "GROUP_CODE",
"locator_value": "GRP-001"
},
"arrival_date": "2026-07-26",
"departure_date": "2026-07-29",
"rate_code": "BAR",
"booking_scenario": "STANDARD",
"room_items": [
{
"room_type_code": "TWN",
"room_count": 2
}
],
"manual_review": null
},
{
"order_ref": "order-1",
"event_type": "PAYMENT",
"target_order": {
"booking_type": "GROUP",
"locator_type": "GROUP_CODE",
"locator_value": "GRP-001"
},
"attachment_ids": ["att-pay-1"],
"manual_review": null
}
]
}
```
V4 纯通知包示例:
```json
{
"route_code": "S10",
"source_message": {
"source_message_id": "mail-20260718-0002",
"conversation_id": "thread-002",
"subject": "Thanks",
"sender": "guest@example.test",
"sent_at": "2026-07-18T02:10:00Z",
"body": "Noted with thanks.",
"body_content_type": "text/plain",
"attachments": []
},
"order_contexts": [],
"message_events": []
}
```
V4 字段说明:
| 字段 | 是否必填 | 中文说明 |
| --- | --- | --- |
| `route_code` | 是 | 普通业务固定为 `null`;入口通知第一版支持 `S10/S99`,当前新业务语义以 `S10` 为准,`S99` 仅作为兼容入口保留。 |
| `source_message.source_message_id` | 是 | 外部来源消息 ID对应 SourceMessage Inbox 的 `external_message_id`。 |
| `source_message.body_content_type` | 是 | 只能是 `text/plain``text/html`。 |
| `source_message.attachments[]` | 是 | 包级附件数组;每个附件必须有 `id/name/content_type/url``size` 可省略或为 `null`。 |
| `order_contexts[]` | 普通业务必填 | 每个 `order_ref` 一项,第一版必须带 `basic_information.account_code``basic_information.manual_review`。 |
| `message_events[]` | 普通业务必填 | 逐 event 入站,后端按数组顺序处理。 |
| `message_events[].event_type` | 是 | 第一版支持 `NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``TRACE_RESERVATION_NOTES``ROOMING_LIST``PAYMENT`。 |
| `message_events[].target_order` | 是 | `GROUP + GROUP_CODE`,或 `FIT + BOOKING_CODE / CONFIRMATION_NUMBER`。 |
| `message_events[].manual_review` | 是 | 只能是 `null` 或布尔 `true``true` 必须能由当前对象中的未解决字段解释。 |
| `PAYMENT.attachment_ids[]` | PAYMENT 必填 | 必须引用同包 `source_message.attachments[].id`。 |
当前已支持的 V4 行为:
- 命中 SourceMessage 后保存 AI batch / transition并按 `message_events[]` 顺序处理。
- 可映射 event 先复用现有订单 / 任务 / 任务卡链路,`ai_payload_json` 会保留 `v4_source_message``v4_order_context``v4_message_event`
- `route_code=S10/S99` 创建只读 `SOURCE_MESSAGE_ONLY` 任务,任务列表可见,订单列表不可见。
- `PAYMENT.attachment_ids[]` 引用不存在的附件、`UPDATE_BOOKING` 携带 `rate_code`、以及其他 V4 event 契约错误,只写 `adapter_contract_error` transition不创建用户可处理业务任务。
- 技术契约错误不会自动转为 S10/S99也不会创建前端可处理业务任务。
当前 V4 入站仍未完成完整多卡模型Basic Information 独立卡、V4 页面模型、真实 OPERA / OHIP、普通任务切换订单均后置。
### 8.3 V3 S10/S99 结构化请求体
S10 示例:
@@ -493,7 +608,7 @@ S10 示例:
S99 与 S10 使用相同结构,但 `route_code=S99``agent_assessment.status=material_package_unavailable`,且 `manual_review` 必须是完整入口复核对象。
### 8.3 V3 业务根请求体
### 8.4 V3 业务根请求体
```json
{
@@ -589,7 +704,7 @@ V3 字段说明:
}
```
### 8.4 V2 JSON 兼容请求体
### 8.5 V2 JSON 兼容请求体
```json
{
@@ -645,7 +760,7 @@ V3 字段说明:
`informational_message` 结构化任务仅用于历史兼容。新数据如果是纯信息类邮件或无法形成业务素材包,应优先使用 V3 结构化 `S10/S99`;旧联调或兼容场景仍可使用下面的 `S000/S999` 文本请求体。
### 8.5 S000/S999 文本请求体
### 8.6 S000/S999 文本请求体
纯信息类邮件:
@@ -669,7 +784,7 @@ S999,mail-20260708-0001
S000/S999 不在 body 里传 `hotel_id`,后端使用平台酒店表唯一 `ACTIVE` 酒店和外部消息 ID 查询 SourceMessage Inbox。命中后创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务:任务列表可见,订单列表不可见,不允许编辑、确认、转换订单、执行 OPERA 或重试 OPERA也不参与同订单任务执行顺序阻塞。该文本格式仅为兼容路径新数据优先使用结构化 `S10/S99`
### 8.6 成功响应
### 8.7 成功响应
```json
{

View File

@@ -432,10 +432,14 @@ V3 P0.1 不做以下事项:
## 14. 当前代码现状提醒
截至 M002 V3 CP9 后端第一版落地后,当前后端已经实现:
截至 M002 V4 入站解析基线落地后,当前后端已经实现:
- `S000/S999` 文本结果兼容处理。
- 结构化 `S10/S99` 入站处理,复用 `SOURCE_MESSAGE_ONLY` 只读特殊任务。
- V4 包级 `route_code=S10/S99` 入站处理,复用 `SOURCE_MESSAGE_ONLY` 只读特殊任务;普通 V4 业务包要求 `route_code=null`
- V4 业务根 `source_message + order_contexts[] + message_events[]` 基础解析;`source_message.source_message_id` 按 SourceMessage Inbox 的 `external_message_id` 反查邮件。
- V4 第一版识别 `NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``TRACE_RESERVATION_NOTES``ROOMING_LIST``PAYMENT`,可映射 event 先复用现有订单 / 任务 / 任务卡链路,并保存 `catalog_code=M002V4``skill_id=booking-desk-event-v4``field_contract_version=20260718-v4` 和 V4 原始三元组 / 原始 event payload。
- V4 `PAYMENT.attachment_ids[]` 必须匹配 `source_message.attachments[].id`V4 `UPDATE_BOOKING` 不接受 `rate_code``after.rate_code`;这类契约错误只落 `adapter_contract_error` transition不创建用户可处理业务任务。
- 40 条 P0.1 路由枚举 / 稳定配置。
- V3 业务根 `source_message + message_events[]` 基础解析;能派生到稳定路由的 event 创建业务任务,无法派生的 event、显式 `contract_errors`、根 `missing_fields`、不完整 `manual_review`、当前 producer 旧 Parent Cancel Booking 和不完整 parent split 候选只落 `adapter_contract_error` transition。
- P0.1 Parent split 已支持单边 Parent key 归一Parent key 候选冲突且符合 `target_object_unclear + parent_identity_candidates[]` 时进入同卡 type-known manual review不再误判为 adapter contract error。
@@ -464,4 +468,6 @@ V3 P0.1 不做以下事项:
仍需后续 checkpoint 实现:
- V4 订单任务 + 多卡领域模型重建,尤其是 Basic Information 订单级独立卡、邮件展示卡和各业务卡独立确认 / 锁定。
- V4 前端页面模型、任务详情字段矩阵和目录校验完全切换。
- 真实 OPERA / OHIP、普通任务任意切换订单、字段矩阵从当前扁平结构整体迁移到 0711 P0 新结构、历史旧 Parent Cancel Booking payload 批量迁移。

View File

@@ -4,9 +4,9 @@
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 1.0 |
| 文档版本 | 1.1 |
| 日期 | 2026-07-18 |
| 状态 | 当前 V4 字段基线;后续需同步 SuperAgent、Adapter、MCP Schema 和信息系统 DTO |
| 状态 | 当前 V4 字段基线;后端已完成 CP1 入站解析与数据模型基线,完整 V4 多卡模型仍需后续 checkpoint |
| 适用范围 | 0718 业务基线下Agent → Adapter / MCP → 信息系统的业务回调字段 |
| 不适用范围 | 数据库表设计、前端视觉细节、真实 PMS API、技术失败后台重试、旧 M002 V3 数据兼容 |
@@ -14,7 +14,7 @@
本文把 2026-07-18 导入的业务基线、Agent 回调问题答复、草案审查答复和剩余 10 项确认回复,整理为 M002 V4 的 Agent 回调字段契约。
本契约用于后续 M002 V4 主流程设计、后端领域建模、前端页面模型、Adapter / MCP Schema 对齐和 SuperAgent 联调。当前代码尚未按本文完成改造
本契约用于后续 M002 V4 主流程设计、后端领域建模、前端页面模型、Adapter / MCP Schema 对齐和 SuperAgent 联调。当前后端已按本文完成 V4 入站解析基线:能识别 V4 包、校验关键契约、保存 AI transition / 任务卡原始 payload并把可映射的六类 event 先接入现有订单任务链路
当前已确认开发阶段数据可以清空,因此 M002 V4 后续可以按新模型重建,不要求兼容旧任务数据、旧草稿、旧 OPERA 模拟、旧 `S000/S999`、旧 Fallback 或旧 `case_keys`
@@ -681,3 +681,24 @@ AI 回调包
- 当前无 PMS API不生成 OPERA 模拟操作和 PMS 成功语义。
- 技术异常不创建用户可见任务。
- 开发阶段不兼容老数据,允许清空旧任务相关数据后迁移。
## 25. 后端 CP1 已落地范围
2026-07-18 后端已完成 M002 V4 入站解析与数据模型基线,当前代码支持:
- `POST /api/integrations/superagent/task-results` 接收 V4 JSON 包:`route_code``source_message``order_contexts[]``message_events[]`
- `source_message.source_message_id` 按 SourceMessage Inbox 的 `external_message_id` 定位当前邮件SuperAgent 不传内部数据库 ID。
- `route_code=S10/S99` 复用现有 `SOURCE_MESSAGE_ONLY` 只读特殊任务机制;任务列表可见,订单列表不可见,不可编辑和执行。
- 普通业务包要求 `route_code=null`,并按 `message_events[]` 数组顺序处理。
- 第一版识别六类 `event_type``NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``TRACE_RESERVATION_NOTES``ROOMING_LIST``PAYMENT`
- 能映射到现有稳定任务卡的 event 会创建业务任务,并在 `ai_payload_json` 中保存 `v4_source_message``v4_order_context``v4_message_event``route_code`、系统处理分类和 `field_contract_version=20260718-v4`
- `PAYMENT.attachment_ids[]` 必须能匹配 `source_message.attachments[].id`;不匹配时只写 `adapter_contract_error` transition不创建用户可处理业务任务。
- `UPDATE_BOOKING` 中出现 `rate_code``after.rate_code` 时按 `UPDATE_RATE_CODE_NOT_ALLOWED` 写入 `adapter_contract_error` transition。
- `manual_review` 只接受 `null` 或布尔 `true``true` 必须能由当前对象中可识别的未解决字段解释。
当前 CP1 仍未完成:
- 尚未重建 V4 订单任务 + 多卡领域模型Basic Information 仍只是保存在 V4 原始 payload / order context 中,未作为独立可确认任务卡落地。
- 尚未取消 V3 草稿 / OPERA 模拟骨架;现有可映射 event 仍复用 M002 V3 任务状态和任务卡创建链路。
- 尚未接入真实 PMS / OPERA / OHIP。
- 尚未改造前端 V4 页面模型;前端第一版只能通过现有任务详情字段和原始 payload 观察 V4 入站结果。

View File

@@ -96,7 +96,7 @@
| `POST /api/ai-query/v1/object-detail` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC返回最小必要上下文 | 记录请求 ID、client_id 和安全错误 |
| `POST /api/ai-query/v1/conversation-tasks` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC不返回邮件原文 | 记录请求 ID、client_id 和安全错误 |
| `POST /api/ai-query/v1/conversation-source` | `THIRD_PARTY_SUPERAGENT` | HMAC 鉴权 | 保持 HMAC只按契约返回需要字段 | 记录请求 ID、client_id 和安全错误 |
| `POST /api/integrations/superagent/task-results` | `THIRD_PARTY_SUPERAGENT` | HMAC + nonce + timestamp + body hash | 保持;外部 `source_message_id` 必须匹配 Inbox | 记录 batch、transition、错误和幂等结果 |
| `POST /api/integrations/superagent/task-results` | `THIRD_PARTY_SUPERAGENT` | HMAC + nonce + timestamp + body hash | 保持;V4 / V3 / V2 共存期均必须用外部 `source_message_id` 匹配 Inbox,技术契约错误只落 adapter error不创建用户可处理任务 | 记录 batch、transition、adapter error、幂等结果和安全错误 |
| `/mcp` | `THIRD_PARTY_MCP` | Bearer Token提交工具可独立开关 | 保持;工具级能力限制,不暴露无关接口 | 记录工具调用结果和业务入站结果 |
| AgentBus WebSocket | `THIRD_PARTY_AGENTBUS` | AgentBus Token + capture 开关 | 保持;只入 SourceMessage不直接建业务任务 | 记录 SourceMessage、payload hash 和 dispatch run |