350 lines
16 KiB
Markdown
350 lines
16 KiB
Markdown
# M002 Backend Checkpoint Plan 后端开发 Checkpoint 计划
|
||
|
||
## 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 文档版本 | 0.4 |
|
||
| 日期 | 2026-07-12 |
|
||
| 状态 | V2 后端 checkpoint 阶段记录;V3 新开发和当前实现状态以 `M002-order-task-workflow-v3.md` 为准 |
|
||
| 适用范围 | M002 后端实现拆分、交付物和验收标准 |
|
||
| 主要读者 | 后端、测试、产品、后续协作 agent |
|
||
|
||
## 1. 文档定位
|
||
|
||
本文把 `M002-order-task-workflow-v2.md`、`M002-superagent-task-result-api-contract.md` 和 `M002-backend-data-model-design.md` 拆成可执行后端 checkpoint,用于理解当前已阶段实现的 M002 V2 能力。
|
||
|
||
2026-07-11 后,M002 后续新开发必须先读 `M002-order-task-workflow-v3.md`。V3 已确认采用 0711 P0 冻结基线,新增结构化 `S10/S99`、方案 C、type-known manual review 同卡解阻、复核场景订单归属确认和 P1/P2 fail-closed 边界。2026-07-12 后,Parent Group / Allotment 语义按 P0.1 修订,路由总数从 42 调整为 40,完整 Parent split 父事件从旧 `Cancel Booking + linked_parent_release_after_child_split` 改为 `Cancel Allotment + cancel_allotment_control_block`。本文下方 V2 checkpoint 不再覆盖这些新需求。
|
||
|
||
每个 checkpoint 都应先读项目规范,再按本项目包结构和注释要求实现。不要一次性把完整后端做完,也不要在不确定字段或目录归属时先写再重构。
|
||
|
||
## 2. 开发前必读
|
||
|
||
后端开发前必须先读:
|
||
|
||
- `AGENTS.md`
|
||
- `README.md`
|
||
- `docs/project/backend-development-guidelines.md`
|
||
- `docs/import/reusable/backend-development-guidelines.md`
|
||
- `docs/import/reusable/backend-base-structure-pagination-guidelines.md`
|
||
- `docs/import/reusable/alibaba-java-coding-guidelines-summary.md`
|
||
- `docs/project/requirements/M002-order-task-workflow-v2.md`
|
||
- `docs/project/requirements/M002-order-task-workflow-v3.md`
|
||
- `docs/project/requirements/M002-v3-p0.1-parent-group-routing-update.md`
|
||
- `docs/project/requirements/M002-superagent-task-result-api-contract.md`
|
||
- `docs/project/requirements/M002-backend-data-model-design.md`
|
||
- `docs/import/20260711/开发交付_P0冻结基线_2026-07-11/README_交付说明.md`
|
||
- `docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更与路由说明_3.0_to_current.md`
|
||
- `docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更说明_3.0_to_当前版_2026-07-10.xlsx`
|
||
- `docs/import/20260712/开发交付_P0_to_P0.1_增量修订说明_给开发Codex_2026-07-11.md`
|
||
- `docs/import/20260706/开发AI先读_工作顺序.md`
|
||
- `docs/import/20260706/AI输出参数并集字典.xlsx`
|
||
- `docs/import/20260706/任务卡展示编辑矩阵.xlsx`
|
||
|
||
## 3. 代码组织要求
|
||
|
||
后端实现必须继续遵守当前项目包结构习惯:
|
||
|
||
- `control` 放 Controller 具体实现。
|
||
- `service` 放 Service 接口。
|
||
- `service.impl` 放 Service 实现类。
|
||
- `domain` 放 Entity。
|
||
- `mapper` 放 MyBatis Mapper。
|
||
- `repository` 放 Repository 接口和具体实现。
|
||
- `common.dto`、`common.request`、`common.result` 放通用数据载体。
|
||
- `common.enums` 放枚举。
|
||
- 外部系统适配类放在对应 `integrations.<capability>.<provider>.adapter` 包。
|
||
|
||
Controller、Service、Service 实现类的方法必须有中文注释。Entity 字段必须有中文注释。Mapper 继承 MyBatis-Plus 的自带方法不强制写注释,自定义方法按复杂度补充中文注释。
|
||
|
||
## 4. Checkpoint 1:接口契约与安全骨架
|
||
|
||
名称:`m002-cp01-superagent-intake-security`
|
||
|
||
目标:
|
||
|
||
- 建立 SuperAgent 任务结果入站接口骨架。
|
||
- 完成 HMAC 鉴权、请求体大小限制、timestamp 和 nonce 防重放。
|
||
- 暂不创建完整订单任务,只返回受控错误或最小接收结果。
|
||
|
||
建议范围:
|
||
|
||
- 新增配置项:`SUPERAGENT_TASK_RESULT_HMAC_SECRET` 等。
|
||
- 新增 HMAC 校验组件。
|
||
- 新增 nonce 去重存储,第一版可用数据库或可控缓存实现。
|
||
- 新增请求 / 响应 DTO。
|
||
- 新增统一错误响应。
|
||
|
||
验收标准:
|
||
|
||
- 缺失 Header 返回 `401`。
|
||
- timestamp 超时返回 `401`。
|
||
- 签名错误返回 `401`。
|
||
- nonce 重放返回 `409`。
|
||
- 请求体过大返回 `413`。
|
||
- 响应和日志不暴露 secret、签名原文或完整请求体。
|
||
|
||
不做:
|
||
|
||
- 不做业务字段合法性判断。
|
||
- 不执行 OPERA 模拟。
|
||
- 不开发前端页面。
|
||
|
||
## 5. Checkpoint 2:AI 过渡层持久化
|
||
|
||
名称:`m002-cp02-ai-transition-persistence`
|
||
|
||
目标:
|
||
|
||
- 建立 AI 接收批次表和 AI 过渡表。
|
||
- 保存外部 `source_message_id + ai_task_results[] + extraction_warnings[]`,并将外部来源消息 ID 反查为内部 SourceMessage Inbox ID 后落业务表。
|
||
- 实现系统生成幂等键,保证重复提交不重复创建记录。
|
||
|
||
建议范围:
|
||
|
||
- Flyway migration。
|
||
- Entity、Mapper、Repository。
|
||
- 批次幂等键生成。
|
||
- item 幂等键生成。
|
||
- 外部 `source_message_id` 存在性校验:通过 `hotel_id + provider + channel + external_message_id` 查找 SourceMessage Inbox。
|
||
- 保存 AI 原始 JSON 和常用物理列。
|
||
|
||
验收标准:
|
||
|
||
- 同一请求重复提交返回幂等重放,不重复插入。
|
||
- 同一外部 `source_message_id` 不同请求体第一版返回 `409`。
|
||
- 每个 item 保存 `array_index`、`source_event_index` 和 `execution_order`。
|
||
- 保存 `ai_payload_json`,用户后续修改不得覆盖该字段。
|
||
|
||
不做:
|
||
|
||
- 不创建 OPERA 操作。
|
||
- 不实现任务详情编辑。
|
||
|
||
## 6. Checkpoint 3:订单、任务和任务卡最小模型
|
||
|
||
名称:`m002-cp03-order-task-card-model`
|
||
|
||
目标:
|
||
|
||
- 建立订单、任务和任务卡表。
|
||
- 将 AI 过渡记录映射成系统订单、任务和任务卡。
|
||
- 完成主任务类型和任务卡类型映射。
|
||
|
||
建议范围:
|
||
|
||
- 订单状态枚举:`TEMPORARY`、`ACTIVE`、`ENDED`、`LOGIC_DELETED`。
|
||
- 任务状态枚举:`PENDING_CONFIRM`、`READY`、`EXECUTING`、`FAILED`、`COMPLETED`。
|
||
- 系统主任务类型枚举。
|
||
- 任务卡类型枚举。
|
||
- Message Notification 创建临时订单和只读任务卡。
|
||
- Fallback / manual_review 创建临时订单和人工复核任务卡。
|
||
|
||
验收标准:
|
||
|
||
- New Booking 无业务号时创建临时订单。
|
||
- Update / Cancel 可匹配订单时挂已有订单,不可匹配时挂临时订单。
|
||
- Message Notification 挂临时订单,但 `queue_participation=false`。
|
||
- 任务保存 AI 原始 `task_type`、系统主任务类型、任务卡类型和 subtype。
|
||
- 任务初始状态符合数据模型设计。
|
||
|
||
不做:
|
||
|
||
- 不实现用户编辑确认。
|
||
- 不实现 OPERA 模拟。
|
||
|
||
## 7. Checkpoint 4:订单挂靠与队列可处理状态
|
||
|
||
名称:`m002-cp04-order-queue-availability`
|
||
|
||
目标:
|
||
|
||
- 实现订单挂靠规则和同订单任务执行顺序。
|
||
- 实现实时计算任务是否可处理。
|
||
- 不落库 `BLOCKED` 状态。
|
||
|
||
建议范围:
|
||
|
||
- 按 `order_id + execution_order` 查询任务队列。
|
||
- 前置参与队列任务未完成时,后续任务只读。
|
||
- 前置参与队列任务为 `FAILED` 或 `COMPLETED` 时视为结束,不阻塞后续任务。
|
||
- `queue_participation=false` 的任务不阻塞队列。
|
||
- 数据库通过 `hotel_id + order_id + queue_participation + execution_order` 唯一约束兜底,服务层遇到并发队列序号冲突时重新取号重试。
|
||
- 联动任务识别 `parent_source_event_index`、`linked_task_group_id`、`blocked_until_parent_completed`。
|
||
- 第一版可先提供任务详情接口,返回实时可处理状态和只读原因,前端页面后续再定。
|
||
|
||
验收标准:
|
||
|
||
- 同一次 AI 返回多个任务时保留数组顺序。
|
||
- 前置任务未完成时后续任务不能编辑、确认、执行或重试。
|
||
- 前置任务为 `FAILED` 时后续任务不再被阻塞。
|
||
- Message Notification 不阻塞其他任务,也不被其他任务阻塞。
|
||
- 任务切换订单后按目标订单队列重新计算可处理状态。
|
||
|
||
不做:
|
||
|
||
- 不允许用户强制完成前置任务。
|
||
- 不允许跳过失败 OPERA 操作。
|
||
|
||
## 8. Checkpoint 5:任务详情、编辑和确认 payload
|
||
|
||
名称:`m002-cp05-task-detail-confirmed-payload`
|
||
|
||
目标:
|
||
|
||
- 提供任务详情读取接口。
|
||
- 支持用户编辑任务卡字段。
|
||
- 用户确认后生成 `confirmed_payload_json`。
|
||
|
||
建议范围:
|
||
|
||
- 任务详情 Response 包含 AI 原始摘要、任务卡字段、可处理状态和阻塞原因。
|
||
- 第一版任务卡字段矩阵由 `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`、展示条件、必填、枚举、日期、数字等矩阵规则做第一版后端校验。
|
||
- 审计用户字段修改和确认。
|
||
|
||
验收标准:
|
||
|
||
- 不可处理任务详情只能查看,不能编辑或确认。
|
||
- 可处理任务可以保存草稿。
|
||
- 用户确认后任务进入 `READY`。
|
||
- OPERA 参数不得从 `ai_payload_json` 读取。
|
||
- 用户修改不覆盖 AI 原始 JSON。
|
||
- 保存草稿接口:`PUT /api/reservation/tasks/{taskId}/draft`。
|
||
- 最终确认接口:`POST /api/reservation/tasks/{taskId}/confirm`。
|
||
|
||
不做:
|
||
|
||
- 不接真实 OPERA。
|
||
- 不把 Excel 全量字段导入数据库。
|
||
|
||
## 9. Checkpoint 6:人工复核转换和订单迁移
|
||
|
||
名称:`m002-cp06-manual-review-conversion`
|
||
|
||
目标:
|
||
|
||
- 实现 Fallback / manual_review 的人工处理。
|
||
- 支持转为 New / Update / Cancel。
|
||
- 支持任务从临时订单迁移到已有订单。
|
||
|
||
建议范围:
|
||
|
||
- 转换类型接口。
|
||
- 订单切换接口。
|
||
- 临时订单逻辑删除。
|
||
- 转换原因字段第一版允许为空,但必须记录审计。
|
||
- 转为 `UPDATE_BOOKING` 或 `CANCEL_BOOKING` 时目标订单 ID 必填。
|
||
- 审计转换、迁移和删除。
|
||
|
||
验收标准:
|
||
|
||
- 转为 `NEW_BOOKING` 时临时订单可继续保留;如果 AI 原始 `case_keys` 已有 Group Code 或 Confirmation No.,第一版可先以 `AI_CANDIDATE` 激活原临时订单。
|
||
- 转为 `UPDATE_BOOKING` 或 `CANCEL_BOOKING` 时必须选择目标订单。
|
||
- 原临时订单无有效任务后进入 `LOGIC_DELETED`。
|
||
- 所有转换都记录前后快照;原因有则记录,没有则为空。
|
||
|
||
不做:
|
||
|
||
- 不允许绕过前置任务直接完成。
|
||
- 不做 AI 业务合法性二次判断。
|
||
|
||
## 10. Checkpoint 7:OPERA 模拟操作与重试
|
||
|
||
名称:`m002-cp07-opera-simulation-results`
|
||
|
||
目标:
|
||
|
||
- 建立 OPERA 模拟逻辑操作和 attempt 记录。
|
||
- 支持执行、失败、重试和结果展示。
|
||
- 支持 New Booking 在必要时回填订单业务号。
|
||
|
||
建议范围:
|
||
|
||
- 从 `confirmed_payload_json` 生成模拟操作。
|
||
- 第一版每个已确认任务固定生成两条 OPERA 模拟操作,后续接真实 OPERA 时再按任务类型扩展。
|
||
- 每次执行或重试新增 attempt。
|
||
- 模拟操作失败时只将该 `operation` 标记为 `FAILED`,任务不进入 `FAILED`,避免按队列规则误判为已结束并跳过失败 OPERA 操作。
|
||
- 全部必要操作成功后任务进入 `COMPLETED`。
|
||
- 第一版只保存模拟请求/响应摘要,不做 New Booking 业务号回填;订单表已预留 `business_key_source`、`business_key_backfilled_at` 等字段,后续真实 OPERA 或明确模拟返回结构后再写入。
|
||
|
||
验收标准:
|
||
|
||
- 未确认任务不能执行 OPERA 模拟。
|
||
- 不可处理任务不能执行 OPERA 模拟。
|
||
- 失败操作不能跳过。
|
||
- 用户不能强制完成任务。
|
||
- 重试不覆盖历史 attempt。
|
||
- 执行接口:`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:审计、查询和收口
|
||
|
||
名称:`m002-cp08-audit-query-hardening`
|
||
|
||
目标:
|
||
|
||
- 补齐审计查询、列表筛选、安全收口和回归测试。
|
||
|
||
建议范围:
|
||
|
||
- 订单任务审计查询。
|
||
- 任务列表基础筛选。
|
||
- 订单详情下任务时间线。
|
||
- 前端 P0 任务列表 / 工作台接口:`GET /api/reservation/tasks`。
|
||
- 前端 P0 订单详情与任务时间线接口:`GET /api/reservation/orders/{orderId}`。
|
||
- 安全日志检查。
|
||
- 关键接口集成测试。
|
||
|
||
验收标准:
|
||
|
||
- 能追溯 AI 接收、任务创建、订单挂靠、用户修改、确认、迁移、OPERA 模拟和重试。
|
||
- 前端可通过 `GET /api/reservation/tasks` 获取任务摘要、订单展示键、来源消息主题和实时可处理状态。
|
||
- 前端可通过 `GET /api/reservation/orders/{orderId}` 获取订单摘要和同订单任务时间线。
|
||
- 列表不返回完整 AI payload、邮件正文、附件 URL 或 Secret。
|
||
- 所有关键路径有测试覆盖。
|
||
- `./mvnw test` 通过,或明确说明环境问题。
|
||
|
||
当前实现记录:
|
||
|
||
- 已实现 `GET /api/reservation/tasks` 第一版,支持酒店、订单、任务类型、任务状态、任务 subtype、任务所属订单状态、队列参与、关键词和分页筛选。
|
||
- 已实现 `GET /api/reservation/orders/{orderId}` 第一版,支持返回订单摘要和任务时间线,`include_tasks=false` 时只返回订单摘要。
|
||
- 两个接口均复用同订单队列可处理状态计算,`FAILED` 和 `COMPLETED` 视为结束,不阻塞后续任务。
|
||
- 已补齐 `GET /api/reservation/tasks` 来源邮件会话摘要字段:`source_sender_summary`、`source_received_at`、`external_conversation_id`、`conversation_message_count`。
|
||
- 已补齐 `GET /api/reservation/orders/{orderId}` 的 `tasks[]` 来源邮件会话摘要字段。
|
||
- 已补齐 `GET /api/reservation/tasks/{taskId}` 顶层来源邮件会话字段,并在 `fields[]` 透出 `result_type`、`task_type`、`task_subtype`、`default_value_source`。
|
||
- 已实现订单列表接口 `GET /api/reservation/orders`,默认查询全部订单状态,支持酒店、订单状态、Group Code、Confirmation No.、关键词和分页筛选;`keyword` 可匹配订单字段,也可匹配来源消息安全摘要命中的 SourceMessage ID;`open_task_count` 排除 `COMPLETED` 和 `FAILED`;订单列表排序已改为读取 `workflow_reservation_order.latest_activity_at`,避免列表查询每次聚合全量任务。
|
||
- 已实现邮件会话详情接口 `GET /api/source-messages/{sourceMessageId}/conversation`,根据 SourceMessage 定位外部会话,返回完整 text/html、`html_body_sanitized`、`html_render_mode`、附件外链、内联图片、来源摘要和关联订单 / 任务摘要;原文读取审计由后端内部写入,前端展示 HTML 时优先使用清洗字段。
|
||
- 已实现 dev/test 受控演示数据 seed 接口 `POST /api/system/reservation/demo-data`,默认关闭,需配置 `reservation.demo-data.enabled=true` 和访问口令;生成真实落库的任务列表、订单列表、订单详情、任务详情和邮件会话详情演示数据。
|
||
- Message Notification 独立列表 / 详情、任务卡前端字段白名单独立接口继续后置;第一版分别复用任务列表 / 任务详情和 `fields[]` 元数据。
|
||
|
||
## 12. 建议开发节奏
|
||
|
||
建议一次只做一个 checkpoint。每个 checkpoint 完成后:
|
||
|
||
- 先自查是否符合项目包结构和中文注释规范。
|
||
- 运行相关测试。
|
||
- 做 code review。
|
||
- 再进入下一个 checkpoint。
|
||
|
||
如果实现过程中遇到以下情况,必须先暂停确认:
|
||
|
||
- 订单状态需要新增第五种。
|
||
- 任务状态需要新增新状态。
|
||
- OPERA 模拟结果字段需要写死真实路径。
|
||
- Excel 字段矩阵需要从代码配置改成数据库配置。
|
||
- 某个类不知道应该放在哪个包。
|
||
- 需要调整已确认的 SuperAgent 接口契约。
|