docs: 收口 V4 任务卡展示与确认口径

This commit is contained in:
andy
2026-07-20 23:57:01 +07:00
parent c5b5ce6aab
commit c1163457a9
12 changed files with 253 additions and 98 deletions

View File

@@ -56,13 +56,13 @@
| `GET /api/reservation/tasks` | 查询任务列表 / 工作台 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`;未传 `order_id` 时按来源消息接收时间倒序,传 `order_id` 时按同订单队列顺序正序;用 `can_process``readonly_reason_code` 控制入口按钮;列表不返回 AI 原始 payload、邮件正文或附件 URL已返回来源邮件会话摘要字段并支持 `order_status` 按任务所属订单状态筛选;旧 S000/S999 和 V3 S10/S99 以 `task_type=SOURCE_MESSAGE_ONLY` 只读任务返回,列表已透出 `result_type``ai_task_type``route_code``system_process_category`。V4 S10/S99 不再进入该旧任务表,应从 V4 工作台来源通知接口展示。 |
| `GET /api/reservation/workbench-items` | 查询 V4 工作台统一列表 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`;返回 V4 业务订单任务和 S10/S99 来源通知混排摘要;支持 `hotel_id``item_type``keyword``page_num``page_size`;默认按 `source_received_at` 倒序,同一来源时间下按 `updated_at``created_at`、数字 `target_id` 倒序;列表不返回邮件正文、附件 URL、`ai_payload_json` 或来源通知原始 payload。 |
| `GET /api/reservation/order-tasks` | 查询 V4 业务订单任务列表 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`;只返回 V4 业务订单任务,不包含 S10/S99 来源通知;支持 `hotel_id``order_id``order_task_status``card_status``keyword``page_num``page_size``order_task_status``OPEN` / `COMPLETED` 返回 400`card_status` 非 V4 卡状态返回 400`card_status` 只筛业务 / 可处理卡,固定来源邮件展示卡不参与筛选。 |
| `GET /api/reservation/order-tasks/{orderTaskId}` | 查询 V4 订单任务详情 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`,后端按订单任务实际酒店校验访问权;返回 `order_task``source_message_summary``source_message_card``basic_information_card``business_cards[]``card_counts``adapter_contract_errors[]``availability`;来源摘要按酒店过滤,邮件正文和附件仍走 SourceMessage 会话接口。CP8 起每张 V4 任务卡返回 `fields[]`,前端应以该字段白名单渲染可编辑控件。 |
| `GET /api/reservation/order-tasks/{orderTaskId}` | 查询 V4 订单任务详情 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`,后端按订单任务实际酒店校验访问权;返回 `order_task``source_message_summary``source_message_card``basic_information_card``business_cards[]``card_counts``adapter_contract_errors[]``availability`;来源摘要按酒店过滤,邮件正文和附件仍走 SourceMessage 会话接口。V4 任务详情页展示顺序固定为 Basic Information、业务卡、SourceMessage Display来源邮件卡位于页面最下方正文限定为当前触发该 order task 的 SourceMessage 正文,前端用 `source_message_summary.source_message_id` 调用 `GET /api/source-messages/{sourceMessageId}/conversation` 后定位当前邮件。Payment 卡下一阶段可返回 `payment_attachments[]` 安全摘要用于展示凭证附件,但本接口不得返回附件 URL图片缩略图 / 大图和非图片下载 URL 仍通过 SourceMessage 会话权限链路取得。CP8 起每张 V4 任务卡返回 `fields[]`,前端应以该字段白名单渲染可编辑控件。 |
| `GET /api/reservation/order-tasks/{orderTaskId}/audits` | 查询 V4 订单任务审计流水 | 必须带 Bearer token需要 `RESERVATION_AUDIT_READ`,后端按订单任务实际酒店校验访问权;返回 `order_task_id``items[]``items[]` 用于展示 V4 卡片确认、复核解阻和订单归属确认轨迹只包含脱敏后的审计摘要不包含邮件正文、HTML、附件 URL、AI 原始 payload、token 或 secret。 |
| `GET /api/reservation/source-notifications/{notificationId}` | 查询 V4 S10/S99 来源通知详情 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`,后端按来源通知实际酒店校验访问权;只返回通知摘要、来源邮件通知卡、会话摘要和 `availability`;不返回订单任务、业务卡、邮件正文、附件 URL 或原始 AI payload。 |
| `GET /api/reservation/source-notifications/{notificationId}/audits` | 查询 V4 S10/S99 来源通知审计流水 | 必须带 Bearer token需要 `RESERVATION_AUDIT_READ`,后端按来源通知实际酒店校验访问权;返回 `notification_id``items[]``items[]` 第一版用于展示来源通知 ack 记录,只包含脱敏后的审计摘要。 |
| `GET /api/reservation/lookups/accounts` | 查询 V4 Account 目录 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`,支持 `hotel_id``keyword``page_num``page_size`;返回统一 wrapper`hotel_id``catalog_type=ACCOUNT``catalog_source``catalog_version``stale``items[]``page``warnings[]``keyword` 匹配目录 code 时后端按稳定 code 大写归一化处理,前端可传小写;匹配显示名仍按数据库比较规则。`keyword` 无匹配时 `items=[]` / `page.total=0`,但只要酒店未过滤目录存在,`catalog_source/catalog_version` 仍保持真实目录元数据,不代表目录未初始化。前端在 `options_source=reservation_v4_account_catalog` 时调用,只提交 `items[].code`Market / Source 以后端确认派生结果为准。 |
| `GET /api/reservation/lookups/room-types` | 查询 V4 Room Type 目录 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`,支持 `hotel_id``keyword``page_num``page_size`;第一版只返回当前酒店 `ACTIVE` 房型目录,不接日期过滤,不代表 PMS 全量房型。`keyword` 匹配房型 code 时后端按稳定 code 大写归一化处理,前端可传小写;匹配显示名仍按数据库比较规则。`keyword` 无匹配时按空选项处理,不要当作目录不可用。前端在 `options_source=reservation_v4_room_type_catalog` 时调用。 |
| `GET /api/reservation/lookups/rate-codes` | 查询 V4 Rate Code 目录 | 必须带 Bearer token需要 `RESERVATION_TASK_READ`支持 `hotel_id``keyword``page_num``page_size`;第一版只返回当前酒店 `ACTIVE` Rate Code`pricing_available=false` 表示后端未接真实价格,不要据此展示价格。`keyword` 匹配 Rate Code 时后端按稳定 code 大写归一化处理,前端可传小写;匹配显示名仍按数据库比较规则。`keyword` 无匹配时按空选项处理,不要当作目录不可用。前端在 `options_source=reservation_v4_rate_code_catalog` 时调用。 |
| `GET /api/reservation/lookups/rate-codes` | 查询 V4 Rate Code 目录 | 当前 CP11 实现只支持 `hotel_id``keyword``page_num``page_size`返回当前酒店 `ACTIVE` Rate Code;下一阶段必须新增必填 `account_code``booking_type=GROUP/FIT`,只返回当前 Account + GROUP/FIT 适用的 Rate Code。`pricing_available=false` 表示后端未接真实价格,不要据此展示价格。`keyword` 匹配 Rate Code 时后端按稳定 code 大写归一化处理,前端可传小写;匹配显示名仍按数据库比较规则。Account 合法但无适用 Rate Code 时按空选项处理,不要当作目录不可用;`account_code` 缺失 / 无效或 `booking_type` 非法时按 400 处理。前端在 `options_source=reservation_v4_rate_code_catalog` 时调用。 |
| `GET /api/admin/reservation/catalogs/accounts` | 管理后台 Account 目录列表 | 必须带 Bearer token需要 `RESERVATION_CATALOG_MANAGE` 和目标酒店访问权;支持 `hotel_id``keyword``status=ACTIVE/DISABLED``page_num``page_size``keyword` 搜索 code 时大小写不敏感,显示名仍按数据库比较规则;返回 `items[] + page`,包含 `id``account_code``account_name``market_code``source_code``status``catalog_source``external_account_id``catalog_version``metadata_json``version``created_at``updated_at`。 |
| `POST /api/admin/reservation/catalogs/accounts` | 管理后台新增 Account 目录 | 必须带 `RESERVATION_CATALOG_MANAGE`;请求 `hotel_id``account_code``account_name``market_code``source_code`,可选 `external_account_id``catalog_version``metadata_json`;后端校验 Market / Source 当前酒店 ACTIVE新增后默认 `ACTIVE``catalog_source=SYSTEM_MANAGED`,写管理审计。 |
| `PUT /api/admin/reservation/catalogs/accounts/{accountId}/status` | 管理后台启用 / 停用 Account | 必须带 `RESERVATION_CATALOG_MANAGE`;请求 `{"status":"ACTIVE"}``{"status":"DISABLED"}`;按记录所属酒店校验访问权;停用后普通 Account lookup 不再返回;如果提交的状态和当前状态一致,后端幂等返回当前记录,不新增管理审计。 |
@@ -72,8 +72,8 @@
前端已在系统设置下新增 `/system/reservation-catalogs` 消费上述目录管理接口。页面入口要求 `RESERVATION_CATALOG_MANAGE`,列表过滤直接传 `hotel_id``keyword``status``page_num``page_size`Account 新增第一版固定提交 `market_code=LEISURE``source_code=TRAVEL_AGENT`;状态重复提交按成功提示处理,不额外弹失败。
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm` | 确认 V4 订单任务卡 | 必须带 Bearer token需要 `RESERVATION_TASK_CONFIRM`,请求 JSON 带 `version`,可选 `confirmed_payload`Basic Information 必须先确认,业务卡第一版不强制逐张顺序确认;前端只提交当前卡 `fields[]` 中可编辑字段,后端以展示快照为基准合并,未开放字段会被忽略;确认前会按当前酒店数据库目录校验 Account / Room Type / Rate Code嵌套字段错误会返回如 `business_fields.after.room_items.0.room_type_code` 的路径,失败返回 `V4_FIELD_VALIDATION_FAILED`;确认后卡片 `CONFIRMED`、写 `confirmed_payload_json/confirmed_at/confirmed_by` 并锁定,重复确认返回错误;成功返回刷新后的订单任务详情。 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` | V4 复核解阻并确认卡片 | 必须带 Bearer token需要 `RESERVATION_MANUAL_REVIEW_RESOLVE`,仅用于 `card_status=REVIEW_REQUIRED`;请求 JSON 带 `version`,可选 `field_overrides[]``reason`;订单任务归属未解决时 `confirmed_order_id` 必填,且必须是当前酒店下真实可见订单;目录错误字段可按 `validation_errors_json` / `fields[].validation_errors` 指向的 pointer 修正;成功后卡片 `CONFIRMED``review_status=RESOLVED`,写 `review_resolution_json/confirmed_payload_json/confirmed_at/confirmed_by` 并返回刷新后的订单任务详情。 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm` | 确认 V4 订单任务卡 | 必须带 Bearer token需要 `RESERVATION_TASK_CONFIRM`,请求 JSON 带 `version`,可选 `confirmed_payload`Basic Information 必须先确认,业务卡第一版不强制逐张顺序确认;前端只提交当前卡 `fields[]` 中可编辑字段,后端以展示快照为基准合并,未开放字段会被忽略;确认前会按当前酒店数据库目录校验 Account / Room Type / Rate Code下一阶段 `rate_code` 还必须属于已确认 Account + 当前业务 event `booking_type` 的适用范围;嵌套字段错误会返回如 `business_fields.after.room_items.0.room_type_code` 的路径,失败返回 `V4_FIELD_VALIDATION_FAILED`;确认后卡片 `CONFIRMED`、写 `confirmed_payload_json/confirmed_at/confirmed_by` 并锁定,重复确认返回错误;成功返回刷新后的订单任务详情。 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` | V4 复核解阻并确认卡片 | 必须带 Bearer token需要 `RESERVATION_MANUAL_REVIEW_RESOLVE`,仅用于 `card_status=REVIEW_REQUIRED`;请求 JSON 带 `version`,可选 `field_overrides[]``reason`;订单任务归属未解决时 `confirmed_order_id` 必填,且必须是当前酒店下真实可见订单;`field_overrides[]` 只允许当前卡 `fields[]` 白名单内可编辑业务字段,问题字段可按 `fields[].validation_errors` 红字提示;成功后卡片 `CONFIRMED``review_status=RESOLVED`,写 `review_resolution_json/confirmed_payload_json/confirmed_at/confirmed_by` 并返回刷新后的订单任务详情。 |
| `POST /api/reservation/source-notifications/{notificationId}/ack` | 确认 V4 S10/S99 来源通知已读 / 已处理 | 必须带 Bearer token需要 `RESERVATION_TASK_CONFIRM`,请求 JSON 带 `version`;仅允许 `route_code=S10/S99`;确认后 `notification_status=ACKED`,写 `ack_by/ack_at`,成功返回刷新后的来源通知详情;重复 ack 返回当前已确认状态且不新增审计;该动作不创建订单、不参与订单阻塞。 |
| `GET /api/reservation/order-tasks/{orderTaskId}/audits` / `GET /api/reservation/source-notifications/{notificationId}/audits` | 查询 V4 业务审计展示数据 | 必须带 Bearer token需要 `RESERVATION_AUDIT_READ`;前端可在 V4 订单任务详情和 S10/S99 来源通知详情的“审计时间线”中调用。响应沿用旧审计行结构:`audit_id``actor_type``actor_id``action``reason``before_snapshot``after_snapshot``occurred_at`。快照已由后端脱敏,前端仍不要把未知 URL-like 字符串当附件或正文直渲。 |
| `GET /api/reservation/orders/{orderId}` | 查询订单详情与任务时间线 | 必须带 Bearer token需要 `RESERVATION_ORDER_READ`,后端按订单所属酒店做访问校验;`include_tasks=false` 可只取轻量摘要,此时旧 `tasks[]`、V4 `v4_order_tasks[]``related_source_messages[]` 都为空数组,`order_overview` 为空快照,`next_v4_action.action_type=NONE`;旧 `tasks[]` 按后端队列顺序返回前端不要自行按创建时间重排V4 `v4_order_tasks[]` 按同订单 V4 订单任务来源时间正序返回;隐藏技术订单详情不可作为普通订单页打开。 |
@@ -88,7 +88,7 @@
| `GET /api/source-messages` | 查询来源消息安全摘要 | 必须带 Bearer token需要 `SOURCE_MESSAGE_READ`列表不返回邮件正文、HTML、附件 URL 或原始 payload查询参数以 `hotel_id``external_message_id``external_conversation_id``page_num``page_size` 为准,后端暂兼容早期 camelCase 参数。 |
| `GET /api/source-messages/{id}` | 查询来源消息安全详情 | 必须带 Bearer token需要 `SOURCE_MESSAGE_READ`,后端按消息所属酒店做访问校验;只用于安全摘要详情。 |
| `GET /api/source-messages/{id}/original` | 读取来源消息原文 | 必须带 Bearer token需要同时拥有 `SOURCE_MESSAGE_READ``SOURCE_MESSAGE_ORIGINAL_READ`;后端按消息所属酒店做访问校验;返回 HTML 时前端展示前必须 sanitize。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 读取邮件会话详情 | 必须带 Bearer token需要同时拥有 `SOURCE_MESSAGE_READ``SOURCE_MESSAGE_ORIGINAL_READ`;返回同一外部会话全部邮件的完整 text/html、`html_body_sanitized`、附件外链、内联图片和关联订单 / 任务摘要;前端不传原文读取 key展示 HTML 时优先使用 `html_body_sanitized`。 |
| `GET /api/source-messages/{sourceMessageId}/conversation` | 读取邮件会话详情 | 必须带 Bearer token需要同时拥有 `SOURCE_MESSAGE_READ``SOURCE_MESSAGE_ORIGINAL_READ`;返回同一外部会话全部邮件的完整 text/html、`html_body_sanitized`、附件外链、内联图片和关联订单 / 任务摘要;前端不传原文读取 key展示 HTML 时优先使用 `html_body_sanitized`V4 Payment 卡图片预览和非图片下载也走该接口,前端只能使用当前触发 SourceMessage 且被 Payment `attachment_ids[]` 引用的附件。 |
| `POST /api/system/debug/eml-superagent-runs` | Debug 页面上传 `.eml` 并调用 SuperAgent | 仅 dev/test 受控调试使用;会写入 SourceMessage Inbox。Debug 服务自身不直接创建订单和任务;如 SuperAgent 通过正式回调 / MCP 写入业务结果,必须按当前 M002 V4 契约创建 V4 order task / cards不再创建旧 `workflow_reservation_task`。 |
| `GET/POST/PUT /api/admin/users...` | 系统管理用户维护 | 需要 Bearer token 和 `SYSTEM_USER_MANAGE`;用户 ID 返回字符串;禁用用户会撤销其 ACTIVE session。 |
| `GET/POST/PUT /api/admin/roles...` | 系统管理角色权限维护 | 需要 `SYSTEM_ROLE_MANAGE`;内置角色只读,自定义角色可新增、编辑和分配权限。 |
@@ -111,7 +111,7 @@
| `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 或错误上报SuperAgent 返回旧 S000/S999 或新 S10/S99 入口通知时都不应被前端视为 JSON 解析失败。测试机 V4 smoke 默认使用实时 AgentBus V4 subject历史 Debug V2/V3 profile 只能由后端显式配置,不应作为 V4 smoke 入口。 |
| `GET /api/reservation/workbench-items` / `/api/reservation/order-tasks/**` / `/api/reservation/source-notifications/{notificationId}` | 新增 M002 V4 CP5 查询接口,并在 CP6 打开卡片确认 / 来源通知 ack availability。 | 这是 V4 新模型前端主入口;前端应按每张卡或通知返回的 `availability.confirmable``availability.ackable``readonly_reason_code` 控制按钮。工作台条目已返回 `created_at` / `updated_at` 作为排序兜底和调试字段;前端不要继续从旧 `/api/reservation/tasks/**` 推断 V4 多卡详情。 |
| `GET /api/reservation/lookups/accounts` / `/room-types` / `/rate-codes` | 新增 M002 V4 CP11 数据库目录 lookup。 | 前端从任务详情 `fields[].options_source` 选择调用哪个 lookup只提交返回项的 `code`,不要提交显示名、派生 Market / Source、目录完整对象或前端自造 code。`warnings[]` 非空时可做非阻塞提示。 |
| `GET /api/reservation/lookups/accounts` / `/room-types` / `/rate-codes` | 新增 M002 V4 CP11 数据库目录 lookup。 | 前端从任务详情 `fields[].options_source` 选择调用哪个 lookup只提交返回项的 `code`,不要提交显示名、派生 Market / Source、目录完整对象或前端自造 code。Rate Code 下一阶段必须带已选 / 已确认 `account_code` 和当前业务 event `booking_type`,不能再拉全酒店全量候选。`warnings[]` 非空时可做非阻塞提示。 |
| `GET/POST/PUT /api/admin/reservation/catalogs/...` | 新增 M002 V4 目录管理后台 CP1 后端接口。 | 仅供系统设置 / 管理后台页面使用,必须带 `RESERVATION_CATALOG_MANAGE`;支持 Account、Room Type、Rate Code 列表、新增、启用 / 停用;停用后普通 lookup 不再返回该目录项。 |
V4 CP5 分页注意:`page_num` 从 1 开始,后端第一版安全上限为 100`page_size` 最大 100。超出上限时后端按上限处理并在 `page.page_num` / `page.page_size` 中返回实际使用值。`order_task_status``card_status` 是稳定枚举查询参数,前端不要传中文文案或自造状态码。
@@ -184,6 +184,7 @@ POST /api/auth/logout
- 第一版仅处理 HTML 内容安全;`inline_images[]``attachments[]``externalUrl` 来自本系统 OSS 服务暂不做额外拦截但前端仍不得写入普通日志、错误上报、localStorage 或 URL query。
- 会话详情接口由后端内部写原文读取审计actor 使用当前登录用户稳定 ID前端不传 `X-TH-Hotel-Source-Original-Read-Key``X-TH-Hotel-Actor``X-TH-Hotel-Access-Scene`
- 会话详情外层字段主要是 snake_case但媒体对象沿用原文读取接口字段当前是 `mediaType``fileName``contentType``sizeBytes``externalUrl``externalMediaId` 这种 camelCase前端类型定义需要单独处理。
- Payment 卡附件预览规则:业务卡里的 `attachment_ids[]` 是付款凭证引用,第一版只读展示并确认卡片,不允许前端增删或替换附件集合;后端下一阶段可返回 `payment_attachments[]` 安全摘要辅助展示。图片附件按 `contentType``image/` 开头判断,在卡片中展示缩略图,点击后打开大图预览;非图片附件统一展示文件名、类型、大小和下载按钮,不在 Payment 卡中内嵌 PDF / Word / Excel 预览。预览和下载必须先通过会话接口定位当前 SourceMessage再按 `externalMediaId` / `payment_attachments[].external_media_id` 或附件 ID 匹配,不能按文件名猜测。
### 5.5 订单列表接入注意
@@ -495,7 +496,7 @@ RESERVATION_ROOMING_LIST_GENERATE
后端已提供以下 V4 查询和写接口,前端接入时按这些约束实现;在前端页面正式集成并完成联调前,不把 V4 前端页面视为完成:
- `/reservation/tasks` 应使用 `GET /api/reservation/workbench-items` 作为默认工作台列表入口,展示 V4 订单任务和 S10/S99 来源通知混排摘要;当筛选工作项类型为订单任务时,改用 `GET /api/reservation/order-tasks`,仅发送后端当前支持的 `keyword``order_task_status``card_status``page_num``page_size`
- `/reservation/order-tasks/{orderTaskId}` 应使用 `GET /api/reservation/order-tasks/{orderTaskId}` 展示 `source_message_card``basic_information_card``business_cards[]``card_counts``order_task` 摘要和 `adapter_contract_errors[]` 只读诊断。
- `/reservation/order-tasks/{orderTaskId}` 应使用 `GET /api/reservation/order-tasks/{orderTaskId}` 展示 `basic_information_card``business_cards[]``source_message_card``card_counts``order_task` 摘要和 `adapter_contract_errors[]` 只读诊断;页面顺序固定为 Basic Information、业务卡、SourceMessage Display
- `/reservation/source-notifications/{notificationId}` 应使用 `GET /api/reservation/source-notifications/{notificationId}` 展示 S10/S99 来源通知详情,并通过 `POST /api/reservation/source-notifications/{notificationId}/ack` 确认已读 / 已处理。
- V4 审计时间线应分别调用 `GET /api/reservation/order-tasks/{orderTaskId}/audits``GET /api/reservation/source-notifications/{notificationId}/audits`;按钮权限使用 `/api/auth/me.permissions[]` 中的 `RESERVATION_AUDIT_READ`
- V4 卡片确认应使用 `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm`,请求带 `version`;前端只从当前卡 `fields[]` 中挑选 `editable=true``raw_readonly!=true``write_target` 指向确认 payload 的字段构造 `confirmed_payload`
@@ -503,8 +504,9 @@ RESERVATION_ROOMING_LIST_GENERATE
- 所有按钮应按后端 `availability.confirmable``availability.reviewable``availability.ackable` 和前端权限共同控制;不可操作原因优先展示 `readonly_reason_message`,否则按 `readonly_reason_code` 做友好映射。
- `fields[].validation_errors` 应展示在对应字段旁边;接口返回 `V4_FIELD_VALIDATION_FAILED``details[]` 带嵌套路径时,前端应尝试定位到对应 field定位不到则在当前卡片动作错误区展示。
- `options_source=reservation_v4_account_catalog``reservation_v4_room_type_catalog``reservation_v4_rate_code_catalog` 时,前端应调用对应 lookup API不再硬编码固定种子如果 lookup 返回空列表或 `warnings[]`,前端展示非阻塞提示,但提交时仍以后端目录校验为准。
- 前端不展示 `ai_payload_json`、邮件完整正文、附件 URL、raw evidence 或 SuperAgent 原始 payload来源邮件详情仍从邮件会话页面查看卡片内仅展示后端普通接口返回的安全摘要、邮件片段和附件名称
- V4 来源消息卡读取 `attachments``uploaded_media``file_references` 时,只允许展示附件名称、类型和大小等安全摘要;如果后端 payload 中异常出现 `https://``oss://``s3://` 直接 URL 字符串,前端必须替换为“未命名附件”或隐藏,不得把 URL 渲染到普通业务页面
- Trace 卡 `trace_items[].department_code` 第一版先固定下拉选项 `FO``HSK``FO+HSK`,不要调用不存在的 Department lookup API也不要允许自由文本正式 Department 目录和后端目录校验后续单独扩展
- 前端不展示 `ai_payload_json`、附件 URL、raw evidence 或 SuperAgent 原始 payloadV4 任务详情页底部 `SOURCE_MESSAGE_DISPLAY` 可展示当前触发该 order task 的 SourceMessage 正文,但必须通过 `GET /api/source-messages/{sourceMessageId}/conversation` 读取并写原文读取审计,不能要求 `GET /api/reservation/order-tasks/{orderTaskId}` 直接返回正文。Payment 卡如展示付款凭证图片,也必须通过同一会话接口获取受控附件 URL卡片内显示缩略图点击打开大图预览非图片只显示文件列表和下载。HTML 邮件优先渲染 `html_body_sanitized`,缺少原文权限或接口失败时降级为安全摘要和“查看邮件会话”入口
- V4 来源消息卡读取 `attachments``uploaded_media``file_references` 时,只允许展示附件名称、类型和大小等安全摘要;如果后端 payload 中异常出现 `https://``oss://``s3://` 等直接 URL 字符串,前端必须替换为“未命名附件”或隐藏,不得把 URL 渲染到普通业务页面。`SOURCE_MESSAGE_DISPLAY` 的邮件正文默认做长度折叠,用户可展开全文。
- V4 主流程不调用旧 V2/V3 草稿、旧任务确认、旧同卡复核接口,也不展示 OPERA 模拟操作入口。
- 2026-07-20 测试机 smoke 注意:订单详情页依赖 `GET /api/reservation/orders/{orderId}` 返回 `order_overview``next_v4_action``related_source_messages[]``v4_order_tasks[].cards[]`。如果测试机响应仍只有旧 `order``tasks[]`、基础 `v4_order_tasks[]``warnings`,应先确认测试机后端是否部署了包含 M002 V4 CP15.1 的最新包;前端不要为了该旧响应重新做兼容逻辑,避免把部署问题固化成页面分支。
@@ -524,6 +526,12 @@ RESERVATION_ROOMING_LIST_GENERATE
- 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 回调接口。
- M002 V4 CP5 已完成查询接口:普通 V4 业务包可通过 `/api/reservation/workbench-items``/api/reservation/order-tasks``/api/reservation/order-tasks/{orderTaskId}` 查看V4 S10/S99 来源通知可通过 `/api/reservation/source-notifications/{notificationId}` 查看。M002 V4 CP6 已开放普通卡片确认和 S10/S99 ack 写接口M002 V4 CP7 已开放 `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` 复核解阻接口M002 V4 CP8 已开放 V4 卡片 `fields[]` 白名单和目录校验M002 V4 CP11 已把固定种子迁移到数据库目录,并开放 Account / Room Type / Rate Code lookup API目录管理后台 CP1 已开放 Account / Room Type / Rate Code 后端列表、新增、启用 / 停用接口V4 业务审计查询已补齐订单任务审计和来源通知 ack 审计两个只读接口。
- V4 任务卡的 `display_payload_json` 只保留后端白名单展示字段;`ai_payload_json` 才包含完整 SuperAgent 原始 event。后续 V4 查询接口不得把 `ai_payload_json`、附件 URL 或 raw evidence 直接给普通页面渲染;前端对来源消息卡附件字段仍做 URL-like 文本兜底脱敏。
- Room Information 卡下一阶段应由后端返回业务展示模型,前端不要自行从 Agent raw payload 计算。`NEW_BOOKING` 展示最终值Group 的最终订单投影字段 `group_block_name` 可编辑,默认来自 `target_order.locator_value``locator_type=GROUP_CODE`Fit 的最终订单投影字段 `fit_name` 可编辑,默认来自 `guest_name ?? target_order.locator_value`Agent 原始 `target_order.locator_value` 始终只读,用户编辑只影响本系统最终订单投影和确认快照。`UPDATE_BOOKING` 展示本地当前值到 Agent 修改后值的 `change_summary[]`,日期变化时连带展示 Nights 差异,字段区展示合并后的最终值;`CANCEL_BOOKING` 从本地订单投影只读展示。Nights 由后端按酒店本地日期派生Adult 不显示。
- Room Information 卡 Breakfast 前端显示为“含早”勾选框Group 固定勾选且只读Fit 由后端按最终 Rate Code 中 `RB` / `RO` 派生无法派生时作为必填勾选项。Group Booking Status 仅 Group 显示,稳定 code 为 `TEN` / `DEF` / `INQ`,展示文案为 `TEN-Tentative``DEF-Definite``INQ-Inquiry`New Group 默认 `TEN``NEW_BOOKING` / `UPDATE_BOOKING` 确认前可改选,`CANCEL_BOOKING` 只读。
- Rooming List 卡确认存在跨卡联动:同订单为 Group 时,确认 `ROOMING_LIST` 后后端应把 Group Booking Status 自动置为 `DEF`,即使此前为 `TEN``INQ`Fit 不显示也不变更该状态。该自动变更需由后端写审计,前端只展示刷新后的状态。
- Rooming List 卡第一版是轻量事项确认卡:前端展示卡片标题、状态、目标订单信息和“确认卡片”按钮即可;不要做名单 rows、附件预览、Excel 生成或 PMS 导入入口。确认仅表示该 Rooming List 事项已人工处理。
- Payment 卡下一阶段建议由后端在 `display_payload_json.payment_attachments[]` 返回安全摘要,字段只包含附件 ID、文件名、类型、大小、是否图片、是否可预览 / 下载等,不包含外链。第一版 `attachment_ids[]` 是 Agent 返回的只读业务事实,前端只展示并确认卡片,不允许用户增删、替换或重新选择附件集合,也不把 `attachment_ids[]``externalUrl` 或完整附件对象提交回确认接口。
- V4 复核态卡片仍是原业务卡,不新建单独复核任务卡;页面状态显示“需要复核”,问题字段用 `fields[].validation_errors` 红字提示,主按钮文案统一为“确认卡片”。前端内部必须根据 `card_status=REVIEW_REQUIRED` 调用 `review-resolution`,不要调用普通 `confirm`
- 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[]` 只读诊断块中,不展示保存、确认、执行或重试按钮。该字段只返回白名单诊断字段,不返回完整 AI payload、邮件正文、附件 URL 或 raw evidence。
- V4 包级契约错误只会保存在 AI transition 中不会出现在普通任务列表V4 event 级契约错误如果同批次存在其它业务任务,前端仍按任务详情里的 `adapter_contract_errors[]` 只读展示诊断信息。
@@ -533,9 +541,9 @@ RESERVATION_ROOMING_LIST_GENERATE
- CP11 起 V4 入站阶段按当前酒店数据库目录做校验Account 缺失或不存在时 Basic Information 卡直接 `REVIEW_REQUIRED`;业务卡已有 `room_items[].room_type_code``rate_code` 但不在当前酒店目录时,业务卡也会直接 `REVIEW_REQUIRED`,错误会回显在 `fields[].validation_errors`
- CP8 确认接口也按 `fields[]` 白名单收口:前端可以只提交用户修改过的可编辑字段,不建议整包回传 `display_payload`。后端会从当前卡展示快照生成确认快照,并只合并可写叶子字段;来源邮件、路由、`target_order``order_ref``manual_review`、校验诊断字段以及前端额外注入字段不会写入 `confirmed_payload_json`
- 业务卡目录校验会递归检查 `business_fields` 下的嵌套结构。例如 `UPDATE_BOOKING` 的房型可能位于 `/business_fields/after/room_items/0/room_type_code`,错误详情会使用 `business_fields.after.room_items.0.room_type_code`;前端展示错误时优先用 `fields[].validation_errors`,接口 400 时可直接展示 `details[]`
- `review-resolution` 请求示例:`{"version":0,"reason":"确认房型映射","confirmed_order_id":"123456","field_overrides":[{"field_pointer":"/business_fields/room_items/0/pms_room_type_code","value":"RM2"}]}``confirmed_order_id` 在订单任务归属未解决时必填;如果订单任务已经绑定订单且 `target_resolution_status=RESOLVED`,只能不传或传当前同一个订单 ID不能借该接口切换到其它订单。`field_pointer` 必须来自当前卡允许编辑的 `basic_information.*``business_fields.*` 叶子字段;展示 payload 有 `missing_fields[]` 时只提交清单里的 pointer没有显式清单时只提交当前值为 `null` / 空字符串的未解决叶子字段;如果是目录校验错误,也可以提交后端 `fields[].validation_errors` 对应的字段 pointer。前端不要提交来源邮件、路由、`target_order``order_ref`、缺失字段清单、`manual_review`、raw evidence、校验诊断字段也不能替换整个对象 / 数组。
- `review-resolution` 请求示例:`{"version":0,"reason":"确认房型映射","confirmed_order_id":"123456","field_overrides":[{"field_pointer":"/business_fields/room_items/0/pms_room_type_code","value":"RM2"}]}``confirmed_order_id` 在订单任务归属未解决时必填;如果订单任务已经绑定订单且 `target_resolution_status=RESOLVED`,只能不传或传当前同一个订单 ID不能借该接口切换到其它订单。`field_pointer` 必须来自当前卡 `fields[]` 中可编辑的 `basic_information.*``business_fields.*` 叶子字段;复核态允许编辑当前卡业务白名单内字段,不再限定只能改空值、`missing_fields[]` 或目录错误字段。前端不要提交来源邮件、路由、`target_order``order_ref`、缺失字段清单、`manual_review`、raw evidence、校验诊断字段也不能替换整个对象 / 数组。
- V4 `fields[]` 第一版字段说明Basic Information 固定返回 `/basic_information/account_code``/basic_information/market_code``/basic_information/source_code`;其中 Account `control_type=select``options_source=reservation_v4_account_catalog`Market / Source 为只读派生字段。业务卡会按展示 payload 里的业务叶子字段返回字段白名单,例如 `/room_items/0/room_type_code``/business_fields/room_items/0/pms_room_type_code`;前端不要自行补未返回字段。
- V4 CP11 已开放独立目录 lookup API。前端应使用 `GET /api/reservation/lookups/accounts``GET /api/reservation/lookups/room-types``GET /api/reservation/lookups/rate-codes` 渲染 Account / Room Type / Rate Code 选项;用户提交确认或复核时只提交稳定 `code`,不要提交显示名、派生 Market / Source 或目录完整对象;后端确认前仍会重新校验目录。`keyword` 查不到只表示当前筛选无结果,不能仅凭 `items=[]` 判断目录未初始化,应结合 `catalog_source``catalog_version``warnings[]`
- V4 CP11 已开放独立目录 lookup API。前端应使用 `GET /api/reservation/lookups/accounts``GET /api/reservation/lookups/room-types``GET /api/reservation/lookups/rate-codes` 渲染 Account / Room Type / Rate Code 选项;用户提交确认或复核时只提交稳定 `code`,不要提交显示名、派生 Market / Source 或目录完整对象;后端确认前仍会重新校验目录。Rate Code 下一阶段依赖 Account + `booking_type`:前端需在 Account 已选 / 已确认且能取得当前业务 event `booking_type` 后再请求 Rate CodeAccount 改变后清空或重新校验已选 Rate Code缺失条件时禁用或空态不硬编码 OWNER RATE Excel。`keyword` 查不到只表示当前筛选无结果,不能仅凭 `items=[]` 判断目录未初始化,应结合 `catalog_source``catalog_version``warnings[]`
- M002 V4 CP12 前端已接入上述三个 lookup APIV4 多卡详情页会按当前卡 `fields[].options_source` 拉取目录选项,空 `items[]``stale=true``warnings[]` 作为非阻塞提示展示Account 选择后只展示目录返回的 `market_code` / `source_code` 辅助确认,确认 / 复核请求仍只提交用户选择的 code。
- V4 新模型确认口径是不保存后端草稿、卡片最终确认后锁定、技术异常不进入用户可处理卡、当前不生成 OPERA 模拟操作。Basic Information 必须先确认;其它业务卡第一版不强制逐张顺序确认。现有 V3 `draft``confirm``manual-review-resolutions` 和 OPERA 模拟接口仍只代表旧链路能力,不能直接等同 V4 多卡最终接口。
- V4 S10/S99 已采用来源通知模型入库:新 V4 `route_code=S10/S99` 不再挂隐藏技术订单,也不再创建旧 `SOURCE_MESSAGE_ONLY` 任务;对应工作台 / 来源通知详情查询接口和 ack 写接口已开放。旧 `SOURCE_MESSAGE_ONLY` 只读任务仅代表 V3 S10/S99 和旧 S000/S999 兼容数据。