275 lines
13 KiB
Markdown
275 lines
13 KiB
Markdown
# 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=GRPA2
|
||
```
|
||
|
||
期望:
|
||
- 三个接口均要求 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。 |
|