Files
th-hotel-simple/docs/project/frontend-backend/frontend-to-backend-api-requests.md

45 KiB
Raw Blame History

前端提醒后端待补接口

1. 文档定位

本文记录前端页面开发时希望后端新增、补齐或稳定的接口草案。本文中的路径、入参和返参是前端视角的最小诉求,不代表后端已经承诺实现;进入开发前需要后端按当前包结构、权限、安全和业务规则二次确认。

2. 当前待补接口总览

优先级 接口 页面 / 场景 状态
P0 订单列表接口 GET /api/reservation/orders 订单列表页、首页工作台 已完成第一版
P0 任务列表接口 GET /api/reservation/tasks 任务列表菜单、订单详情任务入口 已完成第一版,已补来源邮件会话字段和 order_status 筛选
P0 订单详情接口 GET /api/reservation/orders/{orderId} 订单详情页 已完成第一版,已补 tasks[] 每个任务的来源邮件会话字段
P0 任务详情读取接口 GET /api/reservation/tasks/{taskId} 任务详情页动态渲染 已完成第一版,已补来源邮件字段和 3.0 字段元数据
P0 任务详情操作接口 任务详情保存、确认、OPERA、审计 已完成;前端可直接接入
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 S10/S99 源邮件只读通知卡与旧 S000/S999 兼容 任务列表、任务详情来源邮件查看 已完成第一版:旧 S000/S999 兼容,新结构化 S10/S99 可入站并在任务列表 / 详情只读展示
P1 type-known manual review 同卡复核解阻 任务详情复核 已完成第一版原业务任务卡复核、字段修正、订单归属确认、READY 流转
P1 任务卡前端字段白名单元数据接口 字段白名单调试、版本对齐 未完成;若任务详情已透出完整元数据,可后置
后置 普通任务切换订单接口 任务详情订单归属调整 未完成;已确认后置

2.1 后端当前接口完成度核对

本节按 2026-07-08 当前后端 Controller 和 result record 核对,避免重复要求后端实现已经存在的接口。

接口 / 能力 当前后端状态 前端是否可直接接入 仍需后端处理
GET /api/reservation/tasks 已完成第一版,已补来源邮件会话字段和所属订单状态筛选 可以 order_status 按任务所属订单状态过滤;不传时保持当前全部任务列表行为。
GET /api/reservation/orders/{orderId} 已完成第一版,已补 tasks[] 来源邮件会话字段 可以 暂无。
GET /api/reservation/tasks/{taskId} 已完成第一版,已补任务顶层来源邮件字段和 fields[] 3.0 元数据 可以 当前 Controller 不接收 hotel_id;如后续多酒店隔离需要前端显式传酒店上下文,请后端补可选入参或确认按 taskId 全局唯一即可。
PUT /api/reservation/tasks/{taskId}/draft 已完成 可以 当前 Controller 不接收 hotel_id;如写操作需要酒店上下文幂等 / 权限校验,请后端补可选入参或请求体字段。
POST /api/reservation/tasks/{taskId}/confirm 已完成 可以 当前 Controller 不接收 hotel_id;如写操作需要酒店上下文幂等 / 权限校验,请后端补可选入参或请求体字段。
GET /api/reservation/tasks/{taskId}/audits 已完成 可以 当前 Controller 不接收 hotel_id;如审计查询需要酒店上下文隔离,请后端补可选入参。
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute 已完成第一版模拟操作 可以 暂无;真实 OPERA 写入另行确认。
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry 已完成第一版模拟重试 可以 暂无;真实 OPERA 重试另行确认。
POST /api/reservation/tasks/{taskId}/manual-review-conversions 已完成 可以 暂无。
POST /api/reservation/tasks/{taskId}/manual-review-resolutions 已完成第一版 可以 只用于 type-known manual review第一版 confirmed_order_id 必须等于当前任务订单,不开放普通任务任意切换订单。
GET /api/source-messages 已完成安全摘要列表 可以 不能替代邮件会话全文接口。
GET /api/source-messages/{id} 已完成单条安全摘要 可以 不能替代邮件会话全文接口。
GET /api/source-messages/{id}/original 已完成单封原文受控读取 谨慎接入 只能读单封邮件,不能返回同一 conversation 全量邮件。
GET /api/reservation/orders 已完成第一版 可以 默认查询全部订单状态;open_task_count 排除 COMPLETEDFAILED
GET /api/source-messages/{sourceMessageId}/conversation 已完成第一版,已补 html_body_sanitizedhtml_render_mode 可以 返回完整 text/html、后端清洗后的 HTML、媒体外链和关联订单 / 任务摘要;前端不传原文读取 key页面展示优先使用 html_body_sanitized
POST /api/system/reservation/demo-data 已完成 仅本地 / test 联调可用 默认关闭,必须后端配置访问口令;不能作为生产页面接口。
POST /api/system/debug/eml-superagent-runs 已完成第一版 仅 dev/test Debug 页面可用 默认关闭,必须后端配置访问口令、阿里云 OSS 和 SuperAgent Open API第一版只展示 SuperAgent 结果,不创建订单和任务;已能识别旧 S000/S999 和新结构化 S10/S99。
GET /api/source-message-conversations/{externalConversationId} 未发现后端实现 不可以 历史讨论过的候选路径,当前不提供;前端统一使用 GET /api/source-messages/{sourceMessageId}/conversation
GET /api/reservation/message-notifications 未发现后端实现 不可以 第一版不做独立接口;旧 S000/S999 已通过 SOURCE_MESSAGE_ONLY 任务展示0711 P0 新 S10/S99 也继续复用任务列表 / 任务详情只读展示。
GET /api/reservation/task-card-field-whitelist 未发现后端实现 不可以 若任务详情 fields[] 已补齐 3.0 元数据,可后置。

3. 任务列表 / 工作台接口字段补齐

建议路径:

GET /api/reservation/tasks

当前状态:后端已按 P0 最小诉求实现第一版,前端任务列表页可以直接接入该接口。接口已返回任务摘要、订单展示键、来源消息 ID / 主题、来源邮件会话摘要和实时可处理状态,不返回完整 AI payload、邮件正文或附件 URL。

本轮前端新增“任务列表”菜单,并且任务列表、订单详情任务队列都需要能跳转到该任务来源消息所在的完整邮件会话。因此建议在现有返回项上补齐来源邮件会话摘要字段。

默认排序:未传 order_id 时按来源消息接收时间倒序返回,保证任务列表最新消息 / 最新任务在前;传 order_id 时按同订单 queue_sequence 正序返回,保证订单队列处理顺序不被打乱。

已完成字段:

字段 说明
task_id 任务 ID。
order_id 关联订单 ID。
hotel_id 酒店上下文 ID。
display_order_key 前端优先展示的业务号或临时订单号。
temporary_order_no 临时订单号。
task_type 系统主任务类型。
result_type AI 结果类型,例如 normal_taskmanual_reviewsource_message_review_notification
ai_task_type SuperAgent 原始任务类型,例如 New BookingS10S99
task_subtype 任务 subtype。
route_code M002 V3 路由码,例如 R01_NEW_FIT_RESERVATION_NORMALS10S99
system_process_category 系统处理分类,例如 BUSINESS_TASKSOURCE_MESSAGE_NOTIFICATION
task_status 任务状态。
card_name 任务卡展示名称。
queue_sequence 同订单队列顺序。
queue_participation 是否参与订单执行队列。
can_process 当前是否可处理。
readonly_reason_code 只读原因代码。
source_message_id 来源 SourceMessage Inbox ID。
source_subject 来源消息主题摘要。
created_at 任务创建时间。
updated_at 任务更新时间。

建议入参:

参数 必填 说明
hotel_id 酒店 ID。单酒店阶段默认可为空由后端按当前用户上下文或平台酒店表唯一 ACTIVE 酒店解析;显式传值时后端会校验访问权限。
order_id 按订单过滤。
task_type 当前任务列表筛选只提供 NEW_BOOKINGUPDATE_BOOKINGCANCEL_BOOKINGMANUAL_REVIEWSOURCE_MESSAGE_ONLY;不再提供历史 INFORMATIONAL_MESSAGE 筛选项。0711 P0 结构化 S10/S99 复用 SOURCE_MESSAGE_ONLY 只读源邮件通知卡。
task_status 任务状态过滤。
task_subtype 任务卡 subtype 过滤。
order_status 按任务所属订单状态过滤,支持 TEMPORARYACTIVEENDEDLOGIC_DELETED;不传时保持当前行为。
queue_participation 是否参与订单执行队列。
keyword Group Code、Confirmation No、临时订单号、来源消息安全摘要关键词。
page_num 页码,建议从 1 开始。
page_size 每页条数。

建议返参:

{
  "items": [
    {
      "task_id": "10001",
      "order_id": "20001",
      "hotel_id": "HOTEL-TEST",
      "display_order_key": "GRP-001",
      "temporary_order_no": "TMP-20260708-001",
      "task_type": "UPDATE_BOOKING",
      "result_type": "normal_task",
      "ai_task_type": "Payment Evidence",
      "task_subtype": "payment_evidence",
      "route_code": "R10_PAYMENT_EVIDENCE_NORMAL",
      "system_process_category": "BUSINESS_TASK",
      "task_status": "PENDING_CONFIRM",
      "card_name": "Payment Evidence",
      "queue_sequence": 2,
      "queue_participation": true,
      "can_process": false,
      "readonly_reason_code": "PREVIOUS_TASK_NOT_FINISHED",
      "source_message_id": "30001",
      "source_subject": "Booking Update",
      "source_sender_summary": "guest@example.com",
      "source_received_at": "2026-07-08T02:58:00Z",
      "external_conversation_id": "thread-20260708-001",
      "conversation_message_count": 6,
      "created_at": "2026-07-08T03:00:00Z",
      "updated_at": "2026-07-08T03:10:00Z"
    }
  ],
  "page": {
    "page_num": 1,
    "page_size": 20,
    "total": 1
  }
}

本轮已新增字段:

字段 说明
source_sender_summary 来源消息发件人展示值,当前不打码,用于任务列表快速判断来源。
source_received_at 邮件来源接收时间,优先取 AgentBus payload received_at,用于任务列表排序和展示。
external_conversation_id 来源消息所属邮件会话 ID用于打开完整邮件会话详情。
conversation_message_count 会话内邮件数量,用于提示用户该入口是整段会话,不是单封邮件。
result_type / ai_task_type / route_code / system_process_category V3 路由展示字段,用于任务卡标签、筛选和 S10/S99 只读卡判断。

4. 订单详情与任务时间线接口字段补齐

建议路径:

GET /api/reservation/orders/{orderId}

当前状态:后端已按 P0 最小诉求实现第一版。接口返回订单摘要和同订单任务时间线;include_tasks=false 时只返回订单摘要。任务时间线已补齐每个任务的来源邮件会话摘要。

订单详情低保真已确认沿用“订单摘要 + 同订单任务队列 + 当前任务卡 + OPERA 模拟操作 + 审计时间线”。同订单任务队列里的每个任务都需要自己的“查看邮件会话”入口,因为不同任务可能来自不同邮件或不同邮件会话。因此建议补齐 tasks[] 中每个任务的来源邮件会话字段。

建议入参:

参数 必填 说明
orderId 订单 ID。
hotel_id 酒店 ID。单酒店阶段默认可为空由后端解析显式传值时后端会校验访问权限。
include_tasks 是否返回任务时间线,默认 true
include_source_summary 是否返回来源消息摘要,默认 true;第一版参数保留,前端暂不要依赖它做字段裁剪。

建议返参:

{
  "order": {
    "order_id": "20001",
    "hotel_id": "HOTEL-TEST",
    "order_status": "ACTIVE",
    "temporary_order_no": "TMP-20260708-001",
    "confirmation_number": "CNF123456",
    "group_code": "GRP-001",
    "block_code": null,
    "allotment_code": null,
    "display_name": "GRP-001",
    "created_at": "2026-07-08T03:00:00Z",
    "updated_at": "2026-07-08T03:10:00Z"
  },
  "tasks": [
    {
      "task_id": "10001",
      "task_type": "NEW_BOOKING",
      "result_type": "normal_task",
      "ai_task_type": "New Booking",
      "task_subtype": "NEW_BOOKING",
      "route_code": "R01_NEW_FIT_RESERVATION_NORMAL",
      "system_process_category": "BUSINESS_TASK",
      "task_status": "COMPLETED",
      "card_name": "New Booking",
      "queue_sequence": 1,
      "queue_participation": true,
      "can_process": false,
      "readonly_reason_code": "TASK_FINISHED",
      "source_message_id": "30001",
      "source_subject": "Booking Request",
      "source_sender_summary": "guest@example.com",
      "source_received_at": "2026-07-08T02:58:00Z",
      "external_conversation_id": "thread-20260708-001",
      "conversation_message_count": 6,
      "created_at": "2026-07-08T03:00:00Z"
    }
  ],
  "warnings": []
}

本轮已新增字段:

字段 说明
source_message_id 任务对应的来源 SourceMessage Inbox ID。
source_subject 来源消息主题摘要。
source_sender_summary 来源消息发件人展示值,当前不打码。
source_received_at 邮件来源接收时间,优先取 AgentBus payload received_at
external_conversation_id 来源消息所属邮件会话 ID。
conversation_message_count 会话内邮件数量。
result_type / ai_task_type / route_code / system_process_category V3 路由展示字段,和任务列表字段语义一致。

5. 订单列表接口

建议路径:

GET /api/reservation/orders

当前状态:后端已完成第一版。默认查询全部订单状态;open_task_count 排除 COMPLETEDFAILEDnext_processable_task_id 按同订单队列可处理状态实时计算。

默认排序:按后端维护的订单最近业务活动时间倒序返回,保证最近有业务活动的订单排在前面。后端当前使用 workflow_reservation_order.latest_activity_at 作为排序字段,并在订单创建、任务创建、草稿保存、最终确认、人工复核解阻、任务状态变更等写路径维护;前端不要再基于任务时间或更新时间自行重排。

建议入参:

参数 必填 说明
hotel_id 酒店 ID。单酒店阶段默认可为空由后端解析显式传值时后端会校验访问权限。
order_status TEMPORARYACTIVEENDEDLOGIC_DELETED
group_code 按 Group Code 精确或模糊查询,后端决定。
confirmation_number 按 Confirmation No 查询。
keyword 前端搜索框统一关键词;后端匹配订单字段,也会匹配来源消息安全摘要命中的 SourceMessage ID。
page_num 页码。
page_size 每页条数。

建议返参:

{
  "items": [
    {
      "order_id": "20001",
      "hotel_id": "HOTEL-TEST",
      "order_status": "ACTIVE",
      "display_order_key": "GRP-001",
      "temporary_order_no": null,
      "confirmation_number": "CNF123456",
      "group_code": "GRP-001",
      "display_name": "GRP-001",
      "open_task_count": 2,
      "next_processable_task_id": "10002",
      "updated_at": "2026-07-08T03:10:00Z"
    }
  ],
  "page": {
    "page_num": 1,
    "page_size": 20,
    "total": 1
  }
}

6. 前端联调演示数据 seed 接口

建议路径:

POST /api/system/reservation/demo-data

当前状态:后端已完成第一版。该接口只用于本地 / test 联调造数,默认关闭,不是生产业务页面接口。

启用条件:

配置 说明
reservation.demo-data.enabled=true dev 默认开启test 需显式启用,也可用环境变量 RESERVATION_TEST_DEMO_DATA_ENABLED=true
reservation.demo-data.access-key 配置访问口令dev 优先使用 RESERVATION_DEV_DEMO_DATA_ACCESS_KEYtest 优先使用 RESERVATION_TEST_DEMO_DATA_ACCESS_KEY,旧通用变量 RESERVATION_DEMO_DATA_ACCESS_KEY 仅作为兼容兜底。
X-TH-Hotel-Demo-Data-Key 请求头必须携带,与后端配置口令一致。

请求示例:

{
  "run_label": "frontend-smoke"
}

返回说明:

字段 说明
demo_run_id 本次 seed 唯一关键词,可用于任务列表 / 订单列表搜索。
source_messages[] 生成的来源消息 ID、外部消息 ID 和外部会话 ID。
orders[] 生成的订单 ID、订单状态和展示键。
tasks[] 生成的任务 ID、任务类型、任务 subtype 和任务状态。
entrypoints 可直接访问的任务列表、订单列表、订单详情、任务详情、邮件会话详情 URL。

第一版 seed 覆盖:队列阻塞、已完成 OPERA 模拟、OPERA 失败可重试、Fallback 人工复核、历史 Message Notification 只读任务、邮件会话完整 HTML / 附件 / 内联图片。旧 S000/S999 特殊只读任务可通过 SuperAgent 回调补充0711 P0 新入口的 S10/S99 已纳入后端 P0 fixtures 回归测试参考。

6.1 M002 V3 当前状态和后续待补能力

本节记录 0711 P0 基线确认后,前端关心的 V3 能力状态。已完成项可以直接接入;后置项需要另开 checkpoint。

能力 页面 / 场景 状态 前端最小诉求
结构化 S10/S99 入站 任务列表、任务详情、Debug EML 结果展示 已完成第一版 后端接收 result_type=source_message_review_notification + route_code=S10/S99,创建只读源邮件通知卡;任务列表可见,订单列表不可见;返回 route_code、入口说明、agent_assessmentnotification 和 S99 的入口 manual_review
S000/S999 兼容映射 任务列表、任务详情 已完成第一版 旧数据继续可见;前端可按 S000→S10S999→S99 展示统一文案。
40 条 P0.1 路由元数据 任务列表筛选、订单任务时间线、任务详情标题、字段展示 已完成第一版 后端保存并返回 AI 原始 result_type/ai_task_type/task_subtyperoute_code 和系统处理分类;前端不要只依赖系统主任务类型判断卡片。
P0.1 稳定 route_code 任务列表筛选、订单任务时间线、任务详情标题 已完成第一版 route_code 保持历史稳定,不因路由总数变 40 而连续重编号;前端仍可能看到 R41_FALLBACK_BUSINESS_EVENT_REVIEWR42_UNHANDLED_CURRENT_INTENT
Parent split 父事件卡型 任务列表、订单任务时间线、任务详情标题 已完成第一版 0712 P0.1 后Parent split 父事件展示为 Parent Group / Cancel Allotment / cancel_allotment_control_blockroute_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL 展示为普通业务卡,route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_REVIEW 展示为同卡人工复核业务卡;linked_parent_release_after_child_split 仅作为关系字段,不作为任务 subtype 筛选项。
unhandled_current_intents[] 展示块 任务详情 已完成第一版 后端保存并在任务详情 unhandled_intents[] 返回未覆盖业务意图,只用于展示和源邮件查看,不自动建业务任务卡。
adapter_contract_error 任务详情、错误提示 已完成第一版 命中 P1/P2 未闭合或路由冲突时,任务详情 adapter_contract_errors[] 返回稳定错误 code 和原始片段,不转成 Fallback。
type-known manual review 同卡解阻 任务详情复核 已完成第一版 manual_review 不再全部等同 Fallback已知业务卡型返回原业务卡信息、review_statusreview_resolution 和可编辑 pointer 字段,解阻后进入 READY
复核场景订单归属确认 任务详情复核 已完成第一版 后端提供复核确认时的订单归属确认;当前第一版只能确认当前任务所属订单,后续如要选择其他订单需另行细化。
P0 fixtures 回归基线 联调回归 已完成第一版 后端已将 0711 P0 fixtures 纳入测试参考;前端对 S10/S99、同卡复核和只读诊断块的展示应继续按本节稳定字段接入。

6.2 前端本轮接入状态2026-07-11

本轮前端已按 M002 V3 P0 完成以下接入,后端不需要重复补接口:

  • 任务列表已按 result_typeroute_codesystem_process_category 识别 source_message_review_notificationadapter_contract_errorunhandled_current_intent 只读诊断任务S10/S99 和旧 S000/S999 都不展示订单入口。
  • 任务详情已展示 result_typeai_task_typetask_subtyperoute_codesystem_process_categoryreview_status、来源邮件入口、source_message_only_resultmanual_reviewadapter_contract_errors[]unhandled_intents[]
  • Parent Group P0.1 前端已按 route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL/REVIEW 展示 Parent Group / Cancel Allotment / cancel_allotment_control_blockreview 场景继续走同卡人工复核解阻,不展示为 adapter_contract_error
  • type-known result_type=manual_review 已在原业务任务卡展示复核状态和缺失字段,并调用 POST /api/reservation/tasks/{taskId}/manual-review-resolutions 解阻,不再创建第二张人工复核任务卡。
  • 第一版解阻 UI 已改为优先使用任务详情 fields[].field_pointer,并同时提交 P0 主 fields[].field_path;旧扁平 legacy_field_path / legacy_field_values 仅用于 field_contract_version=code-v1 历史任务过渡回显,不作为新前端主动提交路径。
  • 前端只读规则已收口S10/S99、适配契约异常、未处理意图、前置任务阻塞和同卡人工复核待解阻状态都不显示保存草稿、确认任务、人工转换或 OPERA 执行 / 重试入口。
  • 前端 fixture 已补 V3 最小结构样例:source_message 完整对象、message_events[]event_rolecurrent_or_historysource_event_index、四字段 case_keysrelevant_message_excerptattachmentsfile_referencescontext_usedextracted_fieldsmanual_review

仍建议后端确认:

  • GET /api/reservation/tasks 是否会在结构化 S10/S99 行中稳定返回 task_type=SOURCE_MESSAGE_ONLY,或允许返回 MESSAGE_NOTIFICATION 并只依赖 result_type/route_code/system_process_category;前端当前两种都兼容。
  • adapter_contract_error / unhandled_current_intent 如果未来也作为独立列表行返回,请保持 source_message_id 可用,便于前端继续提供邮件会话入口。
  • 同卡人工复核解阻成功后是否一定返回 opera_operations[]。当前文档写“两条 OPERA 模拟操作”,前端实现按实际返回刷新,不假设固定数量。
  • Parent Group manual_review.reason_code=target_object_unclear 场景需要任务详情稳定透出 context_used.parent_identity_candidates[]。当前 ReservationTaskDetailResult 后端 DTO 仅透出 manual_review,前端已兼容顶层 context_used.parent_identity_candidates[]manual_review.context_used.parent_identity_candidates[],但若后端不透出 candidates页面只能显示空态提示。

前端注意:不要把访问口令写入前端仓库、浏览器环境变量或构建产物;该接口只能由本地联调人员手动调用或由受控测试脚本调用。

7. 邮件会话详情接口

建议优先路径:

GET /api/source-messages/{sourceMessageId}/conversation

历史候选路径,当前不提供:

GET /api/source-message-conversations/{externalConversationId}

当前状态:GET /api/source-messages/{sourceMessageId}/conversation 已完成第一版。前端入口从某个任务的 source_message_id 进入,后端根据该 SourceMessage 找到 external_conversation_id,再返回同一邮件会话下的全部邮件。

中文说明:

  • “全部邮件”指同一个 externalConversationId 下的历史邮件、当前邮件和后续回复,不是只展示任务对应的单封来源邮件。
  • 邮件会话详情页需要展示完整正文或清洗后的 HTML、附件、内联图片、发件人展示值、发送 / 接收时间、主题和关联订单 / 任务。
  • 前端不在页面上做业务截断或隐藏但仍只调用本项目后端接口不直接访问邮箱、AgentBus、数据库或外部附件 URL Secret。
  • 如果后端仍需要审计原文读取,应由后端在该业务接口内部处理;前端不保存 X-TH-Hotel-Source-Original-Read-Key 一类受控访问 key。
  • 2026-07-08 后端已新增 html_body_sanitizedhtml_render_mode;前端页面展示邮件 HTML 时应优先使用 html_body_sanitizedhtml_body 只作为原始内容兼容字段,不建议生产直渲。
  • 第一版仅处理 HTML 内容清洗;附件和内联图片 URL 来自本系统 OSS 服务,暂不做额外拦截或代理转换。

建议入参:

参数 必填 说明
sourceMessageId 入口来源消息 ID。后端据此定位 externalConversationId

当前第一版不额外接收 hotelIdincludeBodyincludeRelated。后端默认按 SourceMessage 自身酒店上下文查询同会话邮件,返回完整 text/html、清洗后的 HTML 和关联订单 / 任务摘要,并在内部写原文读取审计。

建议返参:

{
  "conversation": {
      "external_conversation_id": "thread-20260708-001",
      "hotel_id": "HOTEL-TEST",
      "channel": "EMAIL",
      "subject": "Re: Booking Update",
      "message_count": 6,
      "first_received_at": "2026-07-06T01:10:00Z",
      "last_received_at": "2026-07-08T03:28:00Z"
  },
  "messages": [
    {
      "id": "30001",
      "external_message_id": "msg-001",
      "external_conversation_id": "thread-20260708-001",
      "sender_summary": "guest@example.com",
      "subject": "Booking Request",
      "received_at": "2026-07-06T01:10:00Z",
      "source_sent_at": "2026-07-06T01:08:00Z",
      "text_body": "完整邮件正文",
      "html_body": "<p>完整邮件 HTML</p>",
      "html_body_sanitized": "<p>完整邮件 HTML</p>",
      "html_sanitize_required": true,
      "html_render_mode": "SANITIZED_HTML",
      "inline_images": [],
      "attachments": [
        {
          "mediaType": "ATTACHMENT",
          "fileName": "rooming-list.xlsx",
          "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          "sizeBytes": 10240,
          "externalUrl": "由后端决定是否返回可访问 URL",
          "externalMediaId": "media-001"
        }
      ],
      "related_orders": [
        {
          "order_id": "20001",
          "display_order_key": "GRP-001",
          "order_status": "ACTIVE"
        }
      ],
      "related_tasks": [
        {
          "task_id": "10001",
          "order_id": "20001",
          "task_type": "NEW_BOOKING",
          "task_subtype": "NEW_BOOKING",
          "task_status": "PENDING_CONFIRM",
          "card_name": "New Booking"
        }
      ]
    }
  ]
}

8. 任务详情接口字段元数据扩展

建议路径:

GET /api/reservation/tasks/{taskId}

当前状态:后端已有任务详情接口,前端任务详情页可以接入。该接口已返回 fields[]、草稿、确认 payload、可处理状态和 OPERA 模拟操作;本轮已透出来源邮件会话字段,以及旧 docs/import/20260708/任务卡前端展示字段表 3.0.xlsx 中 P0 需要的字段元数据。0711 P0 后续开发应迁移到 docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更说明_3.0_to_当前版_2026-07-10.xlsx 和同目录路由说明。

任务详情页面相关已完成接口:

接口 用途 后端状态
GET /api/reservation/tasks/{taskId} 读取任务详情、字段矩阵、当前值、可处理状态、OPERA 操作摘要。 已完成第一版,已补本节字段。
PUT /api/reservation/tasks/{taskId}/draft 保存任务卡草稿。 已完成。
POST /api/reservation/tasks/{taskId}/confirm 最终确认任务卡字段。 已完成。
GET /api/reservation/tasks/{taskId}/audits 查询任务审计流水。 已完成。
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute 执行 OPERA 模拟操作。 已完成第一版模拟。
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry 重试失败的 OPERA 模拟操作。 已完成第一版模拟。
POST /api/reservation/tasks/{taskId}/manual-review-conversions 将 Fallback / manual_review 转换为具体任务类型。 已完成。
POST /api/reservation/tasks/{taskId}/manual-review-resolutions type-known manual review 在原业务任务卡上提交字段修正和订单归属确认。 已完成第一版。

已完成的 fields[] 字段:

返回口径:fields[] 是后端按当前任务生效规则过滤后的字段集合,不是完整字段矩阵。后端已经应用 visibleresult_typetask_typetask_subtypedisplay_condition;未返回字段对当前任务视为不展示、不校验、不提交,前端不要自行补齐,也不要依赖固定字段数量。

字段 说明
row_number 字段矩阵行号。
card_name 任务卡名称。
display_area 前端展示区域。
field_path 字段路径。
display_name 展示名。
visible 是否展示。
editable 是否可编辑。
input_editable 是否输入方式编辑。
select_editable 是否下拉方式编辑。
date_picker 是否日期选择。
number_input 是否数字输入。
file_display 是否文件展示。
table_editable 是否表格编辑。
enum_options 枚举选项。
required_rule 必填规则。
display_condition 展示条件。
validation_rule 校验规则。
write_path 写入路径。
opera_write_participation 是否参与 OPERA 写入。
opera_parameter_mapping OPERA 参数映射。
notes 备注。
value 当前回显值。

本轮已补字段:

位置 字段 说明
顶层 source_subject 任务来源消息主题摘要。
顶层 source_sender_summary 任务来源消息发件人展示值,当前不打码。
顶层 source_received_at 任务来源邮件接收时间,优先取 AgentBus payload received_at
顶层 external_conversation_id 任务来源消息所属邮件会话 ID。
顶层 conversation_message_count 会话内邮件数量。
fields[] result_type 3.0 字段表中的结果类型,用于前端调试和字段分组校验。
fields[] task_type 3.0 字段表中的任务主类型。
fields[] task_subtype 3.0 字段表中的任务 subtype / 业务动作。
fields[] default_value_source 3.0 字段表中的默认值 / 回显来源。

8.1 Type-known manual review 同卡复核解阻

当前状态:后端已完成第一版。result_type=manual_reviewsystem_task_type 不是 MANUAL_REVIEW 时,前端在原业务任务卡上展示复核模式,不进入 Fallback 转换页面。

任务详情增量字段:

字段 说明
review_status PENDING 表示等待复核,RESOLVED 表示已解阻。
review_resolution 已解阻后的复核结果;未解阻时为 null
manual_review SuperAgent 原始复核说明、缺失字段、阻塞点、建议人工动作;只读展示。

解阻接口:

POST /api/reservation/tasks/{taskId}/manual-review-resolutions
Content-Type: application/json

请求示例:

{
  "confirmed_order_id": "20001",
  "reason": "确认 PMS 房型代码后解阻。",
  "field_overrides": [
    {
      "field_pointer": "/extracted_fields/room_items/0/pms_room_type_code",
      "field_path": "extracted_fields.room_items.0.pms_room_type_code",
      "value": "RM3"
    }
  ]
}

0711 P0 房型复核说明:前端应优先提交 /extracted_fields/room_items/0/pms_room_type_code 或任务详情 fields[].field_path=extracted_fields.room_items.0.pms_room_type_code。后端仍兼容旧扁平 key / pointer也支持只提交 field_path。如果同时提交 field_pointerfield_path,两者必须指向同一字段。响应里的 review_resolution.field_overrides[].field_path 使用 P0 主路径;前端只提交 field_path 时,后端会返回 P0 主 field_pointer;前端提交旧 pointer 时,field_pointer 保留前端原始值,legacy_field_path 仅用于旧页面过渡。

返回示例:

{
  "task_id": "10001",
  "order_id": "20001",
  "task_status": "READY",
  "review_status": "RESOLVED",
  "review_resolution": {
    "schema_version": "manual-review-resolution-v1",
    "confirmed_order_id": "20001",
    "resolved_at": "2026-07-11T00:00:00Z",
    "field_overrides": [
      {
        "field_pointer": "/extracted_fields/room_items/0/pms_room_type_code",
        "field_path": "extracted_fields.room_items.0.pms_room_type_code",
        "legacy_field_path": "extracted_fields.pms_room_type_code",
        "value": "RM3"
      }
    ]
  },
  "confirmed_payload": {
    "schema_version": "field_matrix-p0-room-items-v1",
    "field_values": {
      "extracted_fields.room_items.0.pms_room_type_code": "RM3"
    },
    "legacy_field_values": {
      "extracted_fields.pms_room_type_code": "RM3"
    },
    "effective_payload": {
      "extracted_fields": {
        "room_items": [
          {
            "pms_room_type_code": "RM3"
          }
        ]
      }
    }
  },
  "opera_operations": [
    {"operation_code": "SIMULATE_PRECHECK"},
    {"operation_code": "SIMULATE_WRITE"}
  ]
}

前端注意:

  • field_overrides[] 必须提供 field_pointerfield_pathfield_pointer 必须是 RFC 6901 JSON Pointerfield_path 可以是 P0 主路径或旧扁平路径。两者都只能指向任务详情 fields[] 中当前可编辑字段;只读字段、未知字段或两者指向不一致会返回 TASK_REVIEW_POINTER_INVALID
  • 同一次请求不能重复提交同一字段;重复 field_pointer 或重复映射到同一 field_path 会返回 TASK_REVIEW_POINTER_DUPLICATE
  • confirmed_order_id 第一版必须等于当前任务 order_id;普通任务任意切换订单继续后置。
  • type-known manual review 不能调用通用 POST /api/reservation/tasks/{taskId}/confirm;必须调用本节解阻接口,否则后端返回 TASK_REVIEW_RESOLUTION_REQUIRED
  • review_resolution.resolved_at 是 UTC Z 时间点。
  • 解阻成功后刷新任务详情,按钮状态以新的 task_status=READYavailability 为准。
  • confirmed_payload.field_values 按 P0 主 field_path 保存;legacy_field_values 是旧扁平兼容回显;effective_payload 是后端第一版嵌套结构,不是 OPERA 最终参数。

建议返参增量示例:

{
  "task_id": "10001",
  "order_id": "20001",
  "source_message_id": "30001",
  "source_subject": "Booking Update",
  "source_sender_summary": "guest@example.com",
  "source_received_at": "2026-07-08T02:58:00Z",
  "external_conversation_id": "thread-20260708-001",
  "conversation_message_count": 6,
  "system_task_type": "NEW_BOOKING",
  "task_card_type": "NEW_BOOKING",
  "task_status": "PENDING_CONFIRM",
  "field_contract_version": "20260711-p0",
  "fields": [
    {
      "row_number": 2,
      "card_name": "New Booking",
      "result_type": "RESERVATION",
      "task_type": "NEW_BOOKING",
      "task_subtype": "NEW_BOOKING",
      "display_area": "基础信息",
      "field_path": "case_keys.group_code",
      "display_name": "Group Code",
      "visible": "是",
      "editable": "否",
      "default_value_source": "AI识别结果 / 已确认草稿回显",
      "value": "GRP-001"
    }
  ]
}

中文说明:

  • 如果前端只做“按后端字段直接渲染”,现有 fields[] 可以支撑第一版表单展示;本轮已经扩展 ReservationTaskFieldResult,避免前端维护第二套字段矩阵。
  • fields[] 已是当前任务生效字段集合,前端不能把导入 Excel 或历史矩阵里的其他字段自行合成到页面上;例如 Group Block 不应补出 FIT 专属 Confirmation No. 输入框。
  • result_typetask_typetask_subtypedefault_value_source 当前从后端字段矩阵定义透出。
  • 如果后端已有更细的字段来源或适用场景元数据,可后续再扩展 field_sourceapplicable_scenario,不作为本轮 P0 阻塞项。
  • 前端默认不需要为 GET /api/reservation/ordersGET /api/reservation/tasksGET /api/reservation/orders/{orderId} 自动拼 hotel_id;如已接入酒店选择器,可以传当前选中酒店,后端会校验访问权限。当前 GET /api/reservation/tasks/{taskId} 以及任务写操作 Controller 不接收 hotel_id;第一版先按 ID 定位,后续多酒店隔离 / 权限方案统一补齐。

9. S10/S99 源邮件只读通知卡与历史兼容

当前状态:后端不提供独立 Message Notification 列表 / 详情接口。旧 SuperAgent 入口返回 S000,source_message_idS999,source_message_id 时,后端会创建 SOURCE_MESSAGE_ONLY 只读特殊任务0711 P0 结构化 S10/S99 也复用同一只读任务模型。前端已通过 GET /api/reservation/tasks?task_type=SOURCE_MESSAGE_ONLYGET /api/reservation/tasks/{taskId} 展示;任务列表筛选只保留 SOURCE_MESSAGE_ONLYS10S99,不再提供 S000S999 历史筛选项。

0711 P0 新入口已迁移为结构化 S10/S99

  • S10result_type=source_message_review_notificationroute_code=S10,表示未匹配当前支持的业务事件。
  • S99result_type=source_message_review_notificationroute_code=S99,表示输入不足或无法形成业务素材包。
  • S000 前端语义映射为 S10
  • S999 前端语义映射为 S99

历史 INFORMATIONAL_MESSAGE 仍可通过任务列表 / 任务详情兼容展示,但新数据不要依赖它。

展示规则:

  • task_type=SOURCE_MESSAGE_ONLYtask_subtype=S000/S999:按只读源邮件通知卡展示。
  • route_code=S10/S99:按只读源邮件通知卡展示。
  • 任务列表可见,订单列表不可见。
  • 任务详情只允许查看来源邮件、会话、附件和 SuperAgent 原始返回。
  • 任务详情通过 source_message_only_result 返回 entry_result_codeentry_result_meaningentry_result_descriptionentry_result_source_message_idresult_typeroute_codeagent_assessmentnotification、S99 的入口 manual_reviewraw_answer
  • 不显示编辑、确认、人工转换、执行 OPERA 或重试 OPERA 按钮。
  • 不参与订单任务执行顺序阻塞。

当前不建议新增路径:

GET /api/reservation/message-notifications
GET /api/reservation/message-notifications/{taskId}

列表建议入参:

参数 必填 说明
hotel_id 酒店 ID。单酒店阶段默认可为空由后端解析显式传值时后端会校验访问权限。
order_id 按临时订单或真实订单过滤。
keyword 邮件主题、摘要、发送人关键词。
page_num 页码。
page_size 每页条数。

详情建议返参:

{
  "task_id": "10009",
  "order_id": "20009",
  "task_type": "SOURCE_MESSAGE_ONLY",
  "task_subtype": "S000",
  "task_status": "COMPLETED",
  "queue_participation": false,
  "readonly": true,
  "visible_reason": "S000 pure information entry result",
  "relevant_message_excerpt": "Noted with thanks.",
  "entry_result_code": "S000",
  "entry_result_description": "纯信息类邮件",
  "attachments": [],
  "source_message_id": "30009",
  "external_conversation_id": "thread-20260708-009",
  "created_at": "2026-07-08T03:00:00Z"
}

V3 S10 结构化详情当前增量:

{
  "task_id": "10010",
  "readonly": true,
  "result_type": "source_message_review_notification",
  "route_code": "S10",
  "agent_assessment": {
    "status": "no_booking_action_detected",
    "reason_code": "no_booking_action_detected"
  },
  "notification": {
    "notification_type": "source_message_review",
    "show_source_message": true,
    "requires_user_decision": true
  },
  "manual_review": null,
  "source_message_id": "30010"
}

9.1 V3 诊断展示块

任务详情接口已新增两个只读数组:

字段 说明
adapter_contract_errors[] 同一 SuperAgent 入站批次中未生成任务的 Adapter 契约错误。
unhandled_intents[] 同一 SuperAgent 入站批次中无法映射到业务任务卡的未处理意图。

数组元素字段:

字段 说明
transition_id AI transition ID。
source_event_index AI current 事件序号。
array_index AI 返回数组顺序。
result_type AI 结果类型。
ai_task_type AI 原始任务类型。
task_subtype 业务动作 subtype可能为空。
route_code V3 路由码。
system_process_category 系统处理分类。
adapter_error_code 契约错误代码;未处理意图通常为空。
adapter_error_message 契约错误安全摘要。
payload_fragment 对前端展示安全的 AI item 片段。

前端注意:这两个数组不是任务队列,不提供编辑、确认、执行 OPERA 或重试入口;只用于解释为什么同一封邮件中的某些 event 没有变成业务任务。

10. 任务卡前端字段白名单元数据接口

是否需要该接口待确认。如果任务详情接口 fields[] 已透出 3.0 所需元数据,则第一版可以不做独立白名单接口;如果后续需要字段矩阵调试页、版本对齐页或前端预加载全部任务卡配置,再补独立接口。

建议路径:

GET /api/reservation/task-card-field-whitelist

建议入参:

参数 必填 说明
task_type 按系统主任务类型过滤。
task_subtype 按任务卡 subtype 过滤。
version 字段白名单版本,例如 20260711-p0

建议返参:

{
  "version": "20260711-p0",
  "items": [
    {
      "task_type": "UPDATE_BOOKING",
      "task_subtype": "RATE_CHANGE",
      "field_path": "rate.rate_code",
      "display_name": "Rate Code",
      "visible": true,
      "editable": true,
      "input_type": "select",
      "options": []
    }
  ]
}

11. 已确认后置接口

普通任务切换订单接口继续后置,前端暂不开发提交能力。后续如果恢复开发,建议另行确认:

POST /api/reservation/tasks/{taskId}/order-binding

待确认入参:

{
  "target_order_id": "20002",
  "reason": "人工确认该任务属于另一个订单"
}

待确认返参:

{
  "task_id": "10001",
  "previous_order_id": "20001",
  "target_order_id": "20002",
  "task_status": "PENDING_CONFIRM",
  "audit_id": "90001"
}

12. 待确认问题

  • 订单列表、任务列表当前统一使用 items + page 分页结构;邮件会话详情不分页,返回同一会话全部邮件。
  • 邮件会话详情接口已优先使用 GET /api/source-messages/{sourceMessageId}/conversation
  • 任务详情 fields[] 已由后端直接透出 P0 需要的 3.0 元数据;独立字段白名单接口后置。
  • 独立 Message Notification 页面继续后置;旧 S000/S999 和新 S10/S99 都先在任务列表和任务详情展示。
  • 邮件会话全文读取的审计策略由后端内部处理;前端不保存原文读取 key。
  • GET /api/reservation/tasks 结构化 S10/S99 行的 task_type 返回值请后端最终确认:前端已兼容 SOURCE_MESSAGE_ONLYMESSAGE_NOTIFICATION,但文档口径最好稳定一个。
  • manual-review-resolutions 成功响应中的 opera_operations[] 数量请后端最终确认;前端不写死两条,只按返回内容刷新展示。