接入前端真实接口并标记邮件HTML清洗

This commit is contained in:
andy
2026-07-08 23:37:03 +08:00
parent c83935a26c
commit a0cb3a05d7
25 changed files with 2581 additions and 157 deletions

View File

@@ -40,6 +40,9 @@
## 5. 当前已明确后置事项
- 普通任务切换订单接口后置。
- 任务列表按订单状态 `order_status` 筛选待后端补充或确认。
- 任务详情 / 任务写操作是否需要显式 `hotel_id` 待后端确认;前端已先统一配置 `VITE_RESERVATION_HOTEL_ID` 并用于列表和订单详情查询。
- 邮件 `html_body` 已标记为需要 sanitize前端联调阶段临时直渲只用于本地看效果生产前请后端返回已清洗 HTML 或明确清洗字段,并确认 CSP / 外链图片 / 附件 URL 策略。
- SuperAgent 查询接口 4 后置,当前先不开发。
- SuperAgent 查询接口 3 涉及附件解析、OCR、Excel、voucher、rooming list 等能力,当前系统暂不具备,仍后置。
- 用户身份 / 权限方案后置;当前后端审计 actor 仍是本地占位。

View File

@@ -49,7 +49,7 @@
| `GET /api/source-messages` | 查询来源消息安全摘要 | 列表不返回邮件正文、HTML、附件 URL 或原始 payload。 |
| `GET /api/source-messages/{id}` | 查询来源消息安全详情 | 只用于安全摘要详情。 |
| `GET /api/source-messages/{id}/original` | 读取来源消息原文 | 需要受控访问头,返回 HTML 时前端展示前必须 sanitize。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 读取邮件会话详情 | 返回同一外部会话全部邮件的完整 text/html、附件外链、内联图片和关联订单 / 任务摘要;前端不传原文读取 key,但展示 HTML 前必须 sanitize。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 读取邮件会话详情 | 返回同一外部会话全部邮件的完整 text/html、附件外链、内联图片和关联订单 / 任务摘要;前端不传原文读取 key。2026-07-08 联调阶段前端可临时直渲 `html_body` 看效果;生产方案必须对 `html_body` 做 sanitize建议后端返回已清洗 HTML 或明确清洗字段。 |
### 5.1 本轮新增 / 修改接口说明
@@ -79,10 +79,11 @@
### 5.3 邮件会话详情接入注意
- `GET /api/source-messages/{sourceMessageId}/conversation` 只接收路径参数 `sourceMessageId`;第一版不接收 `hotelId``includeBody``includeRelated`
- 前端当前通过 `VITE_RESERVATION_HOTEL_ID` 统一配置 Reservation 默认酒店上下文,并会在订单列表、任务列表和订单详情查询中传 `hotel_id`;任务详情、任务写操作和邮件会话详情当前后端接口不接收该参数。
- 后端会根据 `sourceMessageId` 定位 `external_conversation_id`,并返回同一会话下全部邮件;如果来源消息没有外部会话 ID会降级返回当前单封邮件。
- `messages[]` 按后端接收时间正序返回,前端不要重新按创建时间或任务时间排序。
- 返回内容包含完整 `text_body``html_body``inline_images[]``attachments[]``related_orders[]``related_tasks[]`
- `html_sanitize_required=true` 时,前端必须先 sanitize 再渲染 HTML不要使用清洗的 `html_body` 直接设置 DOM
- `html_body` 已标记为需要 sanitize`html_sanitize_required=true` 时,生产渲染必须使用清洗HTML。当前为了联调观察效果前端临时直接渲染原始 `html_body`,上线前需要后端 / 前端共同确认清洗字段、CSP、外链图片和附件 URL 策略
- `inline_images[]``attachments[]` 里的 `externalUrl` 可能包含有时效或访问凭证的外链前端不得写入普通日志、错误上报、localStorage 或 URL query。
- 会话详情接口由后端内部写原文读取审计,前端不传 `X-TH-Hotel-Source-Original-Read-Key`
- 会话详情外层字段主要是 snake_case但媒体对象沿用原文读取接口字段当前是 `mediaType``fileName``contentType``sizeBytes``externalUrl``externalMediaId` 这种 camelCase前端类型定义需要单独处理。

View File

@@ -9,7 +9,7 @@
| 优先级 | 接口 | 页面 / 场景 | 状态 |
| --- | --- | --- | --- |
| P0 | 订单列表接口 `GET /api/reservation/orders` | 订单列表页、首页工作台 | 已完成第一版 |
| P0 | 任务列表接口 `GET /api/reservation/tasks` | 任务列表菜单、订单详情任务入口 | 已完成第一版,已补来源邮件会话字段 |
| P0 | 任务列表接口 `GET /api/reservation/tasks` | 任务列表菜单、订单详情任务入口 | 已完成第一版,已补来源邮件会话字段`order_status` 筛选仍待后端补充或确认 |
| P0 | 订单详情接口 `GET /api/reservation/orders/{orderId}` | 订单详情页 | 已完成第一版,已补 `tasks[]` 每个任务的来源邮件会话字段 |
| P0 | 任务详情读取接口 `GET /api/reservation/tasks/{taskId}` | 任务详情页动态渲染 | 已完成第一版,已补来源邮件字段和 3.0 字段元数据 |
| P0 | 任务详情操作接口 | 任务详情保存、确认、OPERA、审计 | 已完成;前端可直接接入 |
@@ -25,12 +25,12 @@
| 接口 / 能力 | 当前后端状态 | 前端是否可直接接入 | 仍需后端处理 |
| --- | --- | --- | --- |
| `GET /api/reservation/tasks` | 已完成第一版,已补来源邮件会话字段 | 可以 | 暂无。 |
| `GET /api/reservation/tasks` | 已完成第一版,已补来源邮件会话字段 | 可以 | 前端暂不传 `order_status`,如任务列表需要按订单状态筛选,请后端补 `order_status` 入参并明确匹配逻辑。 |
| `GET /api/reservation/orders/{orderId}` | 已完成第一版,已补 `tasks[]` 来源邮件会话字段 | 可以 | 暂无。 |
| `GET /api/reservation/tasks/{taskId}` | 已完成第一版,已补任务顶层来源邮件字段和 `fields[]` 3.0 元数据 | 可以 | 暂无。 |
| `PUT /api/reservation/tasks/{taskId}/draft` | 已完成 | 可以 | 暂无。 |
| `POST /api/reservation/tasks/{taskId}/confirm` | 已完成 | 可以 | 暂无。 |
| `GET /api/reservation/tasks/{taskId}/audits` | 已完成 | 可以 | 暂无。 |
| `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` | 已完成 | 可以 | 暂无。 |
@@ -38,7 +38,7 @@
| `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` | 已完成第一版 | 可以 | 返回完整 text/html、媒体外链和关联订单 / 任务摘要;前端不传原文读取 key。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 已完成第一版 | 可以 | 返回完整 text/html、媒体外链和关联订单 / 任务摘要;前端不传原文读取 key。当前前端为看效果临时直渲 `html_body`;请后端标记 / 保障 `html_body` 需要 sanitize生产前返回已清洗 HTML 或明确清洗字段、CSP、附件 URL 策略。 |
| `POST /api/system/reservation/demo-data` | 已完成 | 仅本地 / test 联调可用 | 默认关闭,必须后端配置访问口令;不能作为生产页面接口。 |
| `GET /api/source-message-conversations/{externalConversationId}` | 未发现后端实现 | 不可以 | 历史讨论过的候选路径,当前不提供;前端统一使用 `GET /api/source-messages/{sourceMessageId}/conversation`。 |
| `GET /api/reservation/message-notifications` | 未发现后端实现 | 不可以 | 如需独立信息提醒页再新增;第一版可先用任务接口过滤。 |
@@ -87,6 +87,7 @@ GET /api/reservation/tasks
| `task_type` | 否 | `NEW_BOOKING``UPDATE_BOOKING``CANCEL_BOOKING``MANUAL_REVIEW``INFORMATIONAL_MESSAGE`。 |
| `task_status` | 否 | 任务状态过滤。 |
| `task_subtype` | 否 | 任务卡 subtype 过滤。 |
| `order_status` | 待补 | 前端任务列表已有订单状态筛选控件,但当前后端 Controller 未接收该参数,前端先禁用该筛选。建议后端确认是否支持按任务所属订单状态过滤。 |
| `queue_participation` | 否 | 是否参与订单执行队列。 |
| `keyword` | 否 | Group Code、Confirmation No、临时订单号、来源消息安全摘要关键词。 |
| `page_num` | 否 | 页码,建议从 1 开始。 |
@@ -323,6 +324,7 @@ GET /api/source-message-conversations/{externalConversationId}
- 邮件会话详情页需要展示完整正文或清洗后的 HTML、附件、内联图片、发件人摘要、发送 / 接收时间、主题和关联订单 / 任务。
- 前端不在页面上做业务截断或隐藏但仍只调用本项目后端接口不直接访问邮箱、AgentBus、数据库或外部附件 URL Secret。
- 如果后端仍需要审计原文读取,应由后端在该业务接口内部处理;前端不保存 `X-TH-Hotel-Source-Original-Read-Key` 一类受控访问 key。
- 2026-07-08 联调临时策略:前端为快速看效果,会优先直接渲染后端返回的 `html_body`;这不是最终安全方案。请后端明确标记 `html_body` 需要 sanitize并确认是否输出已清洗 HTML、是否增加 `html_body_sanitized` / `html_render_mode` 等字段,以及生产环境 CSP 和外链图片策略。
建议入参:
@@ -493,6 +495,7 @@ GET /api/reservation/tasks/{taskId}
- 如果前端只做“按后端字段直接渲染”,现有 `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`,请后端确认 taskId / operationId 是否全局唯一;如果不是,需要补可选 `hotel_id` 以避免多酒店数据串读或误写。
## 9. Message Notification 列表 / 详情接口

View File

@@ -177,6 +177,7 @@ th-TH
VITE_API_BASE_URL=http://localhost:8080
VITE_APP_ENV=local
VITE_DEFAULT_LOCALE=zh-CN
VITE_RESERVATION_HOTEL_ID=HOTEL-TEST
VITE_ENABLE_MOCKS=false
```
@@ -190,6 +191,7 @@ VITE_API_PROXY_TARGET=http://127.0.0.1:8081
- 公开配置可以放 `VITE_*`
- Secret 一律不进入 `VITE_*`
- `VITE_RESERVATION_HOTEL_ID` 是当前前端 Reservation 页面默认酒店上下文,用于订单列表、任务列表和订单详情查询;它不是 Secret但需要随本地 / test / prod 环境显式配置,避免页面查到错误酒店数据。
- 生产需要运行时配置时,应由部署系统生成公开配置文件,例如 `/app-config.json`
- 需要秘密的外部调用一律经后端代理或适配器。
@@ -280,3 +282,207 @@ pnpm test -- SomeSpecName.spec.ts
- [ ] 是否运行了 `pnpm typecheck` 或说明了无法运行原因?
- [ ] 是否运行了 `pnpm test` 或说明了无法运行原因?
- [ ] 是否运行了 `pnpm build` 或说明了无法运行原因?
## 18. Reservation 前端低保真结构图与流程图
本节只记录当前 Reservation 前端第一版信息架构草图,用于对齐页面结构和业务主线。具体 checkpoint 设计、接口契约和实施计划应放入单独需求或设计文档,不在本规范中展开。
### 18.1 订单工作台低保真结构图
```text
┌────────────────────────────────────────────────────────────────────────────┐
│ Hotel OMS 中文 / EN / ไทย 主题 / 用户 │
├───────────────┬────────────────────────────────────────────────────────────┤
│ │ 订单工作台 │
│ 订单管理 │ │
│ 任务队列 │ ┌──────────────────────────────────────────────────────┐ │
│ 消息来源 │ │ 筛选区 │ │
│ 系统状态 │ │ 日期范围 | 业务号 | 订单状态 | 任务状态 | 任务卡类型 │ │
│ │ └──────────────────────────────────────────────────────┘ │
│ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │
│ │ │ 订单 / 任务列表 │ │
│ │ │ 业务号 订单状态 当前任务 任务状态 操作 │ │
│ │ │ GRP-001 ACTIVE New Booking 待确认 查看 │ │
│ │ │ TMP-002 TEMP Fallback 人工复核 查看 │ │
│ │ │ CNF-003 ACTIVE Cancel READY 执行 │ │
│ │ └──────────────────────────────────────────────────────┘ │
└───────────────┴────────────────────────────────────────────────────────────┘
```
中文说明:
- 左侧导航只保留已确认的 Reservation 相关入口,不提前暴露未确认部门流程。
- 工作台首屏服务于“找到需要处理的订单或任务”,不是普通订单 CRUD 首页。
- 列表行应同时表达订单状态、当前任务、任务状态和下一步动作。
### 18.2 任务列表低保真结构图
```text
┌────────────────────────────────────────────────────────────────────────────┐
│ Hotel OMS 中文 / EN / ไทย 主题 / 用户 │
├───────────────┬────────────────────────────────────────────────────────────┤
│ │ 任务列表 │
│ 订单列表 │ │
│ 任务列表 │ ┌──────────────────────────────────────────────────────┐ │
│ 消息来源 │ │ 筛选区 │ │
│ 系统状态 │ │ 日期范围 | 订单号/业务号 | 任务类型 | 任务状态 | 可处理 │ │
│ │ │ 来源邮件关键词 | 是否参与队列 │ │
│ │ └──────────────────────────────────────────────────────┘ │
│ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │
│ │ │ 任务数据 │ │
│ │ │ 任务号 订单号 任务卡 状态 来源邮件 │ │
│ │ │ #10001 GRP-001 New Booking 待确认 Booking Req │ │
│ │ │ #10002 GRP-001 Update 阻塞中 Booking Upd │ │
│ │ │ #10003 TMP-002 Fallback 人工复核 Unknown Msg │ │
│ │ │ │ │
│ │ │ 队列 | 可处理 | 邮件会话 | 查看任务 | 查看订单 │ │
│ │ └──────────────────────────────────────────────────────┘ │
└───────────────┴────────────────────────────────────────────────────────────┘
```
中文说明:
- 任务列表是独立菜单,服务于“按任务处理”的工作方式,不是订单列表的复制。
- 列表数据来自 `GET /api/reservation/tasks`;该接口已存在第一版,前端应直接接真实接口,不展示 fixture 假数据。
- 每行任务至少展示 `task_id`、关联订单、任务卡名称、任务类型 / 子类型、任务状态、队列顺序、是否可处理、只读原因和来源邮件摘要。
- 每行操作保留“查看任务”“查看订单”“查看邮件会话”三个入口;邮件会话入口按该任务的 `source_message_id``external_conversation_id` 打开。
- 如果来源邮件会话字段暂未接入,邮件会话入口置灰或展示“接口待补”,不使用假会话数据。
### 18.3 订单详情与任务卡低保真结构图
```text
┌────────────────────────────────────────────────────────────────────────────┐
│ 订单详情 GRP-001 / TMP-20260707-0001 ACTIVE / TEMPORARY │
│ 主来源消息 #190... 业务号来源 AI_CANDIDATE 最近更新 2026-07-08 │
├────────────────────────────────────────────────────────────────────────────┤
│ 订单摘要 │
│ Group Code / Confirmation No. / 临时单号 / 订单状态 / 主来源消息 / 创建时间 │
├───────────────────────────────┬────────────────────────────────────────────┤
│ 同订单任务队列 │ 当前任务卡 │
│ │ │
│ ① New Booking 待确认 邮件会话│ New Booking 卡 │
│ ② Update 阻塞中 邮件会话│ ┌ 证据区 ───────────────────────────────┐ │
│ ③ Trace Notes 未开始 邮件会话│ │ 生成原因 / 来源消息摘要 / 附件 / 邮件会话│ │
│ │ └──────────────────────────────────────┘ │
│ │ ┌ 基础信息 ─────────────────────────────┐ │
│ │ │ Group Code / Confirmation No. / 类型 │ │
│ │ └──────────────────────────────────────┘ │
│ │ ┌ 入住与房型 ───────────────────────────┐ │
│ │ │ 入住日期 / 离店日期 / 房量 / 房型 / Rate│ │
│ │ └──────────────────────────────────────┘ │
│ │ │
│ │ [保存草稿] [确认任务] │
├───────────────────────────────┴────────────────────────────────────────────┤
│ OPERA 模拟操作 │
│ ① 预检查 PENDING / SUCCEEDED / FAILED ② 写入 PENDING / SUCCEEDED / FAILED │
│ │
│ 审计时间线AI 创建 → 保存草稿 → 人工确认 → OPERA 预检查 → OPERA 写入 │
└────────────────────────────────────────────────────────────────────────────┘
```
中文说明:
- 订单详情页必须沿用“订单归档容器 + 同订单任务队列 + 当前任务卡 + OPERA 模拟操作 + 审计时间线”的既有结构,不另起一套订单详情布局。
- 后续任务如果被前置任务阻塞,应在任务队列和任务卡操作区同时体现只读状态。
- 任务卡字段必须按后端字段矩阵分组渲染,不直接把 AI 原始 JSON 展示成自由表单。
- 邮件入口按任务粒度展示:每个任务可能来自不同 `source_message_id`,也可能落在不同 `external_conversation_id`。点击“邮件会话”只打开该任务来源消息所在的完整邮件会话,不代表订单下所有来源消息的合集。
- 当前任务卡证据区展示来源消息摘要、附件摘要和“查看邮件会话”入口完整邮件正文、HTML 和附件详情进入单独邮件会话详情页查看,避免订单详情页被长邮件撑开。
- OPERA 模拟和审计是任务确认后的执行轨迹,不应和 AI 原始建议混在同一区域。
### 18.4 任务详情低保真结构图
```text
┌────────────────────────────────────────────────────────────────────────────┐
│ 任务详情 #10002 Update Booking / RATE_CHANGE PENDING_CONFIRM │
│ 关联订单 GRP-001 [查看订单] 来源邮件 Booking Update [查看邮件会话] │
├────────────────────────────────────────────────────────────────────────────┤
│ 处理状态 │
│ 可处理 / 阻塞原因 / 队列顺序 / 前置任务状态 / 只读说明 │
├────────────────────────────────────────────────────────────────────────────┤
│ 证据区 │
│ 生成原因 / 来源消息摘要 / 附件摘要 / 完整邮件会话入口 │
├────────────────────────────────────────────────────────────────────────────┤
│ 任务卡字段 │
│ 基础信息Group Code / Confirmation No. / 业务动作 │
│ 变更内容before_after / rate_code / fix_charge_items │
│ 人工复核visible_reason / required fields / validation │
├────────────────────────────────────────────────────────────────────────────┤
│ 操作区 │
│ [保存草稿] [确认任务] │
├────────────────────────────────────────────────────────────────────────────┤
│ OPERA 模拟操作 │
│ 预检查 / 写入 / 重试状态 / 最近错误 │
├────────────────────────────────────────────────────────────────────────────┤
│ 审计流水 │
│ AI 创建 → 草稿保存 → 人工确认 → OPERA 预检查 → OPERA 写入 │
└────────────────────────────────────────────────────────────────────────────┘
```
中文说明:
- 任务详情页聚焦单个任务卡的查看、编辑、确认和执行轨迹,不承载同订单全局队列;同订单全局队列仍回到订单详情页查看。
- 任务详情读取来自 `GET /api/reservation/tasks/{taskId}`草稿保存、确认任务、OPERA 模拟和审计流水使用后端已存在的任务工作流接口。
- 证据区只展示来源消息摘要和附件摘要完整邮件正文、HTML、历史邮件和回复进入邮件会话详情页。
- 字段区按后端 `fields[]``display_area` 和字段规则分组渲染,不把 AI 原始 JSON 直接展示为自由表单。
- 如果任务不可处理,操作区应保持只读,并展示 `availability``readonly_reason_code` 给出的原因。
### 18.5 邮件会话详情低保真结构图
```text
┌────────────────────────────────────────────────────────────────────────────┐
│ 邮件会话详情 Re: Booking Update 返回订单 / 返回任务 │
│ Conversation thread-20260708-001 共 6 封 最近收到 2026-07-08 11:28 │
├────────────────────────────────────────────────────────────────────────────┤
│ 会话摘要 │
│ 酒店 / 渠道 EMAIL / 发件人汇总 / 主题 / 关联订单 GRP-001 / 关联任务 3 个 │
├────────────────────────────────────────────────────────────────────────────┤
│ 邮件时间线 │
│ │
│ ┌ 2026-07-06 09:10 guest@example.com Booking Request ────────────────┐ │
│ │ 邮件全文正文或已清洗 HTML │ │
│ │ 附件rooming-list.xlsx / voucher.pdf │ │
│ │ 关联New Booking #10001 │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ ┌ 2026-07-07 14:22 hotel@example.com Re: Booking Request ────────────┐ │
│ │ 邮件全文正文或已清洗 HTML │ │
│ │ 附件:无 │ │
│ │ 关联:无 │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ ┌ 2026-07-08 11:28 guest@example.com Re: Booking Update ─────────────┐ │
│ │ 邮件全文正文或已清洗 HTML │ │
│ │ 附件change-request.pdf │ │
│ │ 关联Update Booking #10002 │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────┘
```
中文说明:
- 邮件会话详情页展示同一个 `external_conversation_id` 下的全部邮件,包括历史邮件、当前邮件和后续回复。
- 页面入口可以来自订单详情任务队列、当前任务卡证据区或任务详情页,但落地页统一为“邮件会话详情”,不是单封邮件详情。
- 每封邮件应展示完整正文或清洗后的 HTML、附件列表、内联图片信息、发送 / 接收时间、发件人摘要、主题和关联订单 / 任务。
- 前端不在本页展示假数据;后端接口未接入时显示“接口待接入 / 暂无邮件会话数据”。
- 邮件全文属于用户在邮箱中本来可见的信息,前端页面不做业务层面的截断隐藏;但仍必须通过本项目后端接口读取,不在前端保存外部系统 Secret 或访问 key。
### 18.6 Reservation 任务主流程图
```mermaid
flowchart LR
A["SourceMessage Inbox<br/>来源消息"] --> B["AI 过渡层<br/>保存 AI 原始 JSON"]
B --> C["订单<br/>业务号或临时单号"]
B --> D["任务队列<br/>按 execution_order 排序"]
D --> E["任务卡详情<br/>字段矩阵驱动渲染"]
E --> F["保存草稿<br/>draft_payload"]
E --> G["最终确认<br/>confirmed_payload"]
G --> H["OPERA 模拟操作<br/>预检查 / 写入"]
H --> I["审计时间线<br/>确认、执行、重试记录"]
```
中文说明:
- `SourceMessage Inbox` 是来源事实层,不表达订单、任务或业务结论。
- AI 输出只作为原始建议和证据保存,不能直接改变最终业务状态。
- 用户确认后的 `confirmed_payload` 才能作为 OPERA 模拟操作输入。
- 审计时间线用于串联人工确认、OPERA 执行和重试记录,便于后续追溯。