# M002 Order Task Workflow 订单任务主流程 V2 ## 文档信息 | 项目 | 内容 | | --- | --- | | 文档版本 | 0.2 | | 日期 | 2026-07-07 | | 状态 | 第二版需求与后端阶段实现记录 | | 适用范围 | SourceMessage 之后的 AI 过渡层、订单挂靠、任务卡、人工确认、OPERA 模拟操作主流程 | | 主要读者 | 产品、后端、前端、测试、后续协作 agent | ## 1. 文档定位 本文是 `M002-order-task-workflow-v1.md` 的第二版修正,目标是把本项目已经讨论确认的订单任务主流程,与 2026-07-06 导入的 AI 任务卡契约对齐。 本文定义业务边界、数据语义和后续实现约束。当前后端已经按拆分 checkpoint 实现了 AI 结果接收、订单任务基础流转、任务草稿保存、最终确认、审计列表、OPERA 模拟骨架、SuperAgent 查询上下文接口 1、2 的最小字段版,以及前端 P0 任务列表 / 订单详情查询接口;前端页面、真实 OPERA、普通任务切换订单、查询接口 3 和查询接口 4 仍未实现。 ## 2. 本版核心修正 相对 V1,本版有以下修正: - 增加 `AI 过渡层`:系统必须先保存 AI 原始输出,再生成订单、任务和任务卡。 - 不再使用 `EXCEPTION` 作为底层结果类型,AI 第一版结果类型统一以 `normal_task`、`manual_review`、`informational_message` 为准。 - 系统主任务类型收敛为 `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`MANUAL_REVIEW`,另保留 `INFORMATIONAL_MESSAGE` 作为不参与执行队列的只读提醒任务。 - 除 `New Booking`、`Cancel Booking`、`Fallback/manual_review` 外,其他业务处理类卡片原则上都归到 `UPDATE_BOOKING` 下的不同任务卡。 - `Message Notification` 也挂到临时订单下面,便于归档和详情查看,但不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。 - 任务卡后端完整规则以 `任务卡展示编辑矩阵.xlsx` 为权威来源,不在代码里随意扩展或重命名字段路径。 - 前端展示 / 编辑白名单以最新导入的 `任务卡前端展示字段表 3.0.xlsx` 为准;该文件只约束前端展示和可编辑范围,不替代后端完整校验、确认写入和 OPERA 映射规则。 - 系统必须同时保存 AI 原始 `task_type`、系统主任务类型、任务卡类型和业务动作 subtype。 - `ai_payload_json` 与 `confirmed_payload_json` 必须分离。OPERA 模拟只能读取用户确认后的 `confirmed_payload_json`。 - 订单业务号候选字段和 OPERA 模拟回填边界需要明确记录,但 OPERA 返回 JSON 字段名目前未知,不能写死。 ## 3. 权威输入资料 本版需求参考以下资料: | 资料 | 作用 | | --- | --- | | `docs/project/requirements/M001-source-message-inbox-prd.md` | 上游 SourceMessage Inbox 边界 | | `docs/project/requirements/M002-order-task-workflow-v1.md` | 第一版整体业务流程 | | `docs/import/20260706/开发AI先读_工作顺序.md` | AI 过渡表、任务卡、确认 payload 和 OPERA 写入工作顺序 | | `docs/import/20260706/AI输出参数并集字典.xlsx` | AI 输出字段路径、字段含义、建议存储方式和索引建议 | | `docs/import/20260706/任务卡展示编辑矩阵.xlsx` | 后端任务卡完整规则来源,包括校验、确认写入、OPERA 映射和展示条件 | | `docs/import/20260708/任务卡前端展示字段表 3.0.xlsx` | 前端任务卡展示 / 编辑白名单,不替代后端完整规则矩阵 | | `docs/import/20260706/0630AI_副本 2/01_main_agent_prompt.md` | Main Agent 输出职责和聚合 JSON 结构 | | `docs/import/20260706/0630AI_副本 2/02_agent_workflow.md` | AI 侧事件拆分、Skill 调用和结果聚合流程 | | `docs/import/20260706/0630AI_副本 2/03_skill_catalog.md` | Skill 目录、结果类型、任务类型和统一输出字段 | | `docs/import/20260706/0630AI_副本 2/skill/S01-S08*.md` | 各业务任务卡的抽取规则和边界 | | `docs/import/20260706/0630AI_副本 2/references/qbd_liantai_email_table_rules.md` | QBD / LianTai 表格邮件拆分和证据规则 | | `docs/import/20260706/0630AI_副本 2/skill/*/references/rate_code_rules.md` | Rate Code 判断规则 | | `docs/import/20260706/0630AI_副本 2/skill/*/references/room_type_mapping_rules.md` | 房型映射规则 | 说明:`开发AI先读_工作顺序.md` 中提到的 `AI过渡表开发契约_README.md` 和 `AI过渡表开发契约_两张样例表.xlsx` 在当前导入目录下未找到同名文件。当前以后端完整规则矩阵、AI 输出参数字典和前端 3.0 白名单共同作为字段来源;三者职责不同,不能互相覆盖。 ## 4. 总体流程 ```text AgentBus / 未来其他入口 → SourceMessage Inbox 记录原始来源事实 → SuperAgent / Main Agent 读取 SourceMessage 并拆分 current 事件 → 对每个事件调用对应 Skill → 聚合输出 source_message_id + ai_task_results[] + extraction_warnings[] → 本系统接收 AI 结果并写入 AI 过渡层 → 本系统根据 result_type + task_type + task_subtype 生成订单、任务和任务卡 → 用户在任务详情页查看、修改字段、确认订单归属 → 系统生成 confirmed_payload_json → 用户触发 OPERA 模拟操作 → 系统保存每条模拟操作结果、失败原因和重试记录 ``` 中文说明: - `SourceMessage Inbox` 是来源事实层,不表达订单、任务或业务结论。 - AI 只输出 JSON,不直接写数据库、不直接创建真实任务卡、不直接写 OPERA。 - 本系统负责保存 AI 原始 JSON、创建任务卡、接收用户修改、生成确认后的 payload、执行 OPERA 模拟并记录结果。 - SuperAgent 不直连本系统数据库,只能通过本系统后端接口查询已有订单和任务上下文。 ## 5. AI 输出接收边界 导入文档已经定义了 SuperAgent / Main Agent 应输出的核心业务结构,但还没有定义完整 HTTP 接口契约。 AI 聚合输出的顶层结构应包含: | 字段 | 中文说明 | | --- | --- | | `source_message_id` | SuperAgent / Main Agent 原样带回的外部来源消息 ID,对应 AgentBus `source.external_message_id`,不是本系统内部 SourceMessage Inbox 主键 | | `ai_task_results[]` | AI 拆分出的一个或多个任务结果,顺序必须保留 | | `extraction_warnings[]` | 抽取警告,不直接等同于业务任务 | `ai_task_results[]` 中关键字段包括: | 字段 | 中文说明 | | --- | --- | | `source_event_index` | AI 拆分出的 current 事件序号,同一次来源消息内用于排序 | | `catalog_code` | Skill 目录代码,例如 S01、S02 | | `skill_id` | 具体 Skill 标识 | | `result_type` | AI 结果类型,第一版只使用 `normal_task`、`manual_review`、`informational_message` | | `task_type` | AI 原始任务类型,例如 `New Booking`、`Voucher Received` | | `task_subtype` / 业务动作 | 更细的业务动作,用于任务卡字段路由 | | `current_or_history` | 当前事件还是历史证据 | | `case_keys` | 订单关联候选键,例如 `group_code`、`confirmation_number` | | `visible_reason` | 给用户看的生成原因 | | `relevant_message_excerpt` | 相关邮件片段 | | `attachments` / `file_references` | 附件和文件引用 | | `context_used` | AI 使用的上下文摘要 | | `extracted_fields` | 业务字段主体 | | `manual_review` | 人工复核结构化原因和证据 | | `informational_message` | 信息提醒内容 | | `additional_operations` | AI 建议的附加动作 | | `idempotency_key` | 幂等键,最终来源和生成规则待确认 | HTTP 契约已在 `docs/project/requirements/M002-superagent-task-result-api-contract.md` 和 `docs/project/integrations/superagent-api-contract.md` 中补充。正式契约要求任务结果通知携带 `hotel_id + source_message_id`,其中 `source_message_id` 是外部来源消息 ID;后端会反查内部 SourceMessage Inbox ID 后再写入 `workflow_*` 表。 ## 6. AI 过渡层数据要求 系统接收 AI 输出后,应先写入 AI 过渡层,再创建任务卡。过渡层用于追溯、幂等、筛选、人工确认和 OPERA 参数组装。 推荐保存完整 JSON: | JSON 字段 | 中文说明 | | --- | --- | | `ai_payload_json` | AI 原始结果,禁止被用户编辑覆盖 | | `case_keys_json` | AI 给出的订单关联候选键 | | `extracted_fields_json` | AI 抽取的业务字段 | | `manual_review_json` | 人工复核信息 | | `informational_message_json` | 信息提醒内容 | | `attachments_json` | 附件和文件引用 | | `context_used_json` | AI 使用的上下文 | | `confirmed_payload_json` | 用户修改并确认后的最终参数 | 推荐冗余物理列: | 物理列 | 中文说明 | | --- | --- | | `source_message_id` | 内部 SourceMessage Inbox ID,来自外部 `source_message_id` 反查后的 `platform_source_message_inbox.id` | | `source_event_index` | AI 事件序号 | | `catalog_code` | Skill 目录代码 | | `skill_id` | Skill 标识 | | `result_type` | AI 结果类型 | | `ai_task_type` | AI 原始任务类型 | | `system_task_type` | 系统主任务类型 | | `task_card_type` | 任务卡类型 | | `task_subtype` | 业务动作 subtype | | `current_or_history` | 当前或历史标识 | | `group_code` | 冗余的 Group Code 候选 | | `confirmation_number` | 冗余的 Confirmation Number 候选 | | `idempotency_key` | 幂等键 | | `manual_reason_code` | 人工复核原因码 | | `parent_source_event_index` | 父任务事件序号 | | `linked_task_group_id` | 联动任务组 ID | | `blocked_until_parent_completed` | 是否等待父任务完成 | | `execution_order` | 同订单下执行顺序 | | `created_at` / `updated_at` | 创建和更新时间 | 不要把所有嵌套字段都建成物理列。只有高频查询、筛选、幂等、排序、队列控制和状态机需要的字段才冗余。 ## 7. 任务分类模型 ### 7.1 AI 结果类型 AI 第一版结果类型只接受: | `result_type` | 中文说明 | 是否可直接 OPERA 模拟 | | --- | --- | --- | | `normal_task` | 可生成业务任务卡的正常任务 | 需用户确认后才允许 | | `manual_review` | 需要人工复核的结构化任务 | 不允许直接写 OPERA | | `informational_message` | 只读信息提醒 | 不允许写 OPERA | 不使用 `exception_task` 和 `no_action`。原来讨论中的异常任务,在本版统一落为 `manual_review`;没有业务动作的信息提醒,统一落为 `informational_message`。 ### 7.2 系统主任务类型 系统内部主任务类型建议为: | 系统主任务类型 | 中文说明 | | --- | --- | | `NEW_BOOKING` | 新建订单任务 | | `UPDATE_BOOKING` | 更新订单任务,下面承载多个不同任务卡 | | `CANCEL_BOOKING` | 取消订单任务 | | `MANUAL_REVIEW` | 人工复核或 Fallback 任务 | | `INFORMATIONAL_MESSAGE` | 信息提醒任务,只归档展示,不参与执行队列 | ### 7.3 AI 任务类型到系统任务和卡片的映射 | AI `task_type` | 系统主任务类型 | 任务卡类型 | 说明 | | --- | --- | --- | --- | | `New Booking` | `NEW_BOOKING` | `NEW_BOOKING` | 新建 FIT、Group Block、Allotment / Control Block | | `Update Booking` | `UPDATE_BOOKING` | `UPDATE_BOOKING` | 通用订单修改卡 | | `Voucher Received` | `UPDATE_BOOKING` | `VOUCHER_RECEIVED` | 凭证类更新卡 | | `Rooming List` | `UPDATE_BOOKING` | `ROOMING_LIST` | 名单/分房表处理卡 | | `Amend Group Code` | `UPDATE_BOOKING` | `AMEND_GROUP_CODE` | 修改 Group Code 卡 | | `Trace / Reservation Notes` | `UPDATE_BOOKING` | `TRACE_RESERVATION_NOTES` | Trace 或备注卡,可作为联动任务 | | `TA Recorder` | `UPDATE_BOOKING` | `TA_RECORDER` | TA Recorder 维护卡,通常由 Rooming List 派生 | | `Cancel Booking` | `CANCEL_BOOKING` | `CANCEL_BOOKING` | 取消 FIT、Group Block、Allotment / Control Block | | `Message Notification` | `INFORMATIONAL_MESSAGE` | `MESSAGE_NOTIFICATION` | 挂临时订单,只读展示,不参与执行队列 | | `Fallback` | `MANUAL_REVIEW` | `FALLBACK_REVIEW` | 人工复核任务 | 系统不得丢弃 AI 原始 `task_type`。任务落库时应同时保存 AI 原始任务类型、系统主任务类型、任务卡类型和业务动作 subtype。 ## 8. Message Notification 处理规则 `Message Notification` 用于感谢、知会、已收到、转发说明、信息同步等没有明确业务执行动作的消息。 本系统处理规则: - 创建临时订单作为归档容器。 - 创建只读信息提醒任务卡。 - 不参与订单任务执行队列。 - 不阻塞同订单其他可执行任务。 - 不被同订单其他可执行任务阻塞。 - 不允许编辑业务字段。 - 不允许确认后执行 OPERA 模拟。 - 可在详情页展示 `visible_reason`、`relevant_message_excerpt`、`attachments` 和 `informational_message`。 ## 9. 任务卡字段约束 任务卡字段来源按职责拆分: - 后端校验、确认写入、OPERA 映射和展示条件以 `docs/import/20260706/任务卡展示编辑矩阵.xlsx` 为权威来源。 - 前端展示 / 编辑白名单以 `docs/import/20260708/任务卡前端展示字段表 3.0.xlsx` 为准。 - 系统不得直接把整个 `ai_task_results[]` 渲染成表单,也不得绕过矩阵自行扩展字段含义。 - 如果后端完整规则与前端白名单出现冲突,例如旧矩阵要求必填但 3.0 白名单未开放展示或编辑,应先记录为前后端契约待确认问题,不由前端或后端单方面放宽规则。 字段矩阵通过以下列控制任务详情页行为: | 列 | 中文说明 | | --- | --- | | `任务卡名称` | 前端任务卡名称 | | `result_type` | 适用的 AI 结果类型 | | `task_type` | 适用的 AI 原始任务类型 | | `task_subtype/业务动作` | 适用的业务动作 | | `字段路径` | 从 AI JSON 或确认 JSON 中取值的路径 | | `展示名` | 前端展示名称 | | `是否展示` | 是否在任务卡展示 | | `是否可编辑` | 用户是否可编辑 | | `是否为输入方式编辑` | 是否普通输入 | | `是否为下拉框方式编辑` | 是否下拉选择 | | `是否日期选择` | 是否日期控件 | | `是否数字输入` | 是否数字输入 | | `是否文件展示` | 是否文件或附件展示 | | `是否表格编辑` | 是否表格型编辑 | | `下拉选项/枚举值` | 可选值,系统不得自行扩展 | | `是否必填` | 用户确认前是否必填 | | `展示条件` | 字段显示条件 | | `校验规则` | 用户确认前校验规则 | | `确认后写入位置` | 写入 `confirmed_payload_json` 的位置 | | `是否参与Opera写入` | 是否允许进入 OPERA 参数 | | `Opera API参数映射` | OPERA 参数映射意图 | ### 9.1 关键卡片字段摘要 本节只摘录核心字段,完整字段以 Excel 矩阵为准。 | 任务卡 | 关键字段 | | --- | --- | | New Booking | `case_keys.group_code`、`case_keys.confirmation_number`、入住/离店日期、房量、房型原文、Opera 房型代码、Rate Code、结算价、Fix Charge、子团房量、表格行证据 | | Update Booking | `case_keys.group_code`、`case_keys.confirmation_number`、修改类型、修改前/后、Rate / 结算价结果、Fix Charge、表格行证据 | | Cancel Booking | `case_keys.group_code`、`case_keys.confirmation_number`、取消对象类型、取消范围、取消生效日期、取消备注 | | Voucher Received | 原始凭证、凭证类型、`case_keys.group_code`、确认后动作、凭证展示字段、部门流转、关联 Group Code | | Rooming List | 名单文件、名单类型、目标 Key、文件类型判断、附件 / Sheet 绑定、后续动作意图、派生任务候选 | | Amend Group Code | 旧 Group Code、新 Group Code | | Trace / Reservation Notes | `case_keys.group_code`、`case_keys.confirmation_number`、Trace 类型、通知部门、Trace Text、入住人数更新、改价公式、父任务事件序号 | | TA Recorder | Group Code、名单 / 分房附件、TA Recorder 状态、Rooming List 父任务 | | Message Notification | 生成原因、邮件片段、附件、信息提醒内容 | | Fallback / manual_review | 复核原因码、复核说明、复核记录类型、阻断点、缺失字段、冲突点、建议核对证据、建议人工动作、候选 Group Code、候选 Confirmation No. | ## 10. AI 原始值和人工确认值 AI 原始输出和用户确认值必须分离。 | 概念 | 中文说明 | | --- | --- | | `ai_payload_json` | AI 原始输出,作为证据和审计,不被用户编辑覆盖 | | `confirmed_payload_json` | 用户修改并确认后的最终业务参数 | 系统规则: - 任务详情首次展示可从 `ai_payload_json` 按矩阵字段路径取值。 - 用户编辑后必须写入 `confirmed_payload_json`。 - 用户确认前必须按矩阵和后端硬校验检查必填、类型、枚举和执行条件。 - OPERA 模拟只能从 `confirmed_payload_json` 取值。 - 不允许直接从 `ai_payload_json` 组装 OPERA 参数。 - 不允许因为用户修改而覆盖 AI 原始输出。 ## 11. 订单业务号和临时订单 系统不应只用一个含义模糊的“订单号”。建议至少区分: | 字段 | 中文说明 | | --- | --- | | `order_id` | 系统内部订单 ID,永远存在 | | `order_key_type` | 业务号类型,例如 `GROUP_CODE`、`CONFIRMATION_NUMBER`、`TEMPORARY` | | `order_business_key` | 真实业务号,例如 Group Code 或 Confirmation Number | | `temporary_order_code` | 临时订单展示编号 | ### 11.1 可作为订单业务号候选的字段 订单业务号候选字段包括: | 字段路径 | 适用场景 | 中文说明 | | --- | --- | --- | | `case_keys.group_code` | Group / Block / Allotment 类任务 | 主要 Group Code 候选 | | `case_keys.confirmation_number` | FIT Reservation 类任务 | 主要 Confirmation Number 候选 | | `extracted_fields.old_group_code` | Amend Group Code | 定位原订单 | | `extracted_fields.new_group_code` | Amend Group Code | 修改成功后的新业务号候选 | | `extracted_fields.group_code` | TA Recorder 等卡片 | 任务卡内 Group Code 候选 | | `extracted_fields.target_key` | Rooming List | 目标 Key,需要判断实际是 Group Code 还是 Confirmation Number | | `related_group_codes[]` | Voucher 等场景 | 关联展示或候选,不应自动作为唯一主订单号 | 系统匹配订单时应优先使用用户确认后的 `confirmed_payload_json`;如果尚未确认,只能把 AI 字段作为候选和展示依据。 ### 11.2 New Booking 的订单号处理 `NEW_BOOKING` 不一定都需要等待 OPERA 模拟创建后才有真实业务号。 规则: - 如果用户确认后的 payload 已有可用业务号,优先使用该业务号。 - FIT Reservation 优先看 `confirmation_number`。 - Group / Block / Allotment 优先看 `group_code`。 - 如果确认后的 payload 没有可用业务号,先创建临时订单并使用 `temporary_order_code` 展示和追踪。 - OPERA 模拟创建成功后,如果结果中返回真实业务号,再回填订单业务号。 - 第一版尚未实现确认 payload 时,Fallback 转 `NEW_BOOKING` 可先读取 AI 原始 `case_keys.group_code` / `case_keys.confirmation_number` 作为 `AI_CANDIDATE`,用于把原临时订单激活为 ACTIVE;后续用户确认字段时再把来源升级为 `USER_CONFIRMED`。 ### 11.3 什么时候从 OPERA 模拟结果回填订单号 只有在 `NEW_BOOKING` 且确认后的 payload 没有可用业务号时,才需要从 OPERA 模拟结果回填订单号。 | 任务场景 | 回填业务含义 | | --- | --- | | New FIT Reservation | 从 OPERA 模拟结果中的 Confirmation No. / Reservation Confirmation Number 含义字段回填 | | New Group Block | 从 OPERA 模拟结果中的 Group Code / Block Code 含义字段回填 | | New Allotment / Control Block | 从 OPERA 模拟结果中的 Group Code / Block Code / Allotment Code 含义字段回填 | 当前导入文档没有定义 OPERA 模拟结果的 JSON 字段名,因此不能在需求中写死 `result.confirmationNumber`、`result.groupCode` 等具体路径。该字段名需要在 OPERA 模拟模块设计时另行确认。 ### 11.4 非 New Booking 的订单号规则 `UPDATE_BOOKING`、`CANCEL_BOOKING`、`Voucher Received`、`Rooming List`、`Trace / Reservation Notes`、`TA Recorder` 等任务,原则上不应依赖 OPERA 模拟结果生成订单号。 这些任务应先通过 `case_keys` 或对应卡片字段挂靠已有订单;如果无法自动归属,则创建或使用临时订单,并等待人工确认订单关系。 ## 12. 订单挂靠和临时订单 任务必须挂靠到订单下,便于详情查看、队列控制和审计。 | 场景 | 挂靠规则 | | --- | --- | | New Booking 有业务号 | 按确认后的业务号创建或匹配订单 | | New Booking 无业务号 | 创建临时订单 | | Update Booking 可匹配已有订单 | 挂靠已有订单 | | Update Booking 无法匹配订单 | 挂靠临时订单,等待人工确认 | | Cancel Booking 可匹配已有订单 | 挂靠已有订单 | | Cancel Booking 无法匹配订单 | 挂靠临时订单,等待人工确认 | | Fallback / manual_review | 先挂靠临时订单,人工处理时可转换类型和订单归属 | | Message Notification | 挂靠临时订单,只读归档 | 任务从临时订单迁移到已有订单时,必须记录审计。若原临时订单已无有效任务,应逻辑删除,并记录删除原因。 ## 13. 任务顺序和可处理状态 同一个订单下,任务必须按顺序处理。 排序依据: ```text order_id + execution_order ``` 同一次 AI 返回多个任务时: - 必须保留 `ai_task_results[]` 列表顺序。 - 可使用 `source_event_index`、`execution_order` 或批次内 item index 保存顺序。 - 不得只依赖创建时间,因为同批次任务创建时间可能完全一致。 处理规则: - 前置任务未完成时,后续任务只能查看。 - `FAILED` 视为当前前置任务已经结束,不阻塞后续任务;用户不能跳过失败的 OPERA 操作,但失败任务本身不再卡住后续任务查看和处理顺序。 - 后续任务不能编辑字段。 - 后续任务不能确认订单关系。 - 后续任务不能执行 OPERA 模拟。 - 后续任务不能重试 OPERA 模拟。 - `Message Notification` 不参与执行队列,不阻塞其他任务,也不被其他任务阻塞。 - 联动任务可通过 `parent_source_event_index`、`linked_task_group_id`、`blocked_until_parent_completed` 表达依赖。 ## 14. 人工复核和 Fallback `manual_review` 是结构化人工复核,不是空结果,也不是系统失败。 人工复核卡至少应展示: - `manual_review.reason_code` - `manual_review.visible_reason` - `manual_review.review_record_type` - `manual_review.blocking_points[]` - `manual_review.missing_fields[]` - `manual_review.conflicting_points[]` - `manual_review.evidence_to_check[]` - `manual_review.suggested_human_actions[]` Fallback 处理规则: - 创建 `MANUAL_REVIEW` 任务。 - 默认挂靠临时订单。 - 用户处理时可以选择转为 `NEW_BOOKING`、`UPDATE_BOOKING` 或 `CANCEL_BOOKING`。 - 转换时必须记录审计;原因字段第一版允许为空。 - 转为 `NEW_BOOKING` 时,临时订单可以继续保留;如果已有确认 payload 则优先使用确认业务号,第一版尚未实现确认 payload 时可先使用 AI 原始 `case_keys` 中的业务号候选。 - 转为 `UPDATE_BOOKING` 或 `CANCEL_BOOKING` 时,用户必须选择目标订单;任务迁移后原临时订单无有效任务时可逻辑删除。 - 类型转换、订单迁移和临时订单逻辑删除都必须记录审计。 ## 15. OPERA 模拟操作 当前阶段没有真实 OHIP / OPERA 接口,只做 OPERA 模拟操作。 允许进入 OPERA 模拟的前置条件: - `result_type = normal_task`。 - 当前任务是订单执行队列中可处理的任务。 - 用户已确认订单归属。 - 用户已确认字段,且系统已生成 `confirmed_payload_json`。 - 字段矩阵中 `是否参与Opera写入` 为 `是` 或满足 `条件参与`。 - 后端硬校验通过。 不允许进入 OPERA 模拟的场景: - `manual_review`。 - `informational_message`。 - 未确认的 AI 原始值。 - 证据字段、只读字段、历史字段、uncertain 字段。 - S04 的 `voucher_display_fields` 等展示字段。 - 字段矩阵明确 `是否参与Opera写入=否` 的字段。 一个任务可能产生多条 OPERA 模拟操作。任务详情页应展示每条模拟操作的结果、状态、失败原因、重试次数和最近执行时间。重试必须保留历史记录,不能覆盖原始失败记录。 第一版后端实现中,任务最终确认后固定生成两条 OPERA 模拟操作: | 顺序 | 操作代码 | 中文说明 | | --- | --- | --- | | 1 | `SIMULATE_PRECHECK` | OPERA 模拟预检查 | | 2 | `SIMULATE_WRITE` | OPERA 模拟写入 | 当前模拟操作只保存请求/响应摘要和 attempt 记录,不接真实 OPERA,也不从模拟结果回填订单业务号。失败时只把对应操作标记为 `FAILED`,任务保持未完成,避免用户绕过失败操作。 ## 16. 审计要求 以下行为必须记录审计: - AI 结果接收批次。 - `ai_task_results[]` 中每个 item 的创建顺序。 - AI 原始 JSON 保存。 - 订单自动挂靠或临时订单创建。 - 用户修改任务字段。 - 用户确认订单关系。 - `confirmed_payload_json` 生成。 - 任务类型转换。 - 任务切换订单。 - 临时订单逻辑删除。 - OPERA 模拟操作执行。 - OPERA 模拟操作重试。 - 从 OPERA 模拟结果回填订单业务号。 审计至少包含: | 字段 | 中文说明 | | --- | --- | | `actor` | 操作人或系统调用方 | | `action` | 操作类型 | | `reason` | 用户填写或系统记录的原因 | | `before_snapshot` | 变更前摘要 | | `after_snapshot` | 变更后摘要 | | `occurred_at` | 发生时间 | 审计中不得记录 Secret、Token、完整邮件正文、真实附件 URL 或不必要的个人敏感信息。 ## 17. 暂不包含范围 本版暂不定义: - SuperAgent 查询上下文接口 3、4;接口 1、2 的第一版最小字段已单独定义并落地在 `M002-ai-query-minimal-fields.md`。 - OPERA 模拟结果 JSON 字段名。 - 真实 OHIP / OPERA 接口地址、鉴权和返回结构。 - 前端具体页面布局和交互细节。 - 全量 158 条任务卡字段配置复制版。 - Rate Code 和房型规则的代码实现。 - 普通任务切换订单接口和前端交互。 - 用户身份、权限和真实 actor 注入。 ## 18. 待确认问题 - SuperAgent 创建任务接口的 URL、Method、Header、鉴权和错误响应格式。 - SuperAgent 查询上下文接口 1、2 已实现最小字段版,并已启用与任务结果接收接口一致的 HMAC;接口 3 文件解析和接口 4 订单及任务查询仍需后续确认与实现,后续梳理未完成事项时必须持续提醒。 - SuperAgent 任务结果通知中的 `source_message_id` 已确认是外部来源消息 ID,对应 AgentBus `source.external_message_id`;查询接口中的 `source_message_id` 和 `source_event_index` 第一版接收但忽略。 - `source_event_index`、批次 item index、`execution_order` 的最终编号规则是否都从 1 开始。 - SuperAgent 查询上下文接口 3、4 的 URL、入参、返回字段和鉴权方式。 - `Message Notification` 是否需要在前端订单列表上单独标识为只读提醒。 - OPERA 模拟结果中 Confirmation No.、Group Code、Block Code、Allotment Code 的具体字段路径。 - 临时订单在无任务后是否立即逻辑删除,还是保留一段时间便于追溯。 - 普通任务切换订单接口何时纳入实现。 - 用户身份和权限体系何时接入,审计 `actor` 如何从登录态获取。 ## 19. 后续建议 checkpoint 建议后续按以下顺序拆分: 1. 定义 SuperAgent 调本系统的任务结果接收接口契约。 2. 定义 AI 过渡层、订单、任务、任务卡、审计、OPERA 模拟结果的最小数据模型。 3. 定义系统主任务类型、任务卡类型、`result_type`、任务状态和订单状态枚举。 4. 实现 AI 结果接收、幂等、顺序保存和任务卡创建。 5. 实现订单自动挂靠、临时订单创建和人工订单切换。 6. 实现任务详情字段展示、编辑、确认和 `confirmed_payload_json`。当前后端已实现保存草稿和最终确认接口,前端页面待定。 7. 实现任务队列阻塞规则和 `Message Notification` 只读归档规则。当前后端已实现阻塞规则和只读提醒归档的基础能力,前端页面待定。 8. 实现 OPERA 模拟操作结果底表、重试和订单业务号回填。当前后端已实现固定两条模拟操作、attempt、执行、重试和审计列表;订单业务号回填待真实 OPERA 返回结构确认后再做。 9. 根据前端页面范围实现列表、详情和只读/可处理状态展示。当前后端已实现 `GET /api/reservation/tasks` 和 `GET /api/reservation/orders/{orderId}` 第一版;前端页面和订单列表、Message Notification 独立列表 / 详情、任务卡字段白名单元数据接口仍待后续确认。