diff --git a/CONTEXT.md b/CONTEXT.md index b9ec257..b019944 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -43,6 +43,8 @@ TH Hotel Simple 是一个前后端分离的酒店业务协同项目。 - SourceMessage:外部消息来源事实,当前主要承接 AgentBus 邮件 JSON。 - Email / Message Conversation:邮件和邮件会话,用于历史邮件查询、正文读取和会话级任务查询。 - Reservation Case / Task:预订相关订单、任务卡、人工复核和任务结果。 +- Reservation Order Task / Card:M002 V4 后续采用的订单任务与多卡模型;一封来源邮件可按 `order_ref` 形成多个订单任务,每个订单任务下包含来源邮件展示卡、Basic Information 卡和若干业务卡。 +- Source Message Notification:M002 V4 的 S10 纯通知模型;只表示来源邮件需要被查看和确认已处理,不形成订单任务或业务卡。 - Identity / Access / Hotel / Menu:登录、用户、角色、权限、酒店授权和动态菜单底座。 - Debug EML:受控调试入口,用于上传 EML 并触发 SuperAgent 调试链路。 - Manual Invoice:手工开票生成能力,包含 Excel 模板、PDF 转换和 OSS 输出。 diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 05c2cff..7a0929a 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -4,21 +4,21 @@ | --- | --- | | 最近更新 | 2026-07-18 | | 当前分支 | `feature/huangting` | -| 当前阶段 | M002 V4 入站基线与业务能力迭代并行 | -| 当前重点 | SuperAgent V4 回调入站解析修正版、现有任务链路过渡适配和后续 V4 多卡模型规划 | +| 当前阶段 | M002 V4 入站基线与多卡模型设计并行 | +| 当前重点 | M002 V4 CP2 订单任务与多卡领域模型设计决策已闭合,后续准备进入 V4 表结构和 Repository 落地 | ## 1. 当前 Checkpoint -- 名称:`M002-V4-CP1-agent-callback-intake-baseline` -- 状态:Done,已完成后端入站解析基线、review 修复、测试和文档同步。 -- 目标:按 2026-07-18 V4 Agent 回调字段契约接收 `source_message + order_contexts[] + message_events[]`,完成入站解析、基础校验、路由适配和 adapter error 最小落库。 -- 边界:不做完整 V4 多卡领域模型、不做 OPERA / OHIP、不做前端页面、不做历史数据迁移。 +- 名称:`M002-V4-CP2-order-task-card-domain-model` +- 状态:Done,已完成设计文档并补齐 7 项业务决策,尚未写 Java、Flyway、接口或前端代码。 +- 目标:在 CP1 入站解析基线之后,明确 V4 订单任务、SourceMessage 邮件展示卡、Basic Information 独立卡、业务卡、状态、表结构草案、接口草案和后续开发 checkpoint。 +- 边界:只做文档设计;不做 OPERA / OHIP、不做前端页面、不做历史数据迁移。 ## 2. 当前优先级 1. 先把 AI-NSES 的入口文档落地,让新 Agent 不依赖聊天记录也能理解项目。 2. 保持 `docs/project/README.md`、`CONTEXT.md`、`PROJECT_STATE.md` 三个入口之间一致。 -3. 后续开发继续以当前有效的 M002 V4 字段契约、M002 V3 / P0.1 历史实现说明、字段控件契约、SuperAgent 契约和安全边界文档为准。 +3. 后续开发继续以当前有效的 M002 V4 字段契约、M002 V4 CP2 多卡模型设计、M002 V3 / P0.1 历史实现说明、字段控件契约、SuperAgent 契约和安全边界文档为准。 ## 3. 已确认事实 @@ -34,11 +34,12 @@ - `docs/import/` 下按日期导入的资料是输入材料,不等同于当前权威开发契约;当前开发应优先看 `docs/project/README.md` 标记为当前有效或权威契约的文档。 - 后续每完成一个 Feature 或 Checkpoint,需要更新本文件,避免项目状态继续沉淀在聊天记录里。 - M010 Rooming List Excel 生成后端 CP1 和前端 V1 已实现:前端 `/reservation/rooming-lists/new` 上传来源名单和手工字段,后端同步生成 `.xlsx` 直接下载,第一版不落库、不上传 OSS。 -- M002 V4 CP1 当前已完成入站解析和现有任务链路过渡适配;Basic Information 独立卡、V4 订单任务多卡模型和 V4 前端页面仍未完成。 +- M002 V4 CP1 当前已完成入站解析和现有任务链路过渡适配;M002 V4 CP2 已完成订单任务与多卡领域模型设计。Basic Information 独立卡、V4 订单任务多卡表结构、查询 / 写接口和 V4 前端页面仍未完成代码实现。 +- M002 V4 CP2 已确认:V4 工作台统一列表草案为 `/api/reservation/workbench-items`,业务订单任务接口新开 `/api/reservation/order-tasks/**`,S10 来源通知详情草案为 `/api/reservation/source-notifications/{notificationId}`;S10 使用来源通知模型,不再挂隐藏技术订单;`FIT + BOOKING_CODE` 不建 ACTIVE 唯一约束,匹配多条进人工复核;Basic Information 必须先确认;Account / Market / Source 第一版使用固定种子数据;旧 V2/V3 任务详情和草稿确认接口后续可逐步废弃。 ## 5. Next Steps -- 后续如继续做 M002 V4,应优先规划订单任务 + 多卡领域模型、Basic Information 独立卡、前端 V4 页面模型和目录校验能力。 +- 后续如继续做 M002 V4,应优先进入 `M002-V4-CP3`:新增 V4 订单任务表、V4 任务卡表、V4 来源通知表、Entity、Mapper、Repository 和基础测试。 - 后续新增重要功能时,优先在 `docs/project/requirements/` 或未来 `docs/specs/` 中形成 Spec,再实现代码。 - M010 后续如需预览、历史记录、OSS 下载、订单 / 任务预填或客户字段目录化,再单独开前后端 checkpoint。 diff --git a/docs/project/README.md b/docs/project/README.md index e10d4be..3d8fa68 100644 --- a/docs/project/README.md +++ b/docs/project/README.md @@ -46,6 +46,7 @@ | `requirements/M002-order-task-workflow-v3.md` | 当前有效 | M002 订单任务主流程 V3,基于 2026-07-11 P0 冻结基线和 2026-07-12 P0.1 Parent Group 修订,记录 S10/S99、40 路由、方案 C、type-known manual review 同卡解阻和 fail-closed 边界。 | | `requirements/M002-task-field-control-contract-v1.md` | 当前有效 | M002 任务卡字段控件契约 V1,记录任务详情 `fields[]` 控件元数据、人工复核控件复用和前后端开发边界。 | | `requirements/M002-v4-agent-callback-field-contract.md` | 当前有效 | M002 V4 Agent 回调字段契约,基于 2026-07-18 业务基线和最新答复,冻结 `source_message`、`order_contexts`、`message_events`、订单级 Basic Information、六类 Event、S10 和校验口径;后端已完成 V4 入站解析 CP1,完整 V4 多卡主流程仍待后续实现。 | +| `requirements/M002-v4-order-task-card-domain-model-cp2.md` | 当前有效 | M002 V4 CP2 订单任务与多卡领域模型设计,记录 SourceMessage 展示卡、来源通知模型、订单任务、Basic Information 卡、业务卡、状态、表设计草案、已确认业务决策和后续开发 checkpoint。 | | `requirements/M002-superagent-task-result-api-contract.md` | 阶段记录 | M002 SuperAgent 任务结果入站接口契约阶段记录;对外总契约以 `integrations/superagent-api-contract.md` 为准。 | | `requirements/M002-ai-query-minimal-fields.md` | 阶段记录 | M002 SuperAgent 查询上下文接口 1、2 最小字段落地记录;对外总契约以 `integrations/superagent-api-contract.md` 为准。 | | `requirements/M002-backend-data-model-design.md` | 阶段记录 | M002 后端数据模型设计,记录 AI 过渡层、订单、任务、任务卡、审计和 OPERA 模拟结果表。 | @@ -90,6 +91,6 @@ - 接口暴露、权限、酒店隔离和审计边界以 `security-access-control-boundary.md` 为总检查清单;具体 SuperAgent / MCP / AgentBus 请求响应契约仍以 `integrations/` 下对应文档为准。 - AI-NSES 的通用标准以 `../import/reusable/ai-native-software-engineering-standard.md` 为复用来源;本项目采用方式以 `ai-native-adoption.md` 为准。 - M002 V1 只作为历史参考;V2 记录当前阶段实现;后续 M002 新开发以 `requirements/M002-order-task-workflow-v3.md` 为开发基线。 -- 2026-07-18 导入的业务基线已形成 `requirements/M002-v4-agent-callback-field-contract.md` 字段契约;M002 V4 入站解析 CP1 已落地,V4 订单任务 + 多卡领域模型、前端页面模型和完整主流程仍需继续形成 checkpoint。 +- 2026-07-18 导入的业务基线已形成 `requirements/M002-v4-agent-callback-field-contract.md` 字段契约;M002 V4 入站解析 CP1 已落地,V4 订单任务 + 多卡领域模型设计和关键业务决策见 `requirements/M002-v4-order-task-card-domain-model-cp2.md`,后续仍需实现表结构、入站落库、查询接口、卡片确认 / 复核和前端页面模型。 - 前端展示 / 编辑字段以 2026-07-11 P0 冻结基线中的前端字段表、0712 字段控件说明和 `requirements/M002-task-field-control-contract-v1.md` 为白名单和控件契约基线;后端完整校验和 OPERA 映射仍以任务卡完整矩阵、0711 runtime 契约和后端规则为准。 - 时间点语义以 `backend-time-design.md` 为准;数据库时间点按 UTC 理解,API 返回带 `Z` 的 UTC 时间,页面再按酒店或用户时区展示。 diff --git a/docs/project/frontend-backend/backend-to-frontend-notes.md b/docs/project/frontend-backend/backend-to-frontend-notes.md index 2ef4fd6..864c53e 100644 --- a/docs/project/frontend-backend/backend-to-frontend-notes.md +++ b/docs/project/frontend-backend/backend-to-frontend-notes.md @@ -150,7 +150,7 @@ POST /api/auth/logout - `next_processable_task_id` 是后端按同订单队列实时计算出的下一条可处理任务;前端可以用它做“继续处理”入口。 - `display_order_key` 是前端优先展示的订单业务号或临时订单号;`group_code` 和 `confirmation_number` 只有在当前订单业务号类型匹配时返回。 - 订单 ID、任务 ID、SourceMessage ID 在这些前端接口中按字符串返回,前端不要转换成 JavaScript number。 -- 源邮件只读通知卡背后有隐藏技术订单用于满足后端任务外键,但订单列表不会返回该订单;任务列表中该类任务的 `display_order_key`、`temporary_order_no`、`group_code`、`confirmation_number` 可能为空,前端不要因此隐藏整条任务。 +- 当前 V3 / 过渡实现中,源邮件只读通知卡背后有隐藏技术订单用于满足后端任务外键,但订单列表不会返回该订单;任务列表中该类任务的 `display_order_key`、`temporary_order_no`、`group_code`、`confirmation_number` 可能为空,前端不要因此隐藏整条任务。V4 S10 目标模型已改为独立来源通知,不再挂隐藏技术订单。 - 当前前端已按 `SOURCE_MESSAGE_ONLY` 展示旧 S000/S999;后端回调已支持结构化 `route_code=S10/S99`、`result_type=source_message_review_notification` 的新入口通知,并继续只在任务列表和任务详情提供只读查看入口;`INFORMATIONAL_MESSAGE` 仅作为历史 Message Notification 兼容路径保留。 - 任务列表里旧 `task_type=SOURCE_MESSAGE_ONLY`、`task_subtype=S000/S999` 或新 `task_subtype=S10/S99` 的记录只展示邮件来源和 SuperAgent 入口结果,不展示处理按钮。 - 任务详情里 `source_message_only_result` 仅对 `SOURCE_MESSAGE_ONLY` 返回,包含 `entry_result_code`、`entry_result_meaning`、`entry_result_description`、`entry_result_source_message_id`、`result_type`、`route_code`、`agent_assessment`、`notification`、`manual_review` 和 `raw_answer`;普通业务任务该字段为空。 @@ -457,6 +457,9 @@ RESERVATION_ROOMING_LIST_GENERATE - 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[]` 只读诊断块中,不展示保存、确认、执行或重试按钮。 - V4 包级契约错误只会保存在 AI transition 中,不会出现在普通任务列表;V4 event 级契约错误如果同批次存在其它业务任务,前端仍按任务详情里的 `adapter_contract_errors[]` 只读展示诊断信息。 +- M002 V4 CP2 订单任务与多卡领域模型设计已落到 `docs/project/requirements/M002-v4-order-task-card-domain-model-cp2.md`:后续前端 V4 页面应围绕 `order_task + source_message_card + basic_information_card + business_cards[]` 设计;V4 工作台统一列表草案为 `GET /api/reservation/workbench-items`,业务订单任务草案为 `/api/reservation/order-tasks/**`,S10 来源通知详情草案为 `GET /api/reservation/source-notifications/{notificationId}`,但当前还没有实现,不要提前接入草案路径。 +- V4 新模型确认口径是不保存后端草稿、卡片最终确认后锁定、技术异常不进入用户可处理卡、当前不生成 OPERA 模拟操作。Basic Information 必须先确认;其它业务卡第一版不强制逐张顺序确认。现有 V3 `draft`、`confirm`、`manual-review-resolutions` 和 OPERA 模拟接口仍只代表旧链路能力,不能直接等同 V4 多卡最终接口。 +- V4 S10 后续采用来源通知模型:任务列表 / 工作台展示,进入纯通知详情页后只显示邮件展示卡和确认按钮;不再挂隐藏技术订单,不创建订单、不进订单列表、不参与订单阻塞,也不支持编辑、复核、OPERA 或人工终止。当前代码里旧 `SOURCE_MESSAGE_ONLY` 只读任务仍属于过渡实现。 - M002 V3 的结构化 `S10/S99` 入站、40 条 P0.1 路由枚举 / 稳定配置、`UNHANDLED_CURRENT_INTENT`、`adapter_contract_error` transition 最小落库、任务列表 / 订单时间线 / 任务详情 V3 路由字段和只读诊断块透出、type-known manual review 同卡解阻第一版、typed infrastructure error、P0 fixtures 回归基线和 Parent Group / Cancel Allotment 路由修订均已完成。 - 系统管理后台 V1 已完成;后续若要做用户搜索更多筛选、批量操作、密码策略增强、MFA、登录设备管理,应单独开需求。 - 现有 Reservation / SourceMessage 业务接口的强制登录、强制权限和业务审计 actor 全量迁移仍后置。 diff --git a/docs/project/requirements/M002-order-task-workflow-v3.md b/docs/project/requirements/M002-order-task-workflow-v3.md index 91c38ce..6ebcc17 100644 --- a/docs/project/requirements/M002-order-task-workflow-v3.md +++ b/docs/project/requirements/M002-order-task-workflow-v3.md @@ -4,9 +4,9 @@ | 项目 | 内容 | | --- | --- | -| 文档版本 | 0.3 | -| 日期 | 2026-07-13 | -| 状态 | 0712 P0.1 增量确认版;已完成任务卡字段控件契约 V1 后端第一版 | +| 文档版本 | 0.4 | +| 日期 | 2026-07-18 | +| 状态 | 0712 P0.1 增量确认版;已补充 M002 V4 CP1 入站现状和 CP2 多卡模型设计入口 | | 适用范围 | SourceMessage 之后的 SuperAgent 输出适配、任务路由、只读通知卡、人工复核同卡解阻、前后端协作边界 | | 主要读者 | 产品、后端、前端、测试、SuperAgent 对接方、后续协作 agent | @@ -42,7 +42,7 @@ V3 以以下资料和决策为输入: - M002 V3 正式采用 0711 P0 基线,并从 2026-07-12 起采用 P0.1 Parent Group / Allotment 增量修订。 - 旧数据 `S000/S999` 继续在任务列表可见;新数据迁移为 `S10/S99`。 -- `S10/S99` 继续复用隐藏技术订单 + 任务列表只读卡,不进入订单列表和订单执行队列。 +- M002 V3 / P0.1 阶段 `S10/S99` 继续复用隐藏技术订单 + 任务列表只读卡,不进入订单列表和订单执行队列;M002 V4 新模型已确认 S10 改为来源通知模型,不再挂隐藏技术订单。 - 缺少 `source_message.source_message_id` 时,后端已按 `HTTP 400 + infrastructure_input_error + retryable=true` 的技术错误响应返回,不创建 SourceMessage、AI transition、订单、任务或通知卡。 - 内部任务模型采用“方案 C”:完整保存 AI 三元组,系统处理分类和前端展示分类单独维护。 - type-known manual review 使用同一张业务卡复核解阻,不生成第二张 normal task。 @@ -152,6 +152,8 @@ V3 接收端按根结构分流: - 不允许保存草稿、最终确认、复核转换、普通切换订单、执行 OPERA、重试 OPERA。 - 任务详情展示来源邮件、邮件会话、附件、SuperAgent 原始返回、`route_code` 和入口说明。 +以上是 M002 V3 / P0.1 当前实现口径。M002 V4 新模型落地时,S10 改为来源通知模型:任务列表 / 工作台展示,点击进入纯通知详情页,只显示邮件展示卡和确认按钮;不创建订单、不进订单列表、不参与订单阻塞,也不支持编辑、复核、OPERA 或人工终止。 + ### 6.3 旧 S000 / S999 兼容 旧数据 `S000/S999` 已经在系统中以只读特殊任务展示。V3 不删除旧数据,也不要求历史回写。 @@ -248,7 +250,7 @@ V3 内部模型采用方案 C,避免把 SuperAgent 的任务三元组直接等 - 有 `group_code`、`confirmation_number` 等可定位字段时,优先挂靠或创建相应订单。 - 同一个 `hotel_id + GROUP_CODE` 只能有一个 `ACTIVE` 订单。 - 同一个 `hotel_id + CONFIRMATION_NUMBER` 只能有一个 `ACTIVE` 订单。 -- `S10/S99` 使用隐藏技术订单,不进入订单列表。 +- M002 V3 / P0.1 当前实现中,`S10/S99` 使用隐藏技术订单,不进入订单列表;M002 V4 S10 目标模型改为独立来源通知,不再挂订单。 P0 新增明确:复核场景下需要支持用户确认订单归属。它不是普通任务切换订单: @@ -467,8 +469,17 @@ V3 P0.1 不做以下事项: - MCP submit V2 兼容路径已在 `tools/list` 暴露 `ai_task_results[]` item schema,并在 adapter 层校验必填字段、字段类型、允许 `result_type` 和未知字段。 - MCP submit 对缺失 `source_message.source_message_id` 或整个 `source_message` 保留业务入站层 `MISSING_SOURCE_MESSAGE_ID` 错误语义;对 V3 event 业务契约问题不提前整批拒绝,由业务入站层保存 `adapter_contract_error` transition。 +M002 V4 CP2 设计文档已落地: + +- 文档路径:`docs/project/requirements/M002-v4-order-task-card-domain-model-cp2.md`。 +- 设计内容:SourceMessage 邮件展示卡、S10 来源通知、`source_message_id + order_ref` 订单任务、Basic Information 独立卡、每个 V4 event 的业务卡、卡片确认 / 复核 / 锁定、同订单阻塞、表结构草案和后续接口草案。 +- 已确认:V4 工作台统一列表新开 `/api/reservation/workbench-items`,业务订单任务新开 `/api/reservation/order-tasks/**`,S10 来源通知使用 `/api/reservation/source-notifications/**`;S10 采用来源通知模型;`FIT + BOOKING_CODE` 不建 ACTIVE 唯一约束,匹配多条进人工复核;Basic Information 必须先确认,其它业务卡第一版不强制逐张确认;Account / Market / Source 目录第一版使用后端固定种子数据。 +- 当前状态:只完成文档设计,未新增表、Entity、Repository、接口或前端页面。 + 仍需后续 checkpoint 实现: -- V4 订单任务 + 多卡领域模型重建,尤其是 Basic Information 订单级独立卡、邮件展示卡和各业务卡独立确认 / 锁定。 +- V4 表结构和 Repository 落地,包括 V4 订单任务表、V4 任务卡表和 V4 来源通知表。 +- V4 入站写入新模型,真正创建 SourceMessage 展示卡、Basic Information 卡和业务卡。 +- V4 查询接口、卡片确认 / 复核 / 锁定、同订单阻塞和业务审计。 - V4 前端页面模型、任务详情字段矩阵和目录校验完全切换。 - 真实 OPERA / OHIP、普通任务任意切换订单、字段矩阵从当前扁平结构整体迁移到 0711 P0 新结构、历史旧 Parent Cancel Booking payload 批量迁移。 diff --git a/docs/project/requirements/M002-v4-agent-callback-field-contract.md b/docs/project/requirements/M002-v4-agent-callback-field-contract.md index 2a9855a..b64e757 100644 --- a/docs/project/requirements/M002-v4-agent-callback-field-contract.md +++ b/docs/project/requirements/M002-v4-agent-callback-field-contract.md @@ -4,9 +4,9 @@ | 项目 | 内容 | | --- | --- | -| 文档版本 | 1.2 | +| 文档版本 | 1.4 | | 日期 | 2026-07-18 | -| 状态 | 当前 V4 字段基线;后端已完成 CP1 入站解析与数据模型基线,完整 V4 多卡模型仍需后续 checkpoint | +| 状态 | 当前 V4 字段基线;后端已完成 CP1 入站解析基线,CP2 订单任务与多卡领域模型设计及关键决策已落文档,完整 V4 多卡代码仍需后续 checkpoint | | 适用范围 | 0718 业务基线下,Agent → Adapter / MCP → 信息系统的业务回调字段 | | 不适用范围 | 数据库表设计、前端视觉细节、真实 PMS API、技术失败后台重试、旧 M002 V3 数据兼容 | @@ -16,6 +16,8 @@ 本契约用于后续 M002 V4 主流程设计、后端领域建模、前端页面模型、Adapter / MCP Schema 对齐和 SuperAgent 联调。当前后端已按本文完成 V4 入站解析基线:能识别 V4 包、校验关键契约、保存 AI transition / 任务卡原始 payload,并把可映射的六类 event 先接入现有订单任务链路。 +V4 订单任务与多卡领域模型的 CP2 设计已经单独落到 `M002-v4-order-task-card-domain-model-cp2.md`。该文档只代表后续开发方案,不代表表结构、接口或前端页面已经实现。 + 当前已确认开发阶段数据可以清空,因此 M002 V4 后续可以按新模型重建,不要求兼容旧任务数据、旧草稿、旧 OPERA 模拟、旧 `S000/S999`、旧 Fallback 或旧 `case_keys`。 ## 2. 输入资料与优先级 @@ -583,6 +585,8 @@ true - 只显示邮件展示卡。 - 不显示 Basic Information、房间信息或其他业务卡。 - 不需要 `order_ref`、`target_order`、Account 或业务字段。 +- 采用来源通知模型:任务列表 / 工作台展示,点击进入纯通知详情页,不挂隐藏技术订单。 +- 不创建订单、不进入订单列表、不参与订单阻塞,也不支持编辑、复核、OPERA 或人工终止。 - 用户点击“确认”后任务完成。 - 不提供人工终止。 - 不调用 PMS,不修改订单。 @@ -665,7 +669,10 @@ AI 回调包 | Payment 附件 | 正常 Payment 必须 `attachment_ids.length > 0` | | `manual_review` validator | 按各对象条件 Schema 校验,必须能由可识别未解决字段解释 | | Update room_items | 不存在 / `null` / 数组三态 | -| Fit Booking Code 临时定位 | 当前无 Confirmation Number 时可用 Booking Code 查本地订单投影 | +| Fit Booking Code 临时定位 | 当前无 Confirmation Number 时可用 Booking Code 查本地订单投影;第一版不建立 ACTIVE 唯一约束,匹配多条进入人工复核 | +| V4 前端资源路径 | 新开 `/api/reservation/order-tasks/**`,不扩展旧 `/api/reservation/tasks/**` 作为 V4 主入口 | +| Basic Information 前置 | Basic Information 必须先确认;业务卡之间第一版不强制逐张顺序确认 | +| Account 目录 | 第一版使用信息系统后端固定种子数据 | ## 23. 后续仍需技术对齐 @@ -682,6 +689,9 @@ AI 回调包 - 0718 业务基线覆盖 M002 V3 的任务级草稿、READY、OPERA 模拟、Fallback、S99 和旧 Need Manual Review 页面语义。 - 新数据只按 `S10` 表达纯通知。 - 用户可见任务按订单任务 + 多卡建模。 +- 普通业务邮件的来源邮件展示卡只读展示,不需要用户确认。 +- S10 因为没有业务卡,邮件展示卡需要确认按钮,用于记录已读 / 已处理。 +- Basic Information 必须先确认;其它业务卡第一版可以独立确认,不强制逐张顺序确认。 - 每张业务卡独立确认、确认后永久锁定。 - 不保存草稿。 - 当前无 PMS API,不生成 OPERA 模拟操作和 PMS 成功语义。 @@ -710,3 +720,21 @@ AI 回调包 - 尚未取消 V3 草稿 / OPERA 模拟骨架;现有可映射 event 仍复用 M002 V3 任务状态和任务卡创建链路。 - 尚未接入真实 PMS / OPERA / OHIP。 - 尚未改造前端 V4 页面模型;前端第一版只能通过现有任务详情字段和原始 payload 观察 V4 入站结果。 + +## 26. 后端 CP2 设计文档状态 + +2026-07-18 已新增 `M002-v4-order-task-card-domain-model-cp2.md`,明确以下后续开发方向: + +- 普通业务包按 `source_message_id + order_ref` 形成 V4 订单任务。 +- 普通业务包固定展示来源邮件卡,但该卡只读、不阻塞、不替代邮件会话接口。 +- 每个 `order_ref` 创建一张 Basic Information 卡。 +- 每个 `message_events[]` event 创建一张业务卡,卡片按固定业务顺序展示。 +- S10 后续按来源通知模型实现,不再挂隐藏技术订单;只在任务列表 / 工作台展示,并进入纯通知详情页确认已读 / 已处理。 +- `FIT + BOOKING_CODE` 不建立 ACTIVE 唯一约束;业务绑定查到多条时进入人工复核。 +- V4 前端工作台统一列表草案为 `/api/reservation/workbench-items`,业务订单任务接口新开 `/api/reservation/order-tasks/**`,S10 来源通知详情草案为 `/api/reservation/source-notifications/{notificationId}`。 +- V4 新数据不再保存后端草稿;用户只提交最终确认或复核解阻。 +- 卡片确认后锁定,错误修正后续通过审计和未来纠错流程表达,不覆盖原确认。 +- 技术异常只进入 AI transition / 技术运行记录,不进入用户可处理卡。 +- 后续建议新增 V4 订单任务表、V4 任务卡表和 V4 来源通知表,继续复用 SourceMessage、AI batch、AI transition、Reservation Order 和业务审计表。 + +CP2 尚未实现代码、接口、Flyway 或前端页面。后续开发应从 CP3 表结构和 Repository 开始。 diff --git a/docs/project/requirements/M002-v4-order-task-card-domain-model-cp2.md b/docs/project/requirements/M002-v4-order-task-card-domain-model-cp2.md new file mode 100644 index 0000000..0bcb6a6 --- /dev/null +++ b/docs/project/requirements/M002-v4-order-task-card-domain-model-cp2.md @@ -0,0 +1,677 @@ +# M002 V4 CP2 订单任务与多卡领域模型设计 + +## 文档信息 + +| 项目 | 内容 | +| --- | --- | +| 文档版本 | 0.1 | +| 日期 | 2026-07-18 | +| 状态 | CP2 设计文档,尚未写代码 | +| 适用范围 | M002 V4 入站后的订单任务、多卡、状态、查询和写操作设计 | +| 不适用范围 | Java 实现、Flyway migration、真实 PMS / OPERA / OHIP、前端页面视觉稿、历史数据迁移 | + +## 1. 文档定位 + +M002 V4 CP1 已完成 SuperAgent V4 回调包入站解析、基础校验、路由适配和 AI transition 最小落库。CP1 仍然把可映射的 V4 event 临时接入 M002 V3 的订单 / 任务 / 任务卡链路。 + +本文是 CP2 设计文档,用于把 2026-07-18 V4 字段契约落成后续可开发的数据模型和接口草案。本文只描述设计,不代表代码已经实现。 + +后续如本文与 `M002-v4-agent-callback-field-contract.md` 的字段契约冲突,以字段契约为准;如与安全边界冲突,以 `security-access-control-boundary.md` 为准。 + +## 2. CP1 已完成和 CP2 差距 + +| 主题 | CP1 当前实现 | V4 目标模型差距 | +| --- | --- | --- | +| 入站识别 | 已识别 `route_code`、`source_message`、`order_contexts[]`、`message_events[]` | 还没有把 `order_ref` 建成订单任务聚合 | +| SourceMessage | 已按 `source_message.source_message_id` 反查 SourceMessage Inbox | 还没有固定生成业务包内邮件展示卡 | +| Basic Information | 只保存在 `v4_order_context` 原始 payload 中 | 还没有作为每个 `order_ref` 的独立可确认、可锁定卡 | +| 业务 Event | 可映射 event 临时创建旧 `workflow_reservation_task` | 还没有一 event 一业务卡的 V4 多卡模型 | +| 技术错误 | 已落 `adapter_contract_error` transition | 已符合目标方向:不创建用户可处理卡 | +| 草稿 / READY / OPERA | 仍复用 V3 草稿、READY 和 OPERA 模拟骨架 | V4 新数据确认口径是不保存草稿、确认后锁定、当前不生成 OPERA | +| 前端查询 | 复用旧任务列表和任务详情 | 需要新订单任务详情接口返回邮件卡、Basic Information 卡和业务卡数组 | + +## 3. 领域词汇 + +| 术语 | 英文建议 | 中文含义 | +| --- | --- | --- | +| AI 回调包 | AI Callback Package | SuperAgent 对本系统提交的一次 V4 JSON 包,对应一个 SourceMessage 和一个 AI batch | +| 来源邮件展示卡 | Source Message Display Card | 由包级 `source_message` 固定生成的只读展示卡,用于查看当前邮件正文、附件和会话入口 | +| 订单任务 | Reservation Order Task | 同一 `source_message_id + order_ref` 在本系统内形成的业务处理聚合,不等同 PMS 订单,也不等同旧 `workflow_reservation_task` 单任务 | +| 本地订单投影 | Reservation Order Projection | 本系统保存的订单归属和业务号投影,当前主要复用 `workflow_reservation_order` | +| 任务卡 | Reservation Task Card | 订单任务下可独立确认、独立锁定的卡片,例如 Basic Information、房间信息、Trace、Rooming List、Payment | +| 技术失败记录 | Adapter / Technical Error | Agent / Adapter / MCP 契约或技术异常,只进入 AI transition 或技术运行记录,不进入用户可处理任务卡 | + +## 4. 核心关系 + +普通业务包: + +```text +source_message + -> 1 个来源邮件展示卡 + +order_contexts[] + -> 每个 order_ref 创建 1 个订单任务 + -> 每个订单任务创建 1 张 Basic Information 卡 + +message_events[] + -> 每个 event 按 order_ref 挂到对应订单任务 + -> 每个 event 创建 1 张业务任务卡 + +target_order + -> 用于订单任务绑定本地订单投影 +``` + +纯通知包 `route_code=S10`: + +```text +source_message + -> 只显示来源邮件通知卡 + -> 不创建订单任务 + -> 不创建 Basic Information 或业务卡 +``` + +技术异常: + +```text +V4 package / event contract error + -> workflow_reservation_ai_transition + -> system_process_category=ADAPTER_CONTRACT_ERROR + -> 不创建订单任务 + -> 不创建任务卡 +``` + +## 5. 卡片类型第一版 + +| 卡片类型 | 来源 | 是否用户可确认 | 是否可编辑 | 中文说明 | +| --- | --- | --- | --- | --- | +| `SOURCE_MESSAGE_DISPLAY` | `source_message` | 否 | 否 | 普通业务包内固定展示当前邮件和附件入口 | +| `SOURCE_MESSAGE_NOTIFICATION` | `route_code=S10` | 是,仅确认已读 | 否 | 纯通知邮件,只需要用户确认已读 / 已处理 | +| `BASIC_INFORMATION` | `order_contexts[].basic_information` | 是 | 是 | 订单级 Account / Market / Source 卡,第一版 Agent 只给 `account_code` | +| `ROOM_INFORMATION` | `NEW_BOOKING` / `UPDATE_BOOKING` / `CANCEL_BOOKING` | 是 | 是 | 房间信息卡,卡内根据 event_type 展示新建、修改或整单取消字段 | +| `TRACE_RESERVATION_NOTES` | `TRACE_RESERVATION_NOTES` | 是 | 是 | Trace 卡,卡内可有普通备注和加床备注多条事项 | +| `ROOMING_LIST` | `ROOMING_LIST` | 是 | 第一版可只读或确认 | 识别到 Rooming List 任务,不在 Agent 回调里保存名单 rows | +| `PAYMENT` | `PAYMENT` | 是 | 第一版主要确认附件关联 | 付款凭证卡,只按 `attachment_ids[]` 引用包级附件 | + +说明: + +- Basic Information 不是 event,但必须是独立任务卡。 +- 来源邮件展示卡不是 event,普通业务包内只读,不参与订单执行阻塞。 +- S10 采用来源通知模型:任务列表 / 工作台可见,点击进入纯通知详情页;只显示邮件展示卡和确认按钮,不创建订单、不进订单列表、不参与订单阻塞,也不支持编辑、复核、OPERA 或人工终止。 +- 同一 `order_ref` 下如果有多个相同 `event_type`,第一版按 event 数组项分别建卡;页面排序按固定卡片顺序,再按 `source_event_index` 排序。 + +## 6. 状态设计 + +### 6.1 订单任务状态 + +订单任务状态用于列表和页面入口,第一版按卡片状态派生,不允许用户直接编辑。为了便于列表查询,`order_task_status` 可以作为落库快照字段保存当前订单任务自身完成情况;同订单前置任务造成的阻塞不落入 `order_task_status`,而是在查询响应的 `availability` 中实时派生。 + +| 状态 | 中文含义 | 派生规则 | +| --- | --- | --- | +| `OPEN` | 仍有待处理卡 | 存在 `PENDING_CONFIRM` 或 `REVIEW_REQUIRED` 的可确认卡 | +| `COMPLETED` | 当前订单任务已完成 | 所有用户可确认卡均已 `CONFIRMED` | + +查询响应可以额外返回 `display_status=BLOCKED`,表示当前订单任务因同订单前置订单任务未完成、Basic Information 未确认或权限不足而只能查看;该值由查询服务实时计算。 + +技术错误不派生订单任务状态,因为技术错误不创建订单任务。 + +### 6.2 卡片状态 + +| 状态 | 中文含义 | 允许动作 | +| --- | --- | --- | +| `READONLY` | 只读卡 | 只能查看,例如普通业务包的来源邮件展示卡 | +| `PENDING_CONFIRM` | 待确认 | 若没有前置阻塞,允许提交最终确认 | +| `REVIEW_REQUIRED` | 待人工复核 | 若没有前置阻塞,允许提交复核修正并确认 | +| `CONFIRMED` | 已确认锁定 | 只能查看,不允许再次编辑或覆盖 | +| `ACK_REQUIRED` | 通知待确认 | 仅用于 S10 来源通知,落在 `workflow_reservation_v4_source_notification.notification_status` | +| `ACKED` | 通知已确认 | 仅用于 S10 来源通知,落在 `workflow_reservation_v4_source_notification.notification_status` | + +### 6.3 可操作性派生 + +接口响应应返回 `availability` 或等价字段,避免前端自己猜。 + +| 派生状态 | 中文含义 | +| --- | --- | +| `available=true` | 当前用户在权限、酒店、状态和阻塞规则下可以处理 | +| `blocked=true` | 当前卡只能查看 | +| `readonly_reason_code=PRIOR_CARD_NOT_CONFIRMED` | 同一订单任务内前置卡未确认 | +| `readonly_reason_code=PRIOR_ORDER_TASK_NOT_COMPLETED` | 同一本地订单下更早订单任务未完成 | +| `readonly_reason_code=CARD_LOCKED` | 当前卡已确认锁定 | +| `readonly_reason_code=SOURCE_MESSAGE_DISPLAY_READONLY` | 来源邮件展示卡只读 | + +## 7. 确认、复核和锁定规则 + +### 7.1 不保存草稿 + +V4 新数据不再提供后端草稿保存。前端可以在页面本地维护未提交表单状态,但后端只接受最终确认或复核解阻提交。 + +原因: + +- 2026-07-18 V4 契约已确认“不保存草稿”。 +- V4 当前没有真实 OPERA / PMS 执行,后端不需要为半成品 payload 生成后续操作。 +- 可以避免 V3 `draft_payload_json`、`READY` 和 OPERA 模拟骨架继续扩大。 + +### 7.2 最终确认 + +用户确认卡片时,后端保存: + +- `confirmed_payload_json`:用户确认后的结构化字段。 +- `confirmed_by`:当前登录用户 ID。 +- `confirmed_at`:UTC 时间点。 +- `card_status=CONFIRMED`。 + +确认后永久锁定。若后续发现错误,不覆盖原确认记录,应该通过审计记录和未来纠错流程表达。 + +### 7.3 人工复核 + +`manual_review=true` 或目录校验失败时,卡片进入 `REVIEW_REQUIRED`。 + +复核提交后: + +- 不改写 AI 原始 payload。 +- 用户修正写入 `review_resolution_json` 和 `confirmed_payload_json`。 +- 目录值必须来自信息系统受控目录。 +- 通过校验后卡片直接进入 `CONFIRMED`,不再进入 V3 `READY` 状态。 + +### 7.4 Basic Information 目录规则 + +第一版 Basic Information 至少包含: + +- Agent 原始 `account_code`。 +- 信息系统目录校验状态。 +- 后端派生的 `market_code` 和 `source_code` 快照,来源是 Account 目录。 + +如果 `account_code=null` 或目录不存在: + +- 卡片进入 `REVIEW_REQUIRED`。 +- 用户只能从信息系统已有 Account 目录中选择。 +- 后端不得反向篡改 Agent 原始 `basic_information.manual_review`。 + +第一版 Account / Market / Source 目录使用后端固定种子数据,不依赖 SuperAgent 动态提供目录文件。后续如目录由管理后台维护或从外部系统同步,应以专项 checkpoint 设计目录版本、变更审计和回放影响。 + +## 8. 订单归属和 target_order + +### 8.1 order_ref 和 target_order 分工 + +| 字段 | 用途 | +| --- | --- | +| `order_ref` | 当前回调包内归组,同一 `order_ref` 形成一个订单任务 | +| `target_order` | 本系统查找或创建本地订单投影,用于后续同订单阻塞和页面关联 | + +不得用相同 `target_order=null` 合并订单任务;Agent 如果无法判断是否同单,应输出不同 `order_ref`。 + +### 8.2 本地订单绑定规则 + +| `booking_type` | `locator_type` | 第一版绑定规则 | +| --- | --- | --- | +| `GROUP` | `GROUP_CODE` | 按 `hotel_id + GROUP_CODE` 查找 ACTIVE 本地订单;不存在则创建或挂临时可见订单 | +| `FIT` | `BOOKING_CODE` | 按 `hotel_id + BOOKING_CODE` 查找本地订单投影;不存在则创建临时或 Booking Code 订单;若匹配多条则进入人工复核,不自动选单 | +| `FIT` | `CONFIRMATION_NUMBER` | 按 `hotel_id + CONFIRMATION_NUMBER` 查找 ACTIVE 本地订单;不存在则创建可见订单 | +| 任意 | 任意字段未解决 | 创建可见临时订单,订单任务和相关卡片进入复核或阻塞状态,等待用户确认订单归属 | + +`FIT + BOOKING_CODE` 第一版不建立 ACTIVE 唯一约束。`BOOKING_CODE` 是拿到 `CONFIRMATION_NUMBER` 前的临时定位字段,后续不作为 PMS 永久主键;系统只在业务绑定时要求匹配结果至多一条。 + +### 8.3 复核场景订单归属确认 + +V4 CP2 只设计复核场景下的订单归属确认,不开放普通任务任意切换订单。 + +规则: + +- 用户只能在 `REVIEW_REQUIRED` 卡片或订单任务归属未解决时确认订单归属。 +- 订单归属确认必须写业务审计。 +- 若确认到其他订单,原临时订单可在无其它任务引用时逻辑删除。 +- 已确认锁定卡片不能通过该接口二次迁移订单。 + +## 9. 同订单阻塞规则 + +V4 当前不做 OPERA / PMS 执行,但仍需要保留同订单处理顺序,避免用户先确认后续邮件导致业务事实倒置。 + +### 9.1 同一订单任务内 + +推荐固定顺序: + +```text +10 SOURCE_MESSAGE_DISPLAY +20 BASIC_INFORMATION +30 ROOM_INFORMATION +40 TRACE_RESERVATION_NOTES +50 ROOMING_LIST +60 PAYMENT +``` + +规则: + +- `SOURCE_MESSAGE_DISPLAY` 只读,不阻塞。 +- `BASIC_INFORMATION` 未确认时,其它业务卡只能查看,不能确认。 +- 除 Basic Information 必须先确认外,第一版不强制业务卡之间逐张顺序确认;业务卡可独立确认,但页面仍按固定顺序展示。 +- 同类型多张业务卡按 `source_event_index` 排序。 + +### 9.2 同一本地订单下多个订单任务 + +如果多个 SourceMessage 或多个回调包绑定到同一本地订单: + +- 按来源邮件接收时间、AI batch 接收时间、订单任务创建时间排序。 +- 更早订单任务仍有未完成可确认卡时,后续订单任务只能查看。 +- 技术错误 transition 不参与阻塞。 +- S10 来源通知不参与阻塞,也不被阻塞。 + +## 10. 数据表设计草案 + +### 10.1 继续复用的表 + +| 表 | 复用方式 | +| --- | --- | +| `platform_source_message_inbox` | 继续作为来源消息事实和外部 `source_message_id` 查询入口 | +| `workflow_reservation_ai_batch` | 继续保存一次 SuperAgent 回调包的幂等和批次信息 | +| `workflow_reservation_ai_transition` | 继续保存 event 级原始 payload、route、adapter error 和追踪信息 | +| `workflow_reservation_order` | 继续作为本地订单投影和订单列表数据源,但需要补 V4 所需 `BOOKING_CODE` 或 locator 相关能力 | +| `workflow_reservation_audit_log` | 继续保存卡片确认、复核、订单归属确认等业务审计 | + +### 10.2 建议新增表:`workflow_reservation_v4_order_task` + +一条记录表示一个 `source_message_id + order_ref` 形成的 V4 订单任务。 + +| 字段 | 中文说明 | +| --- | --- | +| `id` | V4 订单任务 ID | +| `hotel_id` | 酒店 ID | +| `source_message_id` | SourceMessage Inbox 内部 ID | +| `ai_batch_id` | AI 回调批次 ID | +| `order_ref` | V4 包内订单引用 | +| `order_id` | 绑定的本地订单投影 ID | +| `target_booking_type` | `GROUP` / `FIT` | +| `target_locator_type` | `GROUP_CODE` / `BOOKING_CODE` / `CONFIRMATION_NUMBER` | +| `target_locator_value` | 目标订单定位值,未解决时为空 | +| `target_resolution_status` | `RESOLVED` / `UNRESOLVED` / `CONFLICT` | +| `order_task_status` | 落库快照,仅保存 `OPEN` / `COMPLETED`;`BLOCKED` 由查询响应实时派生 | +| `source_received_at` | 来源邮件接收 UTC 时间,用于排序 | +| `created_at` / `updated_at` | UTC 创建和更新时间 | + +建议唯一约束: + +```text +uk_v4_order_task_source_ref(hotel_id, source_message_id, order_ref) +``` + +### 10.3 建议新增表:`workflow_reservation_v4_task_card` + +一条记录表示 V4 订单任务下的一张卡。 + +| 字段 | 中文说明 | +| --- | --- | +| `id` | V4 任务卡 ID | +| `hotel_id` | 酒店 ID | +| `v4_order_task_id` | 所属 V4 订单任务 ID;S10 来源通知不挂订单任务,后续使用独立通知模型承载 | +| `source_message_id` | 来源消息 ID,便于查邮件会话 | +| `ai_transition_id` | 对应 event 的 AI transition ID;Basic Information 和来源邮件展示卡可为空 | +| `card_type` | 卡片类型 | +| `event_type` | 对应 V4 event_type;非 event 卡为空 | +| `source_event_index` | event 在 `message_events[]` 中的一基序号;非 event 卡固定为 `0`,避免 MySQL 唯一索引因 `NULL` 失效 | +| `card_sort_order` | 页面固定排序值 | +| `card_status` | `READONLY` / `PENDING_CONFIRM` / `REVIEW_REQUIRED` / `CONFIRMED` 等 | +| `review_status` | `PENDING` / `RESOLVED`,仅复核卡使用 | +| `ai_payload_json` | 当前卡使用的 AI 原始片段,不可被用户覆盖 | +| `display_payload_json` | 后端给前端展示的字段快照,可由 AI 和目录派生 | +| `confirmed_payload_json` | 用户最终确认后的字段 | +| `review_resolution_json` | 人工复核修正和订单归属确认结果 | +| `validation_errors_json` | 目录或业务校验错误摘要,不保存敏感正文 | +| `confirmed_by` / `confirmed_at` | 确认人和确认 UTC 时间 | +| `version` | 乐观锁版本 | +| `created_at` / `updated_at` | UTC 创建和更新时间 | + +建议唯一约束: + +```text +uk_v4_task_card_order_task_sort(hotel_id, v4_order_task_id, card_sort_order, source_event_index) +``` + +约束说明: + +- `SOURCE_MESSAGE_DISPLAY`、`BASIC_INFORMATION` 等非 event 卡使用 `source_event_index=0`。 +- event 业务卡使用一基 `source_event_index`。 +- 同一个订单任务下,固定卡片顺序 + `source_event_index` 必须唯一,防止入站重试或幂等异常重复创建同一张卡。 + +### 10.4 建议新增表:`workflow_reservation_v4_source_notification` + +一条记录表示一个 S10 来源通知。它不挂订单任务、不创建订单、不进入订单列表,只用于任务列表 / 工作台和纯通知详情页。 + +| 字段 | 中文说明 | +| --- | --- | +| `id` | 来源通知 ID | +| `hotel_id` | 酒店 ID,第一版使用系统默认酒店或 SourceMessage 所属酒店 | +| `source_message_id` | SourceMessage Inbox 内部 ID | +| `ai_batch_id` | AI 回调批次 ID | +| `ai_transition_id` | S10 对应 AI transition ID | +| `route_code` | 固定为 `S10` | +| `notification_status` | `ACK_REQUIRED` / `ACKED` | +| `raw_payload_json` | S10 原始 AI 片段或包级摘要 | +| `ack_by` / `ack_at` | 确认人和确认 UTC 时间 | +| `source_received_at` | 来源邮件接收 UTC 时间,用于任务列表 / 工作台排序 | +| `version` | 乐观锁版本,用于确认按钮并发控制 | +| `created_at` / `updated_at` | UTC 创建和更新时间 | + +建议唯一约束: + +```text +uk_v4_source_notification_message_batch(hotel_id, source_message_id, ai_batch_id) +``` + +### 10.5 暂不新增的表 + +| 表或能力 | 暂不新增原因 | +| --- | --- | +| V4 草稿表 | V4 已确认不保存草稿 | +| V4 OPERA operation 表 | 当前不做真实 OPERA / OHIP,也不生成 OPERA 模拟 | +| 技术错误用户任务表 | 技术错误不进入用户任务体系,先用 AI transition 和 dispatch run | +| 目录表 | Account、Market、Source 第一版已确认用后端固定种子数据;CP2 只设计边界,后续目录 checkpoint 再决定是否建表、导入或管理后台维护 | + +## 11. Entity / Mapper / Repository 边界草案 + +后续 Java 实现必须遵守当前后端目录规范。 + +### 11.1 domain + +建议新增: + +- `ReservationV4OrderTaskEntity`:映射 `workflow_reservation_v4_order_task`。 +- `ReservationV4TaskCardEntity`:映射 `workflow_reservation_v4_task_card`。 +- `ReservationV4SourceNotificationEntity`:映射 `workflow_reservation_v4_source_notification`。 + +Entity 字段必须有中文注释,说明字段业务含义、来源和状态代码范围。 + +### 11.2 mapper + +建议新增: + +- `ReservationV4OrderTaskMapper` +- `ReservationV4TaskCardMapper` +- `ReservationV4SourceNotificationMapper` + +Mapper 只放 MyBatis-Plus 基础访问和必要语义化查询。自定义方法需要中文注释。 + +### 11.3 repository + +建议新增: + +- `ReservationV4WorkflowRepository` +- `MybatisReservationV4WorkflowRepository` +- `ReservationV4SourceNotificationRepository` +- `MybatisReservationV4SourceNotificationRepository` + +Repository 负责封装: + +- 按 SourceMessage + order_ref 幂等创建订单任务。 +- 创建 Basic Information / SourceMessage / Event 卡。 +- 按 SourceMessage + AI batch 幂等创建 S10 来源通知。 +- 查询订单任务详情和卡片列表。 +- 查询来源通知列表和详情。 +- 卡片确认、锁定、复核解阻的乐观锁更新。 +- 来源通知确认的乐观锁更新。 + +Service 不直接访问 Mapper。 + +### 11.4 service + +建议新增或拆分: + +- `ReservationV4TaskIntakeService`:V4 入站从 AI transition 落 V4 订单任务和卡片。 +- `ReservationV4OrderTaskQueryService`:前端查询订单任务列表和详情。 +- `ReservationV4TaskCardCommandService`:处理卡片确认、复核和订单归属确认。 +- `ReservationV4SourceNotificationService`:处理 S10 来源通知查询和确认。 + +当前 `ReservationAiTaskIntakeServiceImpl` 后续应只负责入站编排和调用 V4 service,不继续膨胀成 V4 领域服务。 + +## 12. 前端查询接口草案 + +以下只是接口草案,CP2 不实现。 + +V4 前端接口不继续扩展旧 `/api/reservation/tasks/**` 作为 V4 主模型入口。第一版草案中,工作台统一列表使用 `/api/reservation/workbench-items`,业务订单任务使用 `/api/reservation/order-tasks/**`,S10 来源通知详情和确认使用 `/api/reservation/source-notifications/**`。 + +### 12.1 工作台统一列表 + +```text +GET /api/reservation/workbench-items +分类:FRONTEND_USER +权限:RESERVATION_TASK_READ +``` + +用途: + +- 作为 V4 任务列表 / 工作台的第一版统一入口。 +- 同时返回业务订单任务和 S10 来源通知。 +- 前端按 `item_type` 区分跳转目标。 + +返回摘要应包含: + +- `item_type`:`ORDER_TASK` / `SOURCE_NOTIFICATION`。 +- `target_id`:订单任务 ID 或来源通知 ID。 +- `source_message_summary` +- `display_order_key`:S10 来源通知为空。 +- `card_counts`:S10 来源通知为空或只返回通知状态。 +- `next_action_card_id`:S10 来源通知为空。 +- `notification_status`:仅 S10 来源通知返回 `ACK_REQUIRED` / `ACKED`。 +- `order_task_status`:仅业务订单任务返回 `OPEN` / `COMPLETED`。 +- `display_status`:可返回 `OPEN` / `BLOCKED` / `COMPLETED` / `ACK_REQUIRED` / `ACKED`。 +- `readonly_reason_code` + +排序规则: + +- 默认按 `source_received_at` 倒序。 +- 同一来源时间下按 AI batch 接收时间、记录创建时间倒序。 + +### 12.2 业务订单任务列表 + +```text +GET /api/reservation/order-tasks +分类:FRONTEND_USER +权限:RESERVATION_TASK_READ +``` + +查询参数草案: + +| 参数 | 中文说明 | +| --- | --- | +| `hotel_id` | 可选,按用户酒店访问权校验 | +| `order_id` | 可选,查询某个本地订单下的订单任务 | +| `card_status` | 可选,筛选含某类待处理卡的订单任务 | +| `keyword` | 可选,匹配邮件主题、发件人、Group Code、Booking Code、Confirmation Number | +| `page_num` / `page_size` | 分页 | + +返回摘要应包含: + +- `order_task_id` +- `order_ref` +- `order_id` +- `display_order_key` +- `source_message_summary` +- `card_counts` +- `next_action_card_id` +- `order_task_status` +- `display_status` +- `readonly_reason_code` + +说明: + +- 该接口只返回业务订单任务,不返回 S10 来源通知。 +- V4 任务列表 / 工作台页面第一版优先使用 `GET /api/reservation/workbench-items`。 + +### 12.3 订单任务详情 + +```text +GET /api/reservation/order-tasks/{orderTaskId} +分类:FRONTEND_USER +权限:RESERVATION_TASK_READ +``` + +返回结构草案: + +```json +{ + "order_task": {}, + "bound_order": {}, + "source_message_card": {}, + "basic_information_card": {}, + "business_cards": [], + "adapter_contract_errors": [], + "availability": {} +} +``` + +前端应以返回的 `cards[]` 和 `availability` 为准渲染,不自行拼完整字段矩阵。 + +### 12.4 S10 来源通知详情 + +```text +GET /api/reservation/source-notifications/{notificationId} +分类:FRONTEND_USER +权限:RESERVATION_TASK_READ +``` + +返回结构草案: + +```json +{ + "notification": {}, + "source_message_card": {}, + "conversation_summary": {}, + "availability": {} +} +``` + +说明: + +- 只用于 S10 纯通知详情页。 +- 不返回 `order_task`、`bound_order`、`basic_information_card` 或 `business_cards`。 +- 邮件正文、附件 URL 和会话原文读取仍按 SourceMessage 权限和原文读取审计规则处理。 + +### 12.5 订单详情时间线 + +建议后续扩展: + +```text +GET /api/reservation/orders/{orderId}/order-tasks +分类:FRONTEND_USER +权限:RESERVATION_ORDER_READ +``` + +用于订单详情页展示 V4 订单任务时间线。旧 `GET /api/reservation/orders/{orderId}` 可以在过渡期继续返回 V3 `tasks[]`。 + +## 13. 前端写操作接口草案 + +### 13.1 确认卡片 + +```text +POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm +分类:FRONTEND_USER +权限:RESERVATION_TASK_CONFIRM +``` + +请求要点: + +- 只提交当前卡允许编辑的字段。 +- 不提交草稿。 +- 必须带 `version` 做并发校验。 +- 后端确认后卡片 `CONFIRMED` 并锁定。 + +### 13.2 复核并确认卡片 + +```text +POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution +分类:FRONTEND_USER +权限:RESERVATION_MANUAL_REVIEW_RESOLVE +``` + +请求要点: + +- 提交 `field_overrides[]`。 +- 可提交复核场景订单归属确认。 +- 校验通过后直接 `CONFIRMED`。 +- 写业务审计。 + +### 13.3 S10 通知确认 + +```text +POST /api/reservation/source-notifications/{notificationId}/ack +分类:FRONTEND_USER +权限:RESERVATION_TASK_CONFIRM +``` + +S10 已确认采用来源通知模型,不继续复用隐藏技术订单或旧 `SOURCE_MESSAGE_ONLY` 任务确认方式。第一版通知详情只显示邮件展示卡和确认按钮,确认动作表示已读 / 已处理。 + +请求要点: + +- 必须带 `version` 做并发校验。 +- 确认后 `notification_status=ACKED`,写确认人和 UTC 确认时间。 +- 重复提交已确认通知应返回幂等成功或明确的已确认状态,不允许回退到 `ACK_REQUIRED`。 + +## 14. 旧 V3 / V2 兼容和废弃边界 + +开发阶段已确认可以清空数据,因此后续 V4 开发可以不迁移历史任务数据。 + +### 14.1 可继续保留 + +- `workflow_reservation_ai_batch` +- `workflow_reservation_ai_transition` +- `workflow_reservation_order` +- `workflow_reservation_audit_log` +- SuperAgent V3 / V2 入站兼容代码,直到正式切换前 + +### 14.2 V4 新数据不再使用 + +- `workflow_reservation_task_card.draft_payload_json` +- V3 `READY` 作为确认后等待 OPERA 的状态语义 +- V3 OPERA 模拟自动生成 +- V2 `ai_task_results[]` 字段矩阵作为新 V4 页面主模型 +- 旧 `S000/S999` 作为新入站格式 +- Fallback 转 New / Update / Cancel 作为 V4 主入口 + +### 14.3 可以后续专项废弃 + +- V2 `text/plain S000/S999` 兼容入口。 +- 旧 `ai_task_results[]` 入站入口。 +- V3 40 路由中不再被 V4 使用的历史 subtype。 +- `workflow_reservation_task` 作为 V4 多卡主模型的直接承载方式。 +- 旧 V2/V3 任务详情、草稿保存和最终确认接口,待 V4 新模型落地并完成前端切换后逐步废弃。 + +废弃前必须先确认前端、MCP、SuperAgent 联调方和测试 fixture 都已切到 V4。 + +## 15. 安全、权限和审计 + +后续实现接口时必须同步更新 `security-access-control-boundary.md`。 + +第一版建议: + +| 能力 | 分类 | 权限码 | 审计 | +| --- | --- | --- | --- | +| 查询工作台、订单任务列表 / 详情、来源通知详情 | `FRONTEND_USER` | `RESERVATION_TASK_READ` | 只读默认不写业务审计 | +| 确认卡片 | `FRONTEND_USER` | `RESERVATION_TASK_CONFIRM` | 写业务审计 | +| 复核解阻 | `FRONTEND_USER` | `RESERVATION_MANUAL_REVIEW_RESOLVE` | 写业务审计 | +| 确认 S10 来源通知 | `FRONTEND_USER` | `RESERVATION_TASK_CONFIRM` | 写业务审计 | +| 读取邮件正文 / 附件 | `FRONTEND_USER` | `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ` | 写原文读取审计 | +| SuperAgent V4 回调 | `THIRD_PARTY_SUPERAGENT` | HMAC 机器鉴权 | 写 AI batch / transition | + +AI 原始 payload、邮件正文、附件 URL 和技术 trace 不应直接进入普通列表接口。 + +## 16. 后续开发 checkpoint + +| Checkpoint | 目标 | 主要交付 | +| --- | --- | --- | +| M002-V4-CP3 | V4 表结构和基础 Repository | 新增 V4 order task / card / source notification 表、Entity、Mapper、Repository、测试 | +| M002-V4-CP4 | V4 入站落新模型 | SuperAgent V4 回调创建订单任务、Basic Information 卡、业务卡、邮件展示卡和 S10 来源通知 | +| M002-V4-CP5 | V4 查询接口 | 工作台统一列表、订单任务列表、详情、订单详情时间线和来源通知详情查询接口 | +| M002-V4-CP6 | V4 卡片确认和复核 | 不保存草稿,支持确认、复核、锁定、审计、阻塞规则和 S10 来源通知确认 | +| M002-V4-CP7 | 受控目录第一版 | Account、RoomType、RateCode、Department 固定目录或版本化快照校验 | +| M002-V4-CP8 | V4 前端契约收口 | 字段、控件、availability、错误展示和旧任务入口切换 | +| M002-V4-CP9 | 旧 V3 / V2 能力收口评估 | 明确哪些兼容入口可以关闭,哪些仍保留只读历史 | + +## 17. 已确认设计决策 + +1. V4 前端接口不继续扩展旧 `/api/reservation/tasks/**`;工作台统一列表新开 `/api/reservation/workbench-items`,业务订单任务新开 `/api/reservation/order-tasks/**`,S10 来源通知使用 `/api/reservation/source-notifications/**`。 +2. `FIT + BOOKING_CODE` 第一版不建立 ACTIVE 唯一约束;业务绑定时要求匹配结果至多一条,匹配多条进入人工复核。 +3. `BOOKING_CODE` 只是拿到 `CONFIRMATION_NUMBER` 前的临时定位字段,后续不作为 PMS 永久主键。 +4. S10 采用来源通知模型:任务列表 / 工作台展示,不挂隐藏技术订单;通知详情只显示邮件展示卡和确认按钮。 +5. S10 不创建订单、不进订单列表、不参与订单阻塞,也不支持编辑、复核、OPERA 或人工终止。 +6. 第一版不强制所有业务卡逐张顺序确认,但 Basic Information 必须先确认。 +7. Basic Information 的 Account / Market / Source 目录第一版使用后端固定种子数据。 +8. 普通业务邮件的来源邮件展示卡只读展示,不需要用户确认;用户只确认 Basic Information 和具体业务卡。 +9. S10 因为没有业务卡,邮件展示卡需要确认按钮,用来记录已读 / 已处理。 +10. V4 新模型落地并完成前端切换后,旧 V2/V3 任务详情、草稿保存和最终确认接口可以逐步废弃。 diff --git a/docs/project/security-access-control-boundary.md b/docs/project/security-access-control-boundary.md index 42cf2f3..5deb448 100644 --- a/docs/project/security-access-control-boundary.md +++ b/docs/project/security-access-control-boundary.md @@ -47,8 +47,15 @@ | `GET /api/reservation/orders` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_ORDER_READ`;支持可选 `hotel_id` 并校验酒店访问权 | 保持登录 + `RESERVATION_ORDER_READ` + 酒店访问权 | 只读查询默认不写业务审计 | | `GET /api/reservation/orders/{orderId}` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_ORDER_READ`;按订单实际所属酒店校验访问权 | 保持登录 + `RESERVATION_ORDER_READ` + 订单所属酒店访问权 | 只读查询默认不写业务审计 | | `GET /api/reservation/tasks/{taskId}` | `FRONTEND_USER` | 已强制 Bearer 登录 + `RESERVATION_TASK_READ`;按任务实际所属酒店校验访问权 | 保持登录 + `RESERVATION_TASK_READ` + 任务所属酒店访问权 | 只读查询默认不写业务审计 | +| `GET /api/reservation/workbench-items` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_TASK_READ` + 酒店访问权;统一返回 V4 业务订单任务和 S10 来源通知摘要 | 只读查询默认不写业务审计;不得返回邮件正文、附件 URL 或 AI 原始 payload | +| `GET /api/reservation/order-tasks` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_TASK_READ` + 酒店访问权;只返回 V4 业务订单任务,不返回 S10 来源通知 | 只读查询默认不写业务审计 | +| `GET /api/reservation/order-tasks/{orderTaskId}` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_TASK_READ` + 订单任务所属酒店访问权 | 只读查询默认不写业务审计;邮件正文和附件读取仍走 SourceMessage 原文权限 | +| `GET /api/reservation/source-notifications/{notificationId}` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_TASK_READ` + 来源通知所属酒店访问权 | 只读查询默认不写业务审计;邮件正文和附件读取仍走 SourceMessage 原文权限 | | `PUT /api/reservation/tasks/{taskId}/draft` | `FRONTEND_USER` | 第一版未全量强制登录;actor 仍待迁移 | 登录 + `RESERVATION_TASK_EDIT` + 酒店访问权 | 写草稿审计可按业务需要记录 | | `POST /api/reservation/tasks/{taskId}/confirm` | `FRONTEND_USER` | 第一版未全量强制登录;actor 仍待迁移 | 登录 + `RESERVATION_TASK_CONFIRM` + 酒店访问权 | 必须写业务审计 | +| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_TASK_CONFIRM` + 订单任务所属酒店访问权 + version 并发校验 | 必须写业务审计 | +| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 订单任务所属酒店访问权 + version 并发校验 | 必须写业务审计,记录复核修正和订单归属确认摘要 | +| `POST /api/reservation/source-notifications/{notificationId}/ack` | `FRONTEND_USER` | M002 V4 CP2 草案,尚未实现 | 登录 + `RESERVATION_TASK_CONFIRM` + 来源通知所属酒店访问权 + version 并发校验 | 必须写业务审计,记录已读 / 已处理确认 | | `POST /api/reservation/tasks/{taskId}/manual-review-conversions` | `FRONTEND_USER` | 第一版已写业务审计,但 actor 待迁移 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 酒店访问权 | 必须写业务审计和原因 | | `POST /api/reservation/tasks/{taskId}/manual-review-resolutions` | `FRONTEND_USER` | 第一版已写业务审计,但 actor 待迁移 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 酒店访问权 | 必须写业务审计 | | `POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute` | `FRONTEND_USER` | 当前为 OPERA 模拟 | 登录 + `RESERVATION_OPERA_SIM_EXECUTE` + 酒店访问权 | 必须写业务审计和 attempt |