实现SuperAgent特殊入口结果处理

This commit is contained in:
andy
2026-07-10 12:05:57 +08:00
parent 9de4f0e7b6
commit 74e429a2cb
29 changed files with 1121 additions and 97 deletions

View File

@@ -2,7 +2,7 @@
## 1. 文档定位
本文记录后端侧提醒前端开发时必须注意的项目规范、业务规则、接口边界和安全要求。当前内容服务于 Reservation 任务详情、订单详情、任务列表、Message Notification 等第一版页面。
本文记录后端侧提醒前端开发时必须注意的项目规范、业务规则、接口边界和安全要求。当前内容服务于 Reservation 任务详情、订单详情、任务列表、S000/S999 特殊只读任务、历史 Message Notification 等第一版页面。
## 2. 项目开发注意事项
@@ -28,7 +28,10 @@
- 用户可以修改任务字段内容;最终确认后,后端使用 `confirmed_payload_json` 作为 OPERA 模拟输入来源。
- 同一订单下,前置任务未结束时,后续任务只能查看,不能编辑、确认或执行 OPERA 模拟操作。
- 任务状态 `FAILED` 第一版视为结束状态,不阻塞后续任务;但失败的 OPERA 操作不能跳过,必须展示失败原因并允许重试。
- Message Notification 挂临时订单,只读展示,不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞
- SuperAgent 新入口结果只会生成 `normal_task``manual_review` 或纯文本 `S000/S999``informational_message` 仅历史兼容,新页面不要再按新数据入口依赖它
- `S000` 表示纯信息类邮件,`S999` 表示无法形成业务素材包。后端会创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务,任务列表可见,订单列表不可见。
- `SOURCE_MESSAGE_ONLY` 任务不允许编辑、确认、人工转换订单、执行 OPERA 或重试 OPERA不参与订单任务执行队列不阻塞其他任务也不被其他任务阻塞。
- 历史 Message Notification 挂临时订单,只读展示,不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
- Fallback / manual_review 转为 New / Update / Cancel 时需要展示审计轨迹;登录权限底座已提供,具体业务审计 actor 迁移仍后置。
- 普通任务切换订单接口已确认后置,前端第一版不要把普通任务拖拽或切换订单做成可提交能力。
@@ -39,10 +42,10 @@
| `POST /api/auth/login` | 用户名密码登录 | 成功后返回 `access_token`、当前用户、可访问酒店、权限码和可见菜单token 只放 `sessionStorage`,不要放 `localStorage`、URL、日志或错误上报。 |
| `GET /api/auth/me` | 恢复当前登录态 | 前端启动后带 `Authorization: Bearer <access_token>` 调用401 时清理 token 并进入登录页。 |
| `POST /api/auth/logout` | 登出当前 session | 带 `Authorization: Bearer <access_token>`;成功后前端必须清理本地 token 和当前用户上下文。 |
| `GET /api/reservation/orders` | 查询订单列表 | 默认返回全部订单状态;`open_task_count` 排除 `COMPLETED``FAILED``next_processable_task_id` 引导用户继续处理。 |
| `GET /api/reservation/tasks` | 查询任务列表 / 工作台 | 用 `can_process``readonly_reason_code` 控制入口按钮;列表不返回 AI 原始 payload、邮件正文或附件 URL已返回来源邮件会话摘要字段并支持 `order_status` 按任务所属订单状态筛选。 |
| `GET /api/reservation/orders/{orderId}` | 查询订单详情与任务时间线 | `include_tasks=false` 可只取订单摘要;时间线按后端队列顺序返回,前端不要自行按创建时间重排;`tasks[]` 已返回来源邮件会话摘要字段。 |
| `GET /api/reservation/tasks/{taskId}` | 查询任务详情 | 以返回的可处理状态和只读原因控制按钮,不只看任务状态;`fields[]` 已包含 P0 字段元数据。 |
| `GET /api/reservation/orders` | 查询订单列表 | 默认返回全部订单状态;`open_task_count` 排除 `COMPLETED``FAILED`隐藏技术订单不返回,因此 S000/S999 不会在订单列表形成订单。 |
| `GET /api/reservation/tasks` | 查询任务列表 / 工作台 | 用 `can_process``readonly_reason_code` 控制入口按钮;列表不返回 AI 原始 payload、邮件正文或附件 URL已返回来源邮件会话摘要字段并支持 `order_status` 按任务所属订单状态筛选S000/S999 会以 `task_type=SOURCE_MESSAGE_ONLY` 返回。 |
| `GET /api/reservation/orders/{orderId}` | 查询订单详情与任务时间线 | `include_tasks=false` 可只取订单摘要;时间线按后端队列顺序返回,前端不要自行按创建时间重排;`tasks[]` 已返回来源邮件会话摘要字段;隐藏技术订单详情不可作为普通订单页打开。 |
| `GET /api/reservation/tasks/{taskId}` | 查询任务详情 | 以返回的可处理状态和只读原因控制按钮,不只看任务状态;`fields[]` 已包含 P0 字段元数据`SOURCE_MESSAGE_ONLY` 详情字段列表和 OPERA 操作列表为空,并通过 `source_message_only_result` 返回 S000/S999 入口结果。 |
| `PUT /api/reservation/tasks/{taskId}/draft` | 保存任务草稿 | 只保存草稿,不代表用户最终确认。 |
| `POST /api/reservation/tasks/{taskId}/confirm` | 最终确认任务 | 后端会做第一版字段校验,通过后进入 `READY`。 |
| `POST /api/reservation/tasks/{taskId}/manual-review-conversions` | Fallback 人工转换 | 只用于 manual_review / fallback不用于普通任务切换订单。 |
@@ -66,7 +69,7 @@
| `GET /api/reservation/orders/{orderId}` | 补齐 `tasks[]` 每条任务的来源邮件会话摘要字段。 | `include_tasks=false` 可只取订单摘要;时间线顺序由后端按订单队列返回,前端不要自行按创建时间重排。`include_source_summary` 第一版不作为前端裁剪字段的强约束,前端暂不要依赖它减少返回字段。 |
| `GET /api/reservation/tasks/{taskId}` | 补齐顶层来源邮件字段,并扩展 `fields[]` 元数据。 | 顶层来源字段用于打开邮件会话;`fields[]` 中的 `result_type``task_type``task_subtype``default_value_source` 用于前端字段分组、调试和白名单对齐。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 新增邮件会话详情接口,并补齐 `html_body_sanitized` / `html_render_mode`。 | 当前唯一推荐路径是这个接口;前端渲染邮件 HTML 时优先使用 `html_body_sanitized`;不要调用历史讨论过的 `/api/source-message-conversations/{externalConversationId}`。 |
| `POST /api/system/debug/eml-superagent-runs` | 新增 Debug EML 上传到 SuperAgent 调试接口,并补齐独立 Debug 外部消息 ID、原始 Message-ID 保留安全 HTML 字段。 | 只用于调试页面;请求为 multipart/form-data必须传 `X-TH-Hotel-Debug-Upload-Key`,但该 key 不能写进前端源码、构建产物、URL、localStorage 或错误上报。 |
| `POST /api/system/debug/eml-superagent-runs` | 新增 Debug EML 上传到 SuperAgent 调试接口,并补齐独立 Debug 外部消息 ID、原始 Message-ID 保留安全 HTML 字段和 S000/S999 识别。 | 只用于调试页面;请求为 multipart/form-data必须传 `X-TH-Hotel-Debug-Upload-Key`,但该 key 不能写进前端源码、构建产物、URL、localStorage 或错误上报SuperAgent 返回 S000/S999 时不是 JSON 解析失败。 |
### 5.2 登录权限接入注意
@@ -123,6 +126,9 @@ POST /api/auth/logout
- `next_processable_task_id` 是后端按同订单队列实时计算出的下一条可处理任务;前端可以用它做“继续处理”入口。
- `display_order_key` 是前端优先展示的订单业务号或临时订单号;`group_code``confirmation_number` 只有在当前订单业务号类型匹配时返回。
- 订单 ID、任务 ID、SourceMessage ID 在这些前端接口中按字符串返回,前端不要转换成 JavaScript number。
- `SOURCE_MESSAGE_ONLY` 任务背后有隐藏技术订单用于满足后端任务外键,但订单列表不会返回该订单;任务列表中该类任务的 `display_order_key``temporary_order_no``group_code``confirmation_number` 可能为空,前端不要因此隐藏整条任务。
- 任务列表里 `task_type=SOURCE_MESSAGE_ONLY``task_subtype=S000/S999` 的记录只展示邮件来源和 SuperAgent 入口结果,不展示处理按钮。
- 任务详情里 `source_message_only_result` 仅对 `SOURCE_MESSAGE_ONLY` 返回,包含 `entry_result_code``entry_result_meaning``entry_result_description``entry_result_source_message_id``raw_answer`;普通任务该字段为空。
### 5.6 前端联调演示数据 seed 接口
@@ -159,7 +165,7 @@ Content-Type: application/json
- 已完成 New Booking 任务和两条 OPERA 模拟成功记录。
- OPERA 模拟失败任务,可在任务详情看到失败 attempt 和重试入口。
- Fallback / manual_review 任务。
- Message Notification 只读任务。
- 历史 Message Notification 只读任务S000/S999 特殊只读任务可通过 SuperAgent 回调或后续专用夹具补充
- 同一邮件会话下多封邮件、完整 HTML、附件外链和内联图片外链。
### 5.7 任务详情字段元数据接入注意

View File

@@ -35,7 +35,7 @@ Debug EML 页面第一版只做一件事:
| 执行状态区 | loading、成功、失败、耗时、本次 `debug_run_id` | 提交后禁用按钮,避免重复点击;失败时展示安全错误摘要。 |
| SourceMessage 追溯区 | `source_message_id``source_provider``external_message_id``external_conversation_id` | 用于确认已写入 SourceMessage Inbox。 |
| 邮件内容预览区 | `html_body_sanitized`、纯文本、附件列表、内联图片列表 | HTML 展示必须优先使用 `html_body_sanitized`。 |
| SuperAgent 结果区 | `superagent_parsed_json``superagent_raw_answer``warnings[]` | JSON 可以格式化展示raw answer 用于排查 SuperAgent 非 JSON 输出。 |
| SuperAgent 结果区 | `superagent_parsed_json``superagent_raw_answer``warnings[]` | JSON 可以格式化展示;S000/S999 会被后端识别成结构化入口结果;raw answer 用于排查其他非 JSON 输出。 |
| 调试 Payload 区 | `agentbus_like_payload` | 只用于调试展示,不让用户编辑后重新提交。 |
## 4. 接口
@@ -120,7 +120,7 @@ export async function uploadDebugEml(input: {
| `superagent_session_id` | string | SuperAgent session ID。 |
| `superagent_run_id` | string | SuperAgent run ID。 |
| `superagent_raw_answer` | string | SuperAgent 最终原始文本回答。 |
| `superagent_parsed_json` | object/null | 后端尝试解析出的 JSON解析失败时可能为空。 |
| `superagent_parsed_json` | object/null | 后端尝试解析出的 JSONS000/S999 会返回识别后的对象,其他解析失败时可能为空。 |
| `warnings[]` | string[] | 安全或解析警告,可在页面顶部或结果区展示。 |
| `status` | string | Debug run 状态。 |
@@ -143,6 +143,18 @@ export async function uploadDebugEml(input: {
- `agentbus_like_payload.source.original_message_id` 是原始邮件 `Message-ID`
- `external_message_id` 是 Debug 链路生成的独立 ID不等同于原始 `Message-ID`
- `superagent_parsed_json` 有值时优先展示格式化 JSON没有值时展示 `superagent_raw_answer`
- 如果 SuperAgent 返回 `S000,source_message_id``S999,source_message_id`,后端会把它识别为特殊入口结果,不会作为 JSON 解析失败处理。前端可在结果区展示 `entry_result_code``entry_result_source_message_id``entry_result_meaning``entry_result_description`
S000/S999 解析示例:
```json
{
"entry_result_code": "S000",
"entry_result_source_message_id": "mail-20260708-0001",
"entry_result_meaning": "PURE_INFORMATION",
"entry_result_description": "纯信息类邮件"
}
```
## 6. 错误响应

View File

@@ -16,7 +16,7 @@
| P0 | 邮件会话详情接口 `GET /api/source-messages/{sourceMessageId}/conversation` | 邮件会话详情页 | 已完成第一版 |
| 联调 | 演示数据 seed 接口 `POST /api/system/reservation/demo-data` | 本地 / test 前端页面看效果 | 已完成;仅 dev/test 受控使用 |
| 联调 | Debug EML 上传接口 `POST /api/system/debug/eml-superagent-runs` | Debug 页面上传 `.eml` 看 SuperAgent 结果 | 已完成第一版;仅 dev/test 受控使用 |
| P1 | Message Notification 列表 / 详情接口 | 信息提醒页或订单详情只读卡片 | 完成独立接口;可先通过任务列表 / 任务详情展示 `INFORMATIONAL_MESSAGE` |
| P1 | S000/S999 特殊只读任务展示 | 任务列表、任务详情来源邮件查看 | 完成后端第一版;通过任务列表 / 任务详情展示 `SOURCE_MESSAGE_ONLY`,不做独立 Message Notification 接口 |
| P1 | 任务卡前端字段白名单元数据接口 | 字段白名单调试、版本对齐 | 未完成;若任务详情已透出完整元数据,可后置 |
| 后置 | 普通任务切换订单接口 | 任务详情订单归属调整 | 未完成;已确认后置 |
@@ -43,7 +43,7 @@
| `POST /api/system/reservation/demo-data` | 已完成 | 仅本地 / test 联调可用 | 默认关闭,必须后端配置访问口令;不能作为生产页面接口。 |
| `POST /api/system/debug/eml-superagent-runs` | 已完成第一版 | 仅 dev/test Debug 页面可用 | 默认关闭,必须后端配置访问口令、阿里云 OSS 和 SuperAgent Open API第一版只展示 SuperAgent 结果,不创建订单和任务。 |
| `GET /api/source-message-conversations/{externalConversationId}` | 未发现后端实现 | 不可以 | 历史讨论过的候选路径,当前不提供;前端统一使用 `GET /api/source-messages/{sourceMessageId}/conversation`。 |
| `GET /api/reservation/message-notifications` | 未发现后端实现 | 不可以 | 如需独立信息提醒页再新增;第一版可先用任务接口过滤。 |
| `GET /api/reservation/message-notifications` | 未发现后端实现 | 不可以 | 第一版不做独立接口;新入口 S000/S999 已通过 `SOURCE_MESSAGE_ONLY` 任务展示。 |
| `GET /api/reservation/task-card-field-whitelist` | 未发现后端实现 | 不可以 | 若任务详情 `fields[]` 已补齐 3.0 元数据,可后置。 |
## 3. 任务列表 / 工作台接口字段补齐
@@ -86,7 +86,7 @@ GET /api/reservation/tasks
| --- | --- | --- |
| `hotel_id` | 否 | 酒店 ID。第一版如果只有单酒店可为空。 |
| `order_id` | 否 | 按订单过滤。 |
| `task_type` | 否 | `NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``MANUAL_REVIEW``INFORMATIONAL_MESSAGE`。 |
| `task_type` | 否 | `NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``MANUAL_REVIEW``INFORMATIONAL_MESSAGE``SOURCE_MESSAGE_ONLY`。其中 `INFORMATIONAL_MESSAGE` 仅历史兼容,新入口 S000/S999 使用 `SOURCE_MESSAGE_ONLY`。 |
| `task_status` | 否 | 任务状态过滤。 |
| `task_subtype` | 否 | 任务卡 subtype 过滤。 |
| `order_status` | 否 | 按任务所属订单状态过滤,支持 `TEMPORARY``ACTIVE``ENDED``LOGIC_DELETED`;不传时保持当前行为。 |
@@ -300,7 +300,7 @@ POST /api/system/reservation/demo-data
| `tasks[]` | 生成的任务 ID、任务类型、任务 subtype 和任务状态。 |
| `entrypoints` | 可直接访问的任务列表、订单列表、订单详情、任务详情、邮件会话详情 URL。 |
第一版 seed 覆盖:队列阻塞、已完成 OPERA 模拟、OPERA 失败可重试、Fallback 人工复核、Message Notification、邮件会话完整 HTML / 附件 / 内联图片。
第一版 seed 覆盖:队列阻塞、已完成 OPERA 模拟、OPERA 失败可重试、Fallback 人工复核、历史 Message Notification 只读任务、邮件会话完整 HTML / 附件 / 内联图片。S000/S999 特殊只读任务可通过 SuperAgent 回调或后续专用夹具补充。
前端注意:不要把访问口令写入前端仓库、浏览器环境变量或构建产物;该接口只能由本地联调人员手动调用或由受控测试脚本调用。
@@ -502,11 +502,23 @@ GET /api/reservation/tasks/{taskId}
- 如果后端已有更细的字段来源或适用场景元数据,可后续再扩展 `field_source``applicable_scenario`,不作为本轮 P0 阻塞项。
- 前端已统一配置 `VITE_RESERVATION_HOTEL_ID`,并会在 `GET /api/reservation/orders``GET /api/reservation/tasks``GET /api/reservation/orders/{orderId}` 自动传 `hotel_id`。当前 `GET /api/reservation/tasks/{taskId}` 以及任务写操作 Controller 不接收 `hotel_id`;第一版先按 ID 定位,后续多酒店隔离 / 权限方案统一补齐。
## 9. Message Notification 列表 / 详情接口
## 9. S000/S999 特殊只读任务与历史 Message Notification
当前状态:未发现后端独立 Message Notification 列表 / 详情接口。当前后端已经支持 `INFORMATIONAL_MESSAGE` 任务类型进入任务体系,第一版前端可以先通过 `GET /api/reservation/tasks?task_type=INFORMATIONAL_MESSAGE``GET /api/reservation/tasks/{taskId}` 展示信息提醒任务。仅当产品确认需要独立“信息提醒页”时,再新增本节接口
当前状态:后端不提供独立 Message Notification 列表 / 详情接口。SuperAgent 新入口返回 `S000,source_message_id``S999,source_message_id` 时,后端会创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务,第一版前端通过 `GET /api/reservation/tasks?task_type=SOURCE_MESSAGE_ONLY``GET /api/reservation/tasks/{taskId}` 展示。
建议路径:
历史 `INFORMATIONAL_MESSAGE` 仍可通过任务列表 / 任务详情兼容展示,但新数据不要依赖它。
展示规则:
- `task_type=SOURCE_MESSAGE_ONLY``task_subtype=S000`:纯信息类邮件。
- `task_type=SOURCE_MESSAGE_ONLY``task_subtype=S999`:无法形成业务素材包。
- 任务列表可见,订单列表不可见。
- 任务详情只允许查看来源邮件、会话、附件和 SuperAgent 原始返回。
- 任务详情通过 `source_message_only_result` 返回 `entry_result_code``entry_result_meaning``entry_result_description``entry_result_source_message_id``raw_answer`
- 不显示编辑、确认、人工转换、执行 OPERA 或重试 OPERA 按钮。
- 不参与订单任务执行顺序阻塞。
当前不建议新增路径:
```text
GET /api/reservation/message-notifications
@@ -529,13 +541,15 @@ GET /api/reservation/message-notifications/{taskId}
{
"task_id": "10009",
"order_id": "20009",
"task_type": "INFORMATIONAL_MESSAGE",
"task_type": "SOURCE_MESSAGE_ONLY",
"task_subtype": "S000",
"task_status": "COMPLETED",
"queue_participation": false,
"readonly": true,
"visible_reason": "FYI message without booking operation",
"visible_reason": "S000 pure information entry result",
"relevant_message_excerpt": "Noted with thanks.",
"informational_message": "该消息仅作信息提醒,不需要执行 OPERA 操作。",
"entry_result_code": "S000",
"entry_result_description": "纯信息类邮件",
"attachments": [],
"source_message_id": "30009",
"external_conversation_id": "thread-20260708-009",
@@ -615,5 +629,5 @@ POST /api/reservation/tasks/{taskId}/order-binding
- 订单列表、任务列表当前统一使用 `items + page` 分页结构;邮件会话详情不分页,返回同一会话全部邮件。
- 邮件会话详情接口已优先使用 `GET /api/source-messages/{sourceMessageId}/conversation`
- 任务详情 `fields[]` 已由后端直接透出 P0 需要的 3.0 元数据;独立字段白名单接口后置。
- Message Notification 是否独立成页面,还是只在订单详情展示。
- 独立 Message Notification 页面继续后置;新入口 S000/S999 第一版先在任务列表和任务详情展示。
- 邮件会话全文读取的审计策略由后端内部处理;前端不保存原文读取 key。