Files
th-hotel-simple/docs/project/requirements/M002-v4-test-machine-smoke-checklist.md
2026-07-20 15:16:21 +07:00

275 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# M002 V4 测试机冒烟清单
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 0.1 |
| 日期 | 2026-07-19 |
| 状态 | 测试机 V4 前后端联调冒烟清单 |
| 适用范围 | 登录、酒店权限、V4 工作台、V4 订单任务详情、目录 lookup、卡片确认、复核解阻、S10/S99 ack、订单详情 V4 时间线 |
| 不适用范围 | 真实 OPERA / OHIP、目录同步、旧 V2/V3 全量回归、M011 CP4、前端视觉验收 |
## 1. 测试前置
1. 测试机后端使用最新包Flyway 至少执行到 V24。
2. `platform_hotel` 单酒店阶段只能有一家 `ACTIVE` 酒店,测试常用 `HOTEL-TEST`
3. 测试账号可以登录,并拥有目标酒店访问权。
4. 普通 V4 业务测试账号至少需要:
- `RESERVATION_TASK_READ`
- `RESERVATION_ORDER_READ`
- `RESERVATION_TASK_CONFIRM`
- `RESERVATION_MANUAL_REVIEW_RESOLVE`
5. 目录管理测试账号需要:
- `RESERVATION_CATALOG_MANAGE`
- 目标酒店访问权
6. 当前酒店已存在 Account、Room Type、Rate Code 目录。若为空,先检查 `workflow_reservation_catalog_account``workflow_reservation_catalog_code`
7. 准备三类 V4 测试数据:
- 普通业务包:至少包含 Basic Information 和一张业务卡。
- `REVIEW_REQUIRED` 业务包:例如未知 Account、未知 Room Type 或缺失字段。
- S10/S99 来源通知:不创建订单任务,只进入来源通知模型。
## 2. 冒烟步骤
### 2.1 登录与酒店权限
步骤:
1. 打开前端登录页。
2. 使用测试账号登录。
3. 选择或确认当前酒店为 `HOTEL-TEST`
期望:
- 登录成功后前端能拿到 Bearer token。
- 当前酒店在用户可访问酒店列表中。
- 使用无酒店权限账号访问 V4 接口时返回 `HOTEL_ACCESS_DENIED`
常见失败:
- `AUTH_TOKEN_REQUIRED`:前端未带 Bearer token。
- `AUTH_SESSION_INVALID`token 过期或后端重启导致会话失效。
- `HOTEL_ACCESS_DENIED`:用户没有目标酒店访问权,或请求 `hotel_id` 与当前账号不匹配。
### 2.2 V4 工作台
接口:
```text
GET /api/reservation/workbench-items?hotel_id=HOTEL-TEST&page_num=1&page_size=20
```
期望:
- 普通 V4 业务订单任务可见。
- S10/S99 来源通知可见。
- 列表不返回邮件正文、附件 URL、AI 原始 payload。
- 默认排序为最新来源消息在前;同一来源时间下按更新时间、创建时间和数字 ID 稳定倒序。
常见失败:
- 列表为空:先确认 SuperAgent 回调是否写入 V4 表,或是否只有旧 V2/V3 数据。
- S10/S99 不可见:检查 `workflow_reservation_v4_source_notification` 是否有记录。
### 2.3 V4 订单任务详情
接口:
```text
GET /api/reservation/order-tasks/{orderTaskId}
```
期望:
- 返回 `order_task``source_message_summary``source_message_card``basic_information_card``business_cards[]``card_counts``availability`
- Basic Information 卡在未确认前应可确认。
- 业务卡在 Basic Information 未确认前应只读,`readonly_reason_code` 能说明原因。
- `fields[]` 是前端展示和编辑白名单,前端不自行补字段。
常见失败:
- 详情 404检查 `orderTaskId` 是否来自 V4 工作台,不要拿旧任务 ID 调 V4 详情。
- 卡片无法确认:先看 `availability``readonly_reason_code`
### 2.4 Account / Room Type / Rate Code Lookup
接口:
```text
GET /api/reservation/lookups/accounts?hotel_id=HOTEL-TEST&keyword=QBD
GET /api/reservation/lookups/room-types?hotel_id=HOTEL-TEST&keyword=RM2
GET /api/reservation/lookups/rate-codes?hotel_id=HOTEL-TEST&keyword=GROUP
```
期望:
- 三个接口均要求 Bearer token 和 `RESERVATION_TASK_READ`
- 只返回当前酒店 `ACTIVE` 目录项。
- `keyword` 查不到时 `items=[]`,但不代表目录未初始化;应结合 `catalog_source``catalog_version``warnings[]` 判断。
- 前端确认 / 复核时只提交 `code`,不要提交显示名或目录完整对象。
常见失败:
- 查不到新增目录:确认目录状态是否为 `ACTIVE`
- 前端提交未知 code 后 400以后端目录校验为准重新选择 lookup 返回项。
### 2.5 Basic Information 确认
接口:
```text
POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm
```
期望:
- 请求带当前卡片 `version`
- Basic Information 确认成功后卡片状态进入 `CONFIRMED`
- 确认后卡片锁定,不允许重复确认。
- 业务卡的可处理性随详情刷新更新。
常见失败:
- `V4_CARD_BASIC_INFORMATION_REQUIRED`:前端先确认了业务卡,应先确认 Basic Information。
- `V4_FIELD_VALIDATION_FAILED`Account 不存在、Room Type / Rate Code 不在当前酒店 ACTIVE 目录。
- 版本冲突:刷新详情后使用最新 `version`
### 2.6 业务卡确认
接口:
```text
POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm
```
期望:
- Basic Information 已确认后,普通业务卡可确认。
- 第一版不强制所有业务卡逐张顺序确认。
- 成功后卡片 `CONFIRMED`,写入 `confirmed_payload_json``confirmed_at``confirmed_by`
常见失败:
- 目录字段错误:看接口 `details[]` 和卡片 `fields[].validation_errors`,按字段 pointer 修正。
- 只读卡无法确认:检查是否是来源邮件展示卡、技术错误卡或 S10/S99 通知。
### 2.7 REVIEW_REQUIRED 复核解阻
接口:
```text
POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution
```
期望:
- 只用于 `card_status=REVIEW_REQUIRED` 的 V4 卡。
- 请求带当前卡片 `version`
- `field_overrides[].field_pointer` 必须来自当前卡可编辑字段。
- 订单归属未解决时,`confirmed_order_id` 必须是当前酒店真实可见订单。
- 成功后卡片进入 `CONFIRMED``review_status=RESOLVED`
常见失败:
- `TASK_REVIEW_POINTER_INVALID` 或 V4 对应非法 pointer 错误:前端提交了只读字段、对象根节点或不存在字段。
- `HOTEL_ACCESS_DENIED`:确认的订单或任务不属于当前用户酒店。
- 复核后仍失败:检查修正后的 Account / Room Type / Rate Code 是否在 ACTIVE 目录中。
### 2.8 S10/S99 来源通知 Ack
接口:
```text
POST /api/reservation/source-notifications/{notificationId}/ack
```
期望:
- 只用于 V4 `route_code=S10/S99` 来源通知。
- 请求带当前通知 `version`
- 成功后 `notification_status=ACKED`,写 `ack_by``ack_at`
- 重复 ack 幂等返回当前状态,不新增业务任务或订单。
常见失败:
- 通知详情 404确认从 V4 工作台拿的是来源通知 ID不是订单任务 ID。
- ack 按钮不显示:检查详情 `availability.ackable`
### 2.9 订单详情 V4 时间线
接口:
```text
GET /api/reservation/orders/{orderId}
```
期望:
- 返回旧 `tasks[]` 兼容字段。
- 返回 V4 `v4_order_tasks[]` 时间线。
- 每项包含 `order_task_id``order_ref``order_task_status``card_counts``source_message_summary``source_received_at``created_at``updated_at``latest_activity_at`
- S10/S99 来源通知不进入订单列表,也不进入订单详情 V4 时间线。
常见失败:
- 时间线为空:确认该 V4 订单任务是否已经绑定到当前订单。
- 订单详情打不开:检查订单所属酒店和当前用户酒店访问权。
## 3. 目录管理后台 CP1 冒烟
接口:
```text
GET /api/admin/reservation/catalogs/accounts
POST /api/admin/reservation/catalogs/accounts
PUT /api/admin/reservation/catalogs/accounts/{accountId}/status
GET /api/admin/reservation/catalogs/room-types
POST /api/admin/reservation/catalogs/room-types
PUT /api/admin/reservation/catalogs/room-types/{catalogId}/status
GET /api/admin/reservation/catalogs/rate-codes
POST /api/admin/reservation/catalogs/rate-codes
PUT /api/admin/reservation/catalogs/rate-codes/{catalogId}/status
```
期望:
- 全部接口要求 Bearer token、`RESERVATION_CATALOG_MANAGE` 和目标酒店访问权。
- 列表支持 `hotel_id``keyword``status``page_num``page_size`
- 新增目录默认 `ACTIVE``catalog_source=SYSTEM_MANAGED`
- 停用后管理列表仍可按 `status=DISABLED` 查到,但普通 lookup 不再返回。
- 启用后普通 lookup 恢复返回。
常见失败:
- `ADMIN_PERMISSION_DENIED`:角色未配置 `RESERVATION_CATALOG_MANAGE`
- `RESERVATION_CATALOG_CONFLICT`:当前酒店已有相同 code。
- `RESERVATION_CATALOG_INVALID_REQUEST`状态、JSON、必填字段或 Market / Source code 不合法。
## 4. 排查 SQL
```sql
SELECT hotel_id, account_code, account_name, market_code, source_code, status, source_system, catalog_version, updated_at
FROM workflow_reservation_catalog_account
WHERE hotel_id = 'HOTEL-TEST'
ORDER BY account_code;
SELECT hotel_id, catalog_type, code, display_name, status, source_system, catalog_version, updated_at
FROM workflow_reservation_catalog_code
WHERE hotel_id = 'HOTEL-TEST'
ORDER BY catalog_type, sort_order, code;
SELECT id, hotel_id, order_ref, order_task_status, source_message_id, created_at, updated_at
FROM workflow_reservation_v4_order_task
WHERE hotel_id = 'HOTEL-TEST'
ORDER BY updated_at DESC, id DESC;
SELECT id, hotel_id, route_code, notification_status, source_message_id, created_at, updated_at
FROM workflow_reservation_v4_source_notification
WHERE hotel_id = 'HOTEL-TEST'
ORDER BY updated_at DESC, id DESC;
```
## 5. 冒烟结论记录
建议每次测试机发版后记录:
| 项目 | 结果 | 备注 |
| --- | --- | --- |
| 登录与酒店权限 | 通过 | 2026-07-20 smoke`/api/auth/me` 返回 `HOTEL-TEST` 和 V4 权限;未带 Bearer 访问 V4 工作台返回 401错误 `hotel_id` 访问工作台和订单详情返回 403。 |
| V4 工作台 | 通过 | `GET /api/reservation/workbench-items` 返回 5 条,包含 `ORDER_TASK``SOURCE_NOTIFICATION`;列表未发现邮件正文、附件 URL、AI 原始 payload 字段。 |
| V4 订单任务列表 | 通过 | `GET /api/reservation/order-tasks` 返回业务订单任务,不包含来源通知;`card_status=REVIEW_REQUIRED` 查询当前测试数据返回 0 条。 |
| V4 订单任务详情 | 通过 | `GET /api/reservation/order-tasks/2079096313548677122` 返回 `source_message_card``basic_information_card``business_cards[]``fields[]``availability`Basic 未确认前业务卡 `readonly_reason_code=PRIOR_CARD_NOT_CONFIRMED`。 |
| Account Lookup | 通过 | `GET /api/reservation/lookups/accounts` 返回 3 条 ACTIVE Account。 |
| Room Type Lookup | 通过 | `GET /api/reservation/lookups/room-types` 返回 8 条 ACTIVE Room Type。 |
| Rate Code Lookup | 通过 | `GET /api/reservation/lookups/rate-codes` 返回 5 条 ACTIVE Rate Code`stale=false`;有固定种子 warning符合当前第一版目录状态。 |
| Basic Information 确认 | 通过 | 使用 `version=0` 确认 Basic Information 成功,卡片进入 `CONFIRMED`version 递增到 1业务卡随后变为可确认。 |
| 业务卡确认 | 通过 | 使用 `version=0` 确认 Room Information 成功,订单任务进入 `COMPLETED`,工作台显示 `display_status=COMPLETED`,订单列表 `open_work_item_count=0``v4_open_order_task_count=0`。 |
| REVIEW_REQUIRED 复核解阻 | 未覆盖写操作 | 当前测试机没有 `REVIEW_REQUIRED` 待复核卡;已用历史完成记录 `2078906313578168322` 验证详情和 `V4_CARD_REVIEW_RESOLVE` 审计查询返回脱敏结果。下一轮需要准备一条待复核测试数据后再跑写操作。 |
| S10/S99 来源通知详情 | 通过 | 工作台包含 S10 与 S99 来源通知;详情接口返回通知摘要和来源消息卡,不返回订单任务或业务卡。 |
| S10/S99 ack | 通过 | 对已 ACK 的 S10 通知重复 ack 返回 200 且保持 `ACKED`验证幂等S10/S99 均未创建订单,也未进入订单列表。 |
| V4 业务审计 | 通过 | 订单任务确认审计和来源通知 ack 审计接口返回 200快照未发现 `ai_payload_json`、正文、HTML、附件 URL、token、secret 等敏感字段。 |
| 订单详情 V4 总览 / 时间线 | 失败 | 测试机 `GET /api/reservation/orders/2079096313393487874` 返回 200但响应仍只有 `order`、旧 `tasks[]`、基础 `v4_order_tasks[]``warnings`;缺少 CP15.1 要求的 `order_overview``next_v4_action``related_source_messages[]``v4_order_tasks[].cards[]`。本地最新后端已有测试覆盖,优先排查测试机是否部署了包含 CP15.1 的最新包。 |
| M011 AgentBus Booking Excel 预处理观察 | 未覆盖 outbound payload | `GET /api/system/agentbus-probe` 显示测试机 AgentBus 已连接且已捕获 frame当前普通 HTTP 接口不暴露发给 SuperAgent 的 outbound payload无法仅通过本次 smoke 确认 `attachment_extractions[]` 是否追加。未推进 M011 CP4未新增解析批次表或行级持久化。 |
| 目录管理 CP1 | 未覆盖 | 本 checkpoint 聚焦 V4 主流程联调;目录管理后台另行 smoke。 |