# 前端提醒后端待补接口

## 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 | Message Notification 列表 / 详情接口 | 信息提醒页或订单详情只读卡片 | 未完成独立接口；可先通过任务列表 / 任务详情展示 `INFORMATIONAL_MESSAGE` |
| 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` | 已完成 | 可以 | 暂无。 |
| `GET /api/source-messages` | 已完成安全摘要列表 | 可以 | 不能替代邮件会话全文接口。 |
| `GET /api/source-messages/{id}` | 已完成单条安全摘要 | 可以 | 不能替代邮件会话全文接口。 |
| `GET /api/source-messages/{id}/original` | 已完成单封原文受控读取 | 谨慎接入 | 只能读单封邮件，不能返回同一 conversation 全量邮件。 |
| `GET /api/reservation/orders` | 已完成第一版 | 可以 | 默认查询全部订单状态；`open_task_count` 排除 `COMPLETED` 和 `FAILED`。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 已完成第一版，已补 `html_body_sanitized` 和 `html_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 结果，不创建订单和任务。 |
| `GET /api/source-message-conversations/{externalConversationId}` | 未发现后端实现 | 不可以 | 历史讨论过的候选路径，当前不提供；前端统一使用 `GET /api/source-messages/{sourceMessageId}/conversation`。 |
| `GET /api/reservation/message-notifications` | 未发现后端实现 | 不可以 | 如需独立信息提醒页再新增；第一版可先用任务接口过滤。 |
| `GET /api/reservation/task-card-field-whitelist` | 未发现后端实现 | 不可以 | 若任务详情 `fields[]` 已补齐 3.0 元数据，可后置。 |

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

建议路径：

```text
GET /api/reservation/tasks
```

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

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

已完成字段：

| 字段 | 说明 |
| --- | --- |
| `task_id` | 任务 ID。 |
| `order_id` | 关联订单 ID。 |
| `hotel_id` | 酒店上下文 ID。 |
| `display_order_key` | 前端优先展示的业务号或临时订单号。 |
| `temporary_order_no` | 临时订单号。 |
| `task_type` | 系统主任务类型。 |
| `task_subtype` | 任务 subtype。 |
| `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。第一版如果只有单酒店，可为空。 |
| `order_id` | 否 | 按订单过滤。 |
| `task_type` | 否 | `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`MANUAL_REVIEW`、`INFORMATIONAL_MESSAGE`。 |
| `task_status` | 否 | 任务状态过滤。 |
| `task_subtype` | 否 | 任务卡 subtype 过滤。 |
| `order_status` | 否 | 按任务所属订单状态过滤，支持 `TEMPORARY`、`ACTIVE`、`ENDED`、`LOGIC_DELETED`；不传时保持当前行为。 |
| `queue_participation` | 否 | 是否参与订单执行队列。 |
| `keyword` | 否 | Group Code、Confirmation No、临时订单号、来源消息安全摘要关键词。 |
| `page_num` | 否 | 页码，建议从 1 开始。 |
| `page_size` | 否 | 每页条数。 |

建议返参：

```json
{
  "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",
      "task_subtype": "RATE_CHANGE",
      "task_status": "PENDING_CONFIRM",
      "card_name": "Rate Change",
      "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` | 来源消息接收时间，用于任务列表排序和展示。 |
| `external_conversation_id` | 来源消息所属邮件会话 ID，用于打开完整邮件会话详情。 |
| `conversation_message_count` | 会话内邮件数量，用于提示用户该入口是整段会话，不是单封邮件。 |

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

建议路径：

```text
GET /api/reservation/orders/{orderId}
```

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

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

建议入参：

| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `orderId` | 是 | 订单 ID。 |
| `hotel_id` | 否 | 酒店 ID。第一版如果只有单酒店，可为空。 |
| `include_tasks` | 否 | 是否返回任务时间线，默认 `true`。 |
| `include_source_summary` | 否 | 是否返回来源消息摘要，默认 `true`；第一版参数保留，前端暂不要依赖它做字段裁剪。 |

建议返参：

```json
{
  "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",
      "task_subtype": "NEW_BOOKING",
      "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` | 来源消息接收时间。 |
| `external_conversation_id` | 来源消息所属邮件会话 ID。 |
| `conversation_message_count` | 会话内邮件数量。 |

## 5. 订单列表接口

建议路径：

```text
GET /api/reservation/orders
```

当前状态：后端已完成第一版。默认查询全部订单状态；`open_task_count` 排除 `COMPLETED` 和 `FAILED`，`next_processable_task_id` 按同订单队列可处理状态实时计算。

建议入参：

| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `hotel_id` | 否 | 酒店 ID。 |
| `order_status` | 否 | `TEMPORARY`、`ACTIVE`、`ENDED`、`LOGIC_DELETED`。 |
| `group_code` | 否 | 按 Group Code 精确或模糊查询，后端决定。 |
| `confirmation_number` | 否 | 按 Confirmation No 查询。 |
| `keyword` | 否 | 前端搜索框统一关键词；后端匹配订单字段，也会匹配来源消息安全摘要命中的 SourceMessage ID。 |
| `page_num` | 否 | 页码。 |
| `page_size` | 否 | 每页条数。 |

建议返参：

```json
{
  "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 接口

建议路径：

```text
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_KEY`，test 优先使用 `RESERVATION_TEST_DEMO_DATA_ACCESS_KEY`，旧通用变量 `RESERVATION_DEMO_DATA_ACCESS_KEY` 仅作为兼容兜底。 |
| `X-TH-Hotel-Demo-Data-Key` | 请求头必须携带，与后端配置口令一致。 |

请求示例：

```json
{
  "hotel_id": "HOTEL-TEST",
  "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 / 附件 / 内联图片。

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

## 7. 邮件会话详情接口

建议优先路径：

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

历史候选路径，当前不提供：

```text
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_sanitized` 和 `html_render_mode`；前端页面展示邮件 HTML 时应优先使用 `html_body_sanitized`，`html_body` 只作为原始内容兼容字段，不建议生产直渲。
- 第一版仅处理 HTML 内容清洗；附件和内联图片 URL 来自本系统 OSS 服务，暂不做额外拦截或代理转换。

建议入参：

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

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

建议返参：

```json
{
  "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. 任务详情接口字段元数据扩展

建议路径：

```text
GET /api/reservation/tasks/{taskId}
```

当前状态：后端已有任务详情接口，前端任务详情页可以接入。该接口已返回 `fields[]`、草稿、确认 payload、可处理状态和 OPERA 模拟操作；本轮已透出来源邮件会话字段，以及 `docs/import/20260708/任务卡前端展示字段表 3.0.xlsx` 中 P0 需要的字段元数据。

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

| 接口 | 用途 | 后端状态 |
| --- | --- | --- |
| `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 转换为具体任务类型。 | 已完成。 |

已完成的 `fields[]` 字段：

| 字段 | 说明 |
| --- | --- |
| `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` | 任务来源消息接收时间。 |
| 顶层 | `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 字段表中的默认值 / 回显来源。 |

建议返参增量示例：

```json
{
  "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": "20260708-3.0",
  "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`，避免前端维护第二套字段矩阵。
- `result_type`、`task_type`、`task_subtype`、`default_value_source` 当前从后端字段矩阵定义透出。
- 如果后端已有更细的字段来源或适用场景元数据，可后续再扩展 `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 列表 / 详情接口

当前状态：未发现后端独立 Message Notification 列表 / 详情接口。当前后端已经支持 `INFORMATIONAL_MESSAGE` 任务类型进入任务体系，第一版前端可以先通过 `GET /api/reservation/tasks?task_type=INFORMATIONAL_MESSAGE` 和 `GET /api/reservation/tasks/{taskId}` 展示信息提醒任务。仅当产品确认需要独立“信息提醒页”时，再新增本节接口。

建议路径：

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

列表建议入参：

| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `hotel_id` | 否 | 酒店 ID。 |
| `order_id` | 否 | 按临时订单或真实订单过滤。 |
| `keyword` | 否 | 邮件主题、摘要、发送人关键词。 |
| `page_num` | 否 | 页码。 |
| `page_size` | 否 | 每页条数。 |

详情建议返参：

```json
{
  "task_id": "10009",
  "order_id": "20009",
  "task_type": "INFORMATIONAL_MESSAGE",
  "task_status": "COMPLETED",
  "queue_participation": false,
  "readonly": true,
  "visible_reason": "FYI message without booking operation",
  "relevant_message_excerpt": "Noted with thanks.",
  "informational_message": "该消息仅作信息提醒，不需要执行 OPERA 操作。",
  "attachments": [],
  "source_message_id": "30009",
  "external_conversation_id": "thread-20260708-009",
  "created_at": "2026-07-08T03:00:00Z"
}
```

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

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

建议路径：

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

建议入参：

| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `task_type` | 否 | 按系统主任务类型过滤。 |
| `task_subtype` | 否 | 按任务卡 subtype 过滤。 |
| `version` | 否 | 字段白名单版本，例如 `20260708-3.0`。 |

建议返参：

```json
{
  "version": "20260708-3.0",
  "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. 已确认后置接口

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

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

待确认入参：

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

待确认返参：

```json
{
  "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 是否独立成页面，还是只在订单详情中展示。
- 邮件会话全文读取的审计策略由后端内部处理；前端不保存原文读取 key。
