实现M002 V4入站写入新模型

This commit is contained in:
andy
2026-07-19 00:54:58 +07:00
parent e6fbd7a111
commit e59ac2f3bf
17 changed files with 1256 additions and 115 deletions

View File

@@ -6,9 +6,9 @@
| --- | --- |
| 文档版本 | 0.2 |
| 日期 | 2026-07-18 |
| 状态 | CP2 设计已确认CP3 表结构、Entity、Mapper、Repository 基线已实现 |
| 状态 | CP2 设计已确认CP3 表结构、Entity、Mapper、Repository 基线已实现CP4 入站写入新模型已实现 |
| 适用范围 | M002 V4 入站后的订单任务、多卡、状态、查询和写操作设计 |
| 不适用范围 | V4 入站写入新模型、V4 前端查询接口、卡片确认 / 复核接口、真实 PMS / OPERA / OHIP、前端页面视觉稿、历史数据迁移 |
| 不适用范围 | V4 前端查询接口、卡片确认 / 复核接口、真实 PMS / OPERA / OHIP、前端页面视觉稿、历史数据迁移 |
## 1. 文档定位
@@ -16,7 +16,7 @@ M002 V4 CP1 已完成 SuperAgent V4 回调包入站解析、基础校验、路
本文是 CP2 设计文档,用于把 2026-07-18 V4 字段契约落成后续可开发的数据模型和接口草案。
截至 CP3,后端已实现本文第 10、11 节中的持久化基线:新增 `workflow_reservation_v4_order_task``workflow_reservation_v4_task_card``workflow_reservation_v4_source_notification` 三张表,以及对应 Entity、Mapper、Repository 和基础测试。CP3 仍未把 SuperAgent V4 入站结果写入这些新表,也未开放 V4 前端查询或写操作接口。
截至 CP4,后端已实现本文第 10、11 节中的持久化基线,并已把 SuperAgent V4 入站结果写入新表:普通业务包创建 V4 订单任务、来源邮件展示卡、Basic Information 卡和业务卡V4 S10/S99 创建来源通知。当前仍未开放 V4 前端查询或写操作接口。
后续如本文与 `M002-v4-agent-callback-field-contract.md` 的字段契约冲突,以字段契约为准;如与安全边界冲突,以 `security-access-control-boundary.md` 为准。
@@ -24,10 +24,10 @@ M002 V4 CP1 已完成 SuperAgent V4 回调包入站解析、基础校验、路
| 主题 | 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 多卡模型 |
| 入站识别 | 已识别 `route_code``source_message``order_contexts[]``message_events[]` | CP4 已把有合法 event 的 `order_ref` 建成订单任务聚合V4 查询接口仍未实现 |
| SourceMessage | 已按 `source_message.source_message_id` 反查 SourceMessage Inbox | CP4 已固定生成普通业务包内邮件展示卡;邮件正文完整读取仍走 SourceMessage 会话接口 |
| Basic Information | 已写入 V4 Basic Information 独立卡 | 目录校验、确认 / 复核写接口仍待 CP6 / CP7 |
| 业务 Event | 可映射 event 临时创建旧 `workflow_reservation_task`,并已额外创建 V4 业务卡 | 旧任务链路仍作前端过渡兼容,后续 V4 查询和写接口完成后再逐步废弃 |
| 技术错误 | 已落 `adapter_contract_error` transition | 已符合目标方向:不创建用户可处理卡 |
| 草稿 / READY / OPERA | 仍复用 V3 草稿、READY 和 OPERA 模拟骨架 | V4 新数据确认口径是不保存草稿、确认后锁定、当前不生成 OPERA |
| 前端查询 | 复用旧任务列表和任务详情 | 需要新订单任务详情接口返回邮件卡、Basic Information 卡和业务卡数组 |
@@ -98,7 +98,7 @@ V4 package / event contract error
- Basic Information 不是 event但必须是独立任务卡。
- 来源邮件展示卡不是 event普通业务包内只读不参与订单执行阻塞。
- S10 采用来源通知模型:任务列表 / 工作台可见点击进入纯通知详情页只显示邮件展示卡和确认按钮不创建订单、不进订单列表、不参与订单阻塞也不支持编辑、复核、OPERA 或人工终止。
- S10/S99 采用来源通知模型:任务列表 / 工作台可见点击进入纯通知详情页只显示邮件展示卡和确认按钮不创建订单、不进订单列表、不参与订单阻塞也不支持编辑、复核、OPERA 或人工终止。
- 同一 `order_ref` 下如果有多个相同 `event_type`,第一版按 event 数组项分别建卡;页面排序按固定卡片顺序,再按 `source_event_index` 排序。
## 6. 状态设计
@@ -124,8 +124,8 @@ V4 package / event contract error
| `PENDING_CONFIRM` | 待确认 | 若没有前置阻塞,允许提交最终确认 |
| `REVIEW_REQUIRED` | 待人工复核 | 若没有前置阻塞,允许提交复核修正并确认 |
| `CONFIRMED` | 已确认锁定 | 只能查看,不允许再次编辑或覆盖 |
| `ACK_REQUIRED` | 通知待确认 | 仅用于 S10 来源通知,落在 `workflow_reservation_v4_source_notification.notification_status` |
| `ACKED` | 通知已确认 | 仅用于 S10 来源通知,落在 `workflow_reservation_v4_source_notification.notification_status` |
| `ACK_REQUIRED` | 通知待确认 | 仅用于 S10/S99 来源通知,落在 `workflow_reservation_v4_source_notification.notification_status` |
| `ACKED` | 通知已确认 | 仅用于 S10/S99 来源通知,落在 `workflow_reservation_v4_source_notification.notification_status` |
### 6.3 可操作性派生
@@ -254,7 +254,7 @@ V4 当前不做 OPERA / PMS 执行,但仍需要保留同订单处理顺序,
- 按来源邮件接收时间、AI batch 接收时间、订单任务创建时间排序。
- 更早订单任务仍有未完成可确认卡时,后续订单任务只能查看。
- 技术错误 transition 不参与阻塞。
- S10 来源通知不参与阻塞,也不被阻塞。
- S10/S99 来源通知不参与阻塞,也不被阻塞。
## 10. 数据表设计草案
@@ -306,7 +306,7 @@ uk_reservation_v4_order_task_source_index(hotel_id, source_message_id, order_con
| --- | --- |
| `id` | V4 任务卡 ID |
| `hotel_id` | 酒店 ID |
| `v4_order_task_id` | 所属 V4 订单任务 IDS10 来源通知不挂订单任务,后续使用独立通知模型承载 |
| `v4_order_task_id` | 所属 V4 订单任务 IDS10/S99 来源通知不挂订单任务,后续使用独立通知模型承载 |
| `source_message_id` | 来源消息 ID便于查邮件会话 |
| `ai_transition_id` | 对应 event 的 AI transition IDBasic Information 和来源邮件展示卡可为空 |
| `card_type` | 卡片类型 |
@@ -339,7 +339,7 @@ uk_reservation_v4_task_card_slot(hotel_id, v4_order_task_id, card_sort_order, so
### 10.4 已新增表:`workflow_reservation_v4_source_notification`
一条记录表示一个 S10 来源通知。它不挂订单任务、不创建订单、不进入订单列表,只用于任务列表 / 工作台和纯通知详情页。
一条记录表示一个 S10/S99 来源通知。它不挂订单任务、不创建订单、不进入订单列表,只用于任务列表 / 工作台和纯通知详情页。
| 字段 | 中文说明 |
| --- | --- |
@@ -347,10 +347,10 @@ uk_reservation_v4_task_card_slot(hotel_id, v4_order_task_id, card_sort_order, so
| `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` |
| `ai_transition_id` | S10/S99 对应 AI transition ID |
| `route_code` | `S10``S99` |
| `notification_status` | `ACK_REQUIRED` / `ACKED` |
| `raw_payload_json` | S10 原始 AI 片段或包级摘要 |
| `raw_payload_json` | S10/S99 原始 AI 片段或包级摘要 |
| `ack_by` / `ack_at` | 确认人和确认 UTC 时间 |
| `source_received_at` | 来源邮件接收 UTC 时间,用于任务列表 / 工作台排序 |
| `version` | 乐观锁版本,用于确认按钮并发控制 |
@@ -410,7 +410,7 @@ CP3 Repository 已封装:
- 按 SourceMessage + order_ref 幂等创建订单任务。
-`order_context_index` 保留同一 SourceMessage 下多个 `order_contexts[]` 的稳定顺序。
- 创建 Basic Information / SourceMessage / Event 卡的基础插入方法;非 event 卡 `source_event_index` 固定写入 `0`
- 按 SourceMessage + AI batch 幂等创建 S10 来源通知。
- 按 SourceMessage + AI batch 幂等创建 S10/S99 来源通知。
- 查询订单任务详情和卡片列表。
- 查询来源通知列表和详情。
- 卡片状态的 version 乐观锁更新基础方法。
@@ -425,18 +425,18 @@ Service 不直接访问 Mapper。
建议新增或拆分:
- `ReservationV4TaskIntakeService`V4 入站从 AI transition 落 V4 订单任务卡片。
- `ReservationV4TaskIntakeService`已实现,V4 入站从 AI transition 落 V4 订单任务卡片和 S10/S99 来源通知
- `ReservationV4OrderTaskQueryService`:前端查询订单任务列表和详情。
- `ReservationV4TaskCardCommandService`:处理卡片确认、复核和订单归属确认。
- `ReservationV4SourceNotificationService`:处理 S10 来源通知查询和确认。
- `ReservationV4SourceNotificationService`:处理 S10/S99 来源通知查询和确认。
当前 `ReservationAiTaskIntakeServiceImpl` 后续应只负责入站编排和调用 V4 service不继续膨胀成 V4 领域服务
当前 `ReservationAiTaskIntakeServiceImpl` 已在 V4 分支调用 `ReservationV4TaskIntakeService` 完成新模型写入;后续查询、确认和复核仍应继续拆到独立 V4 service避免主入站类继续膨胀
## 12. 前端查询接口草案
以下只是接口草案CP2 不实现。
V4 前端接口不继续扩展旧 `/api/reservation/tasks/**` 作为 V4 主模型入口。第一版草案中,工作台统一列表使用 `/api/reservation/workbench-items`,业务订单任务使用 `/api/reservation/order-tasks/**`S10 来源通知详情和确认使用 `/api/reservation/source-notifications/**`
V4 前端接口不继续扩展旧 `/api/reservation/tasks/**` 作为 V4 主模型入口。第一版草案中,工作台统一列表使用 `/api/reservation/workbench-items`,业务订单任务使用 `/api/reservation/order-tasks/**`S10/S99 来源通知详情和确认使用 `/api/reservation/source-notifications/**`
### 12.1 工作台统一列表
@@ -449,7 +449,7 @@ GET /api/reservation/workbench-items
用途:
- 作为 V4 任务列表 / 工作台的第一版统一入口。
- 同时返回业务订单任务和 S10 来源通知。
- 同时返回业务订单任务和 S10/S99 来源通知。
- 前端按 `item_type` 区分跳转目标。
返回摘要应包含:
@@ -457,10 +457,10 @@ GET /api/reservation/workbench-items
- `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`
- `display_order_key`S10/S99 来源通知为空。
- `card_counts`S10/S99 来源通知为空或只返回通知状态。
- `next_action_card_id`S10/S99 来源通知为空。
- `notification_status`:仅 S10/S99 来源通知返回 `ACK_REQUIRED` / `ACKED`
- `order_task_status`:仅业务订单任务返回 `OPEN` / `COMPLETED`
- `display_status`:可返回 `OPEN` / `BLOCKED` / `COMPLETED` / `ACK_REQUIRED` / `ACKED`
- `readonly_reason_code`
@@ -503,7 +503,7 @@ GET /api/reservation/order-tasks
说明:
- 该接口只返回业务订单任务,不返回 S10 来源通知。
- 该接口只返回业务订单任务,不返回 S10/S99 来源通知。
- V4 任务列表 / 工作台页面第一版优先使用 `GET /api/reservation/workbench-items`
### 12.3 订单任务详情
@@ -530,7 +530,7 @@ GET /api/reservation/order-tasks/{orderTaskId}
前端应以返回的 `cards[]``availability` 为准渲染,不自行拼完整字段矩阵。
### 12.4 S10 来源通知详情
### 12.4 S10/S99 来源通知详情
```text
GET /api/reservation/source-notifications/{notificationId}
@@ -551,7 +551,7 @@ GET /api/reservation/source-notifications/{notificationId}
说明:
- 只用于 S10通知详情页。
- 只用于 S10/S99 来源通知详情页。
- 不返回 `order_task``bound_order``basic_information_card``business_cards`
- 邮件正文、附件 URL 和会话原文读取仍按 SourceMessage 权限和原文读取审计规则处理。
@@ -607,7 +607,7 @@ POST /api/reservation/source-notifications/{notificationId}/ack
权限RESERVATION_TASK_CONFIRM
```
S10 已确认采用来源通知模型,不继续复用隐藏技术订单或旧 `SOURCE_MESSAGE_ONLY` 任务确认方式。第一版通知详情只显示邮件展示卡和确认按钮,确认动作表示已读 / 已处理。
S10/S99 已确认采用来源通知模型,不继续复用隐藏技术订单或旧 `SOURCE_MESSAGE_ONLY` 任务确认方式。第一版通知详情只显示邮件展示卡和确认按钮,确认动作表示已读 / 已处理。
请求要点:
@@ -657,7 +657,7 @@ S10 已确认采用来源通知模型,不继续复用隐藏技术订单或旧
| 查询工作台、订单任务列表 / 详情、来源通知详情 | `FRONTEND_USER` | `RESERVATION_TASK_READ` | 只读默认不写业务审计 |
| 确认卡片 | `FRONTEND_USER` | `RESERVATION_TASK_CONFIRM` | 写业务审计 |
| 复核解阻 | `FRONTEND_USER` | `RESERVATION_MANUAL_REVIEW_RESOLVE` | 写业务审计 |
| 确认 S10 来源通知 | `FRONTEND_USER` | `RESERVATION_TASK_CONFIRM` | 写业务审计 |
| 确认 S10/S99 来源通知 | `FRONTEND_USER` | `RESERVATION_TASK_CONFIRM` | 写业务审计 |
| 读取邮件正文 / 附件 | `FRONTEND_USER` | `SOURCE_MESSAGE_READ` + `SOURCE_MESSAGE_ORIGINAL_READ` | 写原文读取审计 |
| SuperAgent V4 回调 | `THIRD_PARTY_SUPERAGENT` | HMAC 机器鉴权 | 写 AI batch / transition |
@@ -668,22 +668,22 @@ AI 原始 payload、邮件正文、附件 URL 和技术 trace 不应直接进入
| 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-CP4 | V4 入站落新模型 | 已完成:SuperAgent V4 回调创建订单任务、Basic Information 卡、业务卡、邮件展示卡和 S10/S99 来源通知 |
| M002-V4-CP5 | V4 查询接口 | 工作台统一列表、订单任务列表、详情、订单详情时间线和来源通知详情查询接口 |
| M002-V4-CP6 | V4 卡片确认和复核 | 不保存草稿,支持确认、复核、锁定、审计、阻塞规则和 S10 来源通知确认 |
| M002-V4-CP6 | V4 卡片确认和复核 | 不保存草稿,支持确认、复核、锁定、审计、阻塞规则和 S10/S99 来源通知确认 |
| 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/**`
1. V4 前端接口不继续扩展旧 `/api/reservation/tasks/**`;工作台统一列表新开 `/api/reservation/workbench-items`,业务订单任务新开 `/api/reservation/order-tasks/**`S10/S99 来源通知使用 `/api/reservation/source-notifications/**`
2. `FIT + BOOKING_CODE` 第一版不建立 ACTIVE 唯一约束;业务绑定时要求匹配结果至多一条,匹配多条进入人工复核。
3. `BOOKING_CODE` 只是拿到 `CONFIRMATION_NUMBER` 前的临时定位字段,后续不作为 PMS 永久主键。
4. S10 采用来源通知模型:任务列表 / 工作台展示,不挂隐藏技术订单;通知详情只显示邮件展示卡和确认按钮。
5. S10 不创建订单、不进订单列表、不参与订单阻塞也不支持编辑、复核、OPERA 或人工终止。
4. S10/S99 采用来源通知模型:任务列表 / 工作台展示,不挂隐藏技术订单;通知详情只显示邮件展示卡和确认按钮。
5. S10/S99 不创建订单、不进订单列表、不参与订单阻塞也不支持编辑、复核、OPERA 或人工终止。
6. 第一版不强制所有业务卡逐张顺序确认,但 Basic Information 必须先确认。
7. Basic Information 的 Account / Market / Source 目录第一版使用后端固定种子数据。
8. 普通业务邮件的来源邮件展示卡只读展示,不需要用户确认;用户只确认 Basic Information 和具体业务卡。
9. S10 因为没有业务卡,邮件展示卡需要确认按钮,用来记录已读 / 已处理。
9. S10/S99 因为没有业务卡,邮件展示卡需要确认按钮,用来记录已读 / 已处理。
10. V4 新模型落地并完成前端切换后,旧 V2/V3 任务详情、草稿保存和最终确认接口可以逐步废弃。