实现V4目录管理后台CP1后端

This commit is contained in:
andy
2026-07-19 17:56:08 +07:00
parent 22767e194d
commit f2c2616ab0
23 changed files with 1958 additions and 31 deletions

View File

@@ -0,0 +1,270 @@
# M002 V4 测试机冒烟清单
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 0.1 |
| 日期 | 2026-07-19 |
| 状态 | 测试机 V4 前后端联调冒烟清单 |
| 适用范围 | 登录、酒店权限、V4 工作台、V4 订单任务详情、目录 lookup、卡片确认、复核解阻、S10/S99 ack、订单详情 V4 时间线 |
| 不适用范围 | 真实 OPERA / OHIP、目录同步、旧 V2/V3 全量回归、前端视觉验收 |
## 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. 冒烟结论记录
建议每次测试机发版后记录:
| 项目 | 结果 | 备注 |
| --- | --- | --- |
| 登录与酒店权限 | 待测 | |
| V4 工作台 | 待测 | |
| V4 订单任务详情 | 待测 | |
| Account Lookup | 待测 | |
| Room Type Lookup | 待测 | |
| Rate Code Lookup | 待测 | |
| Basic Information 确认 | 待测 | |
| 业务卡确认 | 待测 | |
| REVIEW_REQUIRED 复核解阻 | 待测 | |
| S10/S99 ack | 待测 | |
| 订单详情 V4 时间线 | 待测 | |
| 目录管理 CP1 | 待测 | |