实现 M002 CP5 任务确认与 OPERA 模拟骨架
This commit is contained in:
@@ -12,14 +12,21 @@
|
||||
- `GET /api/source-messages/{id}/original`:受控读取邮件原文、HTML 和媒体 URL,并记录访问审计。
|
||||
- `GET /api/system/agentbus-probe`:查看 AgentBus WebSocket 连接状态和安全计数器。
|
||||
- AgentBus WebSocket 入站链路:默认关闭,开启后只把业务 frame 写入 SourceMessage Inbox。
|
||||
- SuperAgent 任务结果接收接口:接收一个 `source_message_id` 下的 AI 任务结果,写入 AI 过渡层、订单、任务和任务卡。
|
||||
- Reservation 任务详情接口:返回任务字段、队列可处理状态和 OPERA 模拟操作摘要。
|
||||
- Reservation 任务草稿保存和最终确认接口:按任务卡矩阵做第一版后端校验,确认后生成 `confirmed_payload_json`。
|
||||
- Reservation OPERA 模拟骨架:已确认任务固定生成两条模拟操作,支持执行、失败重试、attempt 记录和任务审计列表。
|
||||
|
||||
当前不要把以下能力当作已上线:
|
||||
|
||||
- SourceMessage Replay 到 MessageEvent / Evidence。
|
||||
- AI 识别、Case 匹配、Task 创建、Operation、Receipt。
|
||||
- 真实 AI 识别服务实现、Case 完整模型、Operation、Receipt。
|
||||
- 自动 ACK、`task.result` 或客户回复。
|
||||
- 业务前端页面展示邮件原文。
|
||||
- OHIP 或其他业务系统写操作。
|
||||
- OHIP / OPERA 或其他业务系统真实写操作。
|
||||
- SuperAgent 查询上下文接口。
|
||||
- 普通任务切换订单接口。
|
||||
- 用户身份、权限和真实审计 actor。
|
||||
|
||||
## 2. 上线前必须确认
|
||||
|
||||
@@ -86,6 +93,8 @@
|
||||
|
||||
- `server/src/main/resources/db/migration/V3__create_reservation_ai_task_workflow.sql`
|
||||
- `server/src/main/resources/db/migration/V4__harden_reservation_task_queue_and_manual_conversion.sql`
|
||||
- `server/src/main/resources/db/migration/V5__add_reservation_task_draft_and_confirmation.sql`
|
||||
- `server/src/main/resources/db/migration/V6__create_reservation_opera_simulation_tables.sql`
|
||||
|
||||
上线前确认:
|
||||
|
||||
@@ -95,6 +104,7 @@
|
||||
- 表和字段中文注释能正常创建。
|
||||
- 数据库时间按 UTC 写入,接口层负责返回 ISO 8601。
|
||||
- 执行 V4 前,如果目标库已有 M002 试运行数据,必须先检查 ACTIVE 订单业务号重复和同订单任务队列序号重复。
|
||||
- 执行 V5 / V6 前,如果目标库已有 M002 试运行数据,必须确认任务草稿、确认 payload 和 OPERA 模拟操作表允许从空数据开始补齐;不要手工伪造已确认 payload 或 attempt 历史。
|
||||
|
||||
V4 前置检查 SQL:
|
||||
|
||||
@@ -119,6 +129,7 @@ HAVING COUNT(*) > 1;
|
||||
- ACTIVE 订单业务号重复时,先由业务确认保留哪一条 ACTIVE,其他订单应转为 `LOGIC_DELETED`、`ENDED` 或完成任务迁移后再上线。
|
||||
- 同订单任务队列序号重复时,先按来源顺序和审计证据重新分配 `execution_order`,确认前置任务关系正确后再上线。
|
||||
- 不要为了让唯一索引创建成功而随意删除订单、任务或 AI 原始记录。
|
||||
- OPERA 模拟操作失败只代表单条模拟操作失败,当前任务不会因此自动进入 `FAILED`;上线验证时不能把失败操作当作真实 OPERA 失败处理。
|
||||
|
||||
禁止事项:
|
||||
|
||||
|
||||
@@ -191,9 +191,11 @@ Controller、Service、Service 实现类的方法必须有中文注释。Entity
|
||||
建议范围:
|
||||
|
||||
- 任务详情 Response 包含 AI 原始摘要、任务卡字段、可处理状态和阻塞原因。
|
||||
- 第一版任务卡字段矩阵写在代码 Provider 中,避免 Controller / Service 直接硬编码。
|
||||
- 第一版任务卡字段矩阵由 `reservation-task-card/field-matrix-v20260706.json` 资源和 Provider 提供,避免 Controller 直接硬编码。
|
||||
- 保存 `draft_payload_json`。
|
||||
- 确认时生成 `confirmed_payload_json`。
|
||||
- `field_values` 第一版使用矩阵 `field_path` 作为 key,不按 `write_path` 生成 OPERA 参数;后续真实 OPERA 接入时必须在 adapter / 转换层重新组装参数。
|
||||
- 确认时按 `task_subtype`、展示条件、必填、枚举、日期、数字等矩阵规则做第一版后端校验。
|
||||
- 审计用户字段修改和确认。
|
||||
|
||||
验收标准:
|
||||
@@ -203,6 +205,8 @@ Controller、Service、Service 实现类的方法必须有中文注释。Entity
|
||||
- 用户确认后任务进入 `READY`。
|
||||
- OPERA 参数不得从 `ai_payload_json` 读取。
|
||||
- 用户修改不覆盖 AI 原始 JSON。
|
||||
- 保存草稿接口:`PUT /api/reservation/tasks/{taskId}/draft`。
|
||||
- 最终确认接口:`POST /api/reservation/tasks/{taskId}/confirm`。
|
||||
|
||||
不做:
|
||||
|
||||
@@ -253,12 +257,11 @@ Controller、Service、Service 实现类的方法必须有中文注释。Entity
|
||||
建议范围:
|
||||
|
||||
- 从 `confirmed_payload_json` 生成模拟操作。
|
||||
- 每个任务可生成多条操作。
|
||||
- 第一版每个已确认任务固定生成两条 OPERA 模拟操作,后续接真实 OPERA 时再按任务类型扩展。
|
||||
- 每次执行或重试新增 attempt。
|
||||
- 失败任务进入 `FAILED`。
|
||||
- 模拟操作失败时只将该 `operation` 标记为 `FAILED`,任务不进入 `FAILED`,避免按队列规则误判为已结束并跳过失败 OPERA 操作。
|
||||
- 全部必要操作成功后任务进入 `COMPLETED`。
|
||||
- 从 `business_key_candidates_json` 回填订单业务号。
|
||||
- 第一版先在订单表设计 `business_key_source`、`business_key_backfilled_at` 等字段,OPERA 模拟执行模块后续再写入。
|
||||
- 第一版只保存模拟请求/响应摘要,不做 New Booking 业务号回填;订单表已预留 `business_key_source`、`business_key_backfilled_at` 等字段,后续真实 OPERA 或明确模拟返回结构后再写入。
|
||||
|
||||
验收标准:
|
||||
|
||||
@@ -267,12 +270,17 @@ Controller、Service、Service 实现类的方法必须有中文注释。Entity
|
||||
- 失败操作不能跳过。
|
||||
- 用户不能强制完成任务。
|
||||
- 重试不覆盖历史 attempt。
|
||||
- New Booking 无业务号时,模拟成功后可回填 Confirmation Number 或 Group Code 含义字段。
|
||||
- 执行接口:`POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute`。
|
||||
- 重试接口:`POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry`。
|
||||
- 审计列表接口:`GET /api/reservation/tasks/{taskId}/audits`。
|
||||
|
||||
不做:
|
||||
|
||||
- 不接真实 OPERA 接口。
|
||||
- 不写死真实 OPERA 返回字段路径。
|
||||
- 不做普通任务切换订单。
|
||||
- 不做 SuperAgent 查询上下文接口。
|
||||
- 不接用户身份权限,审计 actor 第一版仍使用本地占位。
|
||||
|
||||
## 11. Checkpoint 8:审计、查询和收口
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
| --- | --- |
|
||||
| 文档版本 | 0.1 |
|
||||
| 日期 | 2026-07-07 |
|
||||
| 状态 | 后端数据模型草稿 |
|
||||
| 状态 | 后端数据模型与阶段实现记录 |
|
||||
| 适用范围 | AI 过渡层、订单、任务、任务卡、审计和 OPERA 模拟结果 |
|
||||
| 主要读者 | 后端、数据库、测试、后续协作 agent |
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
本文定义 M002 第一阶段后端数据模型草案,用于支撑 SuperAgent 任务结果入站、订单挂靠、任务卡确认、队列顺序、审计和 OPERA 模拟结果。
|
||||
|
||||
本文不是最终建表 SQL。后续写代码前,应按本项目后端规范补充 Flyway migration、Entity 中文注释、Mapper、Repository、Service 和测试。
|
||||
本文不是完整最终模型。当前后端已经按本模型落地第一阶段 Flyway migration、Entity、Mapper、Repository、Service 和测试;后续真实 OPERA、前端页面和 SuperAgent 查询上下文接口仍需继续补充。
|
||||
|
||||
## 2. 设计原则
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
| `PENDING_CONFIRM` | 待用户确认订单归属和任务字段 |
|
||||
| `READY` | 已确认,等待执行 OPERA 模拟 |
|
||||
| `EXECUTING` | 正在执行 OPERA 模拟 |
|
||||
| `FAILED` | OPERA 模拟失败,必须重试或修正后再执行,不能跳过 |
|
||||
| `FAILED` | 任务级失败结束态;第一版 OPERA 单条模拟操作失败时不直接把任务改为该状态,避免按队列规则误放行 |
|
||||
| `COMPLETED` | 任务已完成 |
|
||||
|
||||
说明:
|
||||
@@ -314,19 +314,21 @@
|
||||
| `hotel_id` | `VARCHAR(64)` | 酒店或业务上下文 |
|
||||
| `order_id` | `BIGINT` | 订单 ID |
|
||||
| `task_id` | `BIGINT` | 任务 ID |
|
||||
| `operation_type` | `VARCHAR(128)` | 操作类型,例如创建预订、更新字段、取消订单 |
|
||||
| `operation_status` | `VARCHAR(32)` | 操作状态:`PENDING`、`EXECUTING`、`SUCCESS`、`FAILED` |
|
||||
| `operation_order` | `INT` | 同任务下操作顺序 |
|
||||
| `confirmed_payload_json` | `LONGTEXT` | 生成该操作时使用的确认 payload 快照 |
|
||||
| `business_key_candidates_json` | `LONGTEXT` | 从模拟结果解析出的订单业务号候选 |
|
||||
| `last_failure_reason` | `VARCHAR(512)` | 最近失败原因 |
|
||||
| `retry_count` | `INT` | 已重试次数 |
|
||||
| `operation_sequence` | `INT` | 同任务下操作顺序,从 1 开始 |
|
||||
| `operation_code` | `VARCHAR(64)` | 模拟操作代码,第一版固定 `SIMULATE_PRECHECK` 和 `SIMULATE_WRITE` |
|
||||
| `operation_name` | `VARCHAR(128)` | 模拟操作展示名称 |
|
||||
| `operation_status` | `VARCHAR(32)` | 操作状态:`PENDING`、`SUCCEEDED`、`FAILED` |
|
||||
| `request_payload_json` | `LONGTEXT` | 生成该操作时使用的模拟请求摘要,不保存完整邮件原文 |
|
||||
| `attempt_count` | `INT` | 已执行 attempt 次数 |
|
||||
| `last_attempt_id` | `BIGINT` | 最近一次 attempt ID |
|
||||
| `last_error_message` | `VARCHAR(512)` | 最近一次失败原因摘要 |
|
||||
| `created_at` / `updated_at` | `DATETIME(6)` | 创建和更新时间 |
|
||||
|
||||
索引建议:
|
||||
|
||||
- 普通索引:`hotel_id + task_id + operation_order`
|
||||
- 普通索引:`hotel_id + operation_status + updated_at`
|
||||
- 唯一索引:`hotel_id + task_id + operation_sequence`
|
||||
- 普通索引:`hotel_id + task_id + operation_status`
|
||||
- 普通索引:`hotel_id + order_id + operation_sequence`
|
||||
|
||||
## 12. OPERA 模拟尝试记录表
|
||||
|
||||
@@ -338,35 +340,36 @@
|
||||
| --- | --- | --- |
|
||||
| `id` | `BIGINT` | 尝试记录 ID |
|
||||
| `hotel_id` | `VARCHAR(64)` | 酒店或业务上下文 |
|
||||
| `operation_id` | `BIGINT` | 所属逻辑操作 |
|
||||
| `order_id` | `BIGINT` | 订单 ID |
|
||||
| `task_id` | `BIGINT` | 所属任务 |
|
||||
| `attempt_no` | `INT` | 第几次尝试,从 1 开始 |
|
||||
| `attempt_status` | `VARCHAR(32)` | 尝试状态:`SUCCESS`、`FAILED` |
|
||||
| `operation_id` | `BIGINT` | 所属逻辑操作 |
|
||||
| `attempt_number` | `INT` | 第几次尝试,从 1 开始 |
|
||||
| `attempt_status` | `VARCHAR(32)` | 尝试状态:`SUCCEEDED`、`FAILED` |
|
||||
| `request_payload_json` | `LONGTEXT` | 本次模拟请求 payload |
|
||||
| `response_payload_json` | `LONGTEXT` | 本次模拟响应 payload |
|
||||
| `business_key_candidates_json` | `LONGTEXT` | 本次响应中的业务号候选 |
|
||||
| `failure_reason` | `VARCHAR(512)` | 失败原因 |
|
||||
| `error_message` | `VARCHAR(512)` | 失败原因摘要 |
|
||||
| `started_at` | `DATETIME(6)` | 开始时间 |
|
||||
| `finished_at` | `DATETIME(6)` | 结束时间 |
|
||||
| `created_at` | `DATETIME(6)` | 记录创建时间 |
|
||||
|
||||
索引建议:
|
||||
|
||||
- 唯一索引:`hotel_id + operation_id + attempt_no`
|
||||
- 唯一索引:`hotel_id + operation_id + attempt_number`
|
||||
- 普通索引:`hotel_id + task_id + created_at`
|
||||
- 普通索引:`hotel_id + operation_id + attempt_number`
|
||||
|
||||
规则:
|
||||
|
||||
- 用户不能跳过失败的 OPERA 模拟操作。
|
||||
- 失败后任务进入 `FAILED`,只能通过修正 payload 后重试或重新执行使其成功。
|
||||
- 失败后操作进入 `FAILED`,任务保持未完成;因为队列规则里任务 `FAILED` 视为已结束,第一版不能把 OPERA 操作失败直接落成任务 `FAILED`,避免后续任务被错误放行。
|
||||
- 不允许用户强制把失败任务改成 `COMPLETED`。
|
||||
- 后续真实 OPERA 接入时,应通过 adapter 把真实响应映射到 `response_payload_json` 和 `business_key_candidates_json`。
|
||||
- 后续真实 OPERA 接入时,应通过 adapter 把真实响应映射到 `response_payload_json`,业务号候选字段需在拿到真实结构后再补稳定字段或 JSON 结构。
|
||||
|
||||
## 13. 订单业务号回填
|
||||
|
||||
只有 `NEW_BOOKING` 且 `confirmed_payload_json` 没有可用业务号时,才从 OPERA 模拟成功结果回填订单业务号。
|
||||
只有 `NEW_BOOKING` 且 `confirmed_payload_json` 没有可用业务号时,才需要从 OPERA 成功结果回填订单业务号。
|
||||
|
||||
回填来源暂定为 `business_key_candidates_json`,示例:
|
||||
当前第一版后端不做业务号回填,也没有落地 `business_key_candidates_json` 字段。后续拿到真实 OPERA 返回结构后,再通过低耦合 adapter 解析候选业务号并补充稳定字段或 JSON 结构。候选结构可以参考:
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
| --- | --- |
|
||||
| 文档版本 | 0.2 |
|
||||
| 日期 | 2026-07-07 |
|
||||
| 状态 | 第二版需求草稿 |
|
||||
| 状态 | 第二版需求与后端阶段实现记录 |
|
||||
| 适用范围 | SourceMessage 之后的 AI 过渡层、订单挂靠、任务卡、人工确认、OPERA 模拟操作主流程 |
|
||||
| 主要读者 | 产品、后端、前端、测试、后续协作 agent |
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
本文是 `M002-order-task-workflow-v1.md` 的第二版修正,目标是把本项目已经讨论确认的订单任务主流程,与 2026-07-06 导入的 AI 任务卡契约对齐。
|
||||
|
||||
本文只定义业务边界、数据语义和后续实现约束,不代表已经开始写代码。后续开发前仍需要拆分 checkpoint,并补充接口契约、表结构、状态机、前端页面和测试验收标准。
|
||||
本文定义业务边界、数据语义和后续实现约束。当前后端已经按拆分 checkpoint 实现了 AI 结果接收、订单任务基础流转、任务草稿保存、最终确认、审计列表和 OPERA 模拟骨架;前端页面、真实 OPERA、普通任务切换订单和 SuperAgent 查询上下文接口仍未实现。
|
||||
|
||||
## 2. 本版核心修正
|
||||
|
||||
@@ -427,6 +427,15 @@ Fallback 处理规则:
|
||||
|
||||
一个任务可能产生多条 OPERA 模拟操作。任务详情页应展示每条模拟操作的结果、状态、失败原因、重试次数和最近执行时间。重试必须保留历史记录,不能覆盖原始失败记录。
|
||||
|
||||
第一版后端实现中,任务最终确认后固定生成两条 OPERA 模拟操作:
|
||||
|
||||
| 顺序 | 操作代码 | 中文说明 |
|
||||
| --- | --- | --- |
|
||||
| 1 | `SIMULATE_PRECHECK` | OPERA 模拟预检查 |
|
||||
| 2 | `SIMULATE_WRITE` | OPERA 模拟写入 |
|
||||
|
||||
当前模拟操作只保存请求/响应摘要和 attempt 记录,不接真实 OPERA,也不从模拟结果回填订单业务号。失败时只把对应操作标记为 `FAILED`,任务保持未完成,避免用户绕过失败操作。
|
||||
|
||||
## 16. 审计要求
|
||||
|
||||
以下行为必须记录审计:
|
||||
@@ -462,28 +471,26 @@ Fallback 处理规则:
|
||||
|
||||
本版暂不定义:
|
||||
|
||||
- SuperAgent 调本系统的正式 HTTP 接口契约。
|
||||
- 幂等键到底由 SuperAgent 生成还是本系统生成。
|
||||
- 订单完整状态机。
|
||||
- 任务完整状态机。
|
||||
- SuperAgent 查询上下文接口。
|
||||
- OPERA 模拟结果 JSON 字段名。
|
||||
- 真实 OHIP / OPERA 接口地址、鉴权和返回结构。
|
||||
- 前端具体页面布局和交互细节。
|
||||
- 全量 158 条任务卡字段配置复制版。
|
||||
- Rate Code 和房型规则的代码实现。
|
||||
- 普通任务切换订单接口和前端交互。
|
||||
- 用户身份、权限和真实 actor 注入。
|
||||
|
||||
## 18. 待确认问题
|
||||
|
||||
- SuperAgent 创建任务接口的 URL、Method、Header、鉴权和错误响应格式。
|
||||
- SuperAgent 查询上下文接口暂不在本 checkpoint 实现,但 SuperAgent 侧已经在整理,后续梳理未完成事项时必须持续提醒。
|
||||
- `source_event_index`、批次 item index、`execution_order` 的最终编号规则是否都从 1 开始。
|
||||
- `idempotency_key` 的来源和冲突处理策略。
|
||||
- 订单状态机有哪些稳定状态。
|
||||
- 任务状态机有哪些稳定状态。
|
||||
- SuperAgent 查询上下文接口的 URL、入参、返回字段和鉴权方式。
|
||||
- `Message Notification` 是否需要在前端订单列表上单独标识为只读提醒。
|
||||
- OPERA 模拟结果中 Confirmation No.、Group Code、Block Code、Allotment Code 的具体字段路径。
|
||||
- 临时订单在无任务后是否立即逻辑删除,还是保留一段时间便于追溯。
|
||||
- 用户是否允许强制完成任务;如果允许,需要什么权限和审计原因。
|
||||
- 普通任务切换订单接口何时纳入实现。
|
||||
- 用户身份和权限体系何时接入,审计 `actor` 如何从登录态获取。
|
||||
|
||||
## 19. 后续建议 checkpoint
|
||||
|
||||
@@ -494,7 +501,7 @@ Fallback 处理规则:
|
||||
3. 定义系统主任务类型、任务卡类型、`result_type`、任务状态和订单状态枚举。
|
||||
4. 实现 AI 结果接收、幂等、顺序保存和任务卡创建。
|
||||
5. 实现订单自动挂靠、临时订单创建和人工订单切换。
|
||||
6. 实现任务详情字段展示、编辑、确认和 `confirmed_payload_json`。
|
||||
7. 实现任务队列阻塞规则和 `Message Notification` 只读归档规则。
|
||||
8. 实现 OPERA 模拟操作结果底表、重试和订单业务号回填。
|
||||
6. 实现任务详情字段展示、编辑、确认和 `confirmed_payload_json`。当前后端已实现保存草稿和最终确认接口,前端页面待定。
|
||||
7. 实现任务队列阻塞规则和 `Message Notification` 只读归档规则。当前后端已实现阻塞规则和只读提醒归档的基础能力,前端页面待定。
|
||||
8. 实现 OPERA 模拟操作结果底表、重试和订单业务号回填。当前后端已实现固定两条模拟操作、attempt、执行、重试和审计列表;订单业务号回填待真实 OPERA 返回结构确认后再做。
|
||||
9. 根据前端页面范围实现列表、详情和只读/可处理状态展示。
|
||||
|
||||
Reference in New Issue
Block a user