补充订单列表V4入口回归验证
This commit is contained in:
@@ -2,17 +2,17 @@
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 最近更新 | 2026-07-19 |
|
||||
| 最近更新 | 2026-07-20 |
|
||||
| 当前分支 | `feature/huangting` |
|
||||
| 当前阶段 | M002 V4 入站、多卡模型、持久化基线、入站写入、查询接口、卡片确认、复核解阻、目录校验、订单详情时间线、DB 目录、Lookup API、前端 lookup 接入和目录管理后台 CP1 前后端 |
|
||||
| 当前重点 | M002 V4 已完成 DB 管理目录与 Lookup API V1 后端、前端 V4 多卡字段 lookup 第一版接入,并完成系统设置下 Account / Room Type / Rate Code 目录管理前端 CP1;后续可做测试机联调、真实 PMS / OPERA / OHIP 同步或 SuperAgent 目录供给方案 |
|
||||
| 当前阶段 | M002 V4 入站、多卡模型、持久化基线、入站写入、查询接口、卡片确认、复核解阻、目录校验、订单详情时间线、DB 目录、Lookup API、前端 lookup 接入、目录管理后台 CP1 前后端和订单列表 V4 继续处理入口 |
|
||||
| 当前重点 | M002 V4 已完成订单列表 V4 继续处理入口字段,`GET /api/reservation/orders` 可返回 V4 下一步订单任务、卡片、动作类型、动作状态和 open 数;后续可做测试机联调、真实 PMS / OPERA / OHIP 同步或 SuperAgent 目录供给方案 |
|
||||
|
||||
## 1. 当前 Checkpoint
|
||||
|
||||
- 名称:`M002-V4-CP13-catalog-admin-cp1`
|
||||
- 状态:Done,后端已开放 Account / Room Type / Rate Code 目录管理后台 CP1 接口,前端已在系统设置新增 `/system/reservation-catalogs` 页面;支持列表查询、新增、启用 / 停用;权限使用 `RESERVATION_CATALOG_MANAGE`,强制 Bearer 登录、权限码、酒店访问权和管理审计。
|
||||
- 目标:让测试机和系统设置页面可以维护第一版数据库目录,停用目录不再进入普通 V4 lookup。
|
||||
- 边界:本轮不接真实 PMS / OPERA / OHIP 同步,不做 Market / Source 独立管理页面,不新增 `workflow_reservation_catalog_sync_run`,不做 SuperAgent 目录机器接口,不废弃旧 V2/V3 接口。
|
||||
- 名称:`M002-V4-CP14-order-list-v4-entrypoint`
|
||||
- 状态:Done,订单列表接口已补齐 V4 下一步处理入口字段:`next_v4_order_task_id`、`next_v4_action_card_id`、`next_v4_action_type`、`next_v4_action_status`、`v4_open_order_task_count`。旧 `open_task_count` 和 `next_processable_task_id` 保持兼容。
|
||||
- 目标:让前端订单列表“继续处理”在存在 V4 待处理订单任务时可优先跳转 V4 订单任务详情;无 V4 待处理时继续回退旧 V2/V3 任务入口。
|
||||
- 边界:本轮不改前端页面、不改 V4 确认 / 复核接口、不接真实 OPERA / OHIP、不废弃旧 V2/V3 任务入口、不把 S10/S99 来源通知放进订单列表。
|
||||
|
||||
## 2. 当前优先级
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 文档版本 | 0.6 |
|
||||
| 日期 | 2026-07-19 |
|
||||
| 状态 | CP2 设计已确认;CP3-CP8 已实现;CP11 DB 目录与 Lookup API V1 已实现 |
|
||||
| 文档版本 | 0.7 |
|
||||
| 日期 | 2026-07-20 |
|
||||
| 状态 | CP2 设计已确认;CP3-CP8、CP11、CP13、CP14 已实现 |
|
||||
| 适用范围 | M002 V4 入站后的订单任务、多卡、状态、查询和写操作设计 |
|
||||
| 不适用范围 | V4 复核接口、真实 PMS / OPERA / OHIP、前端页面视觉稿、历史数据迁移 |
|
||||
|
||||
@@ -16,7 +16,7 @@ M002 V4 CP1 已完成 SuperAgent V4 回调包入站解析、基础校验、路
|
||||
|
||||
本文是 CP2 设计文档,用于把 2026-07-18 V4 字段契约落成后续可开发的数据模型和接口草案。
|
||||
|
||||
截至 CP11,后端已实现本文第 10、11 节中的持久化基线,并已把 SuperAgent V4 入站结果写入新表:普通业务包创建 V4 订单任务、来源邮件展示卡、Basic Information 卡和业务卡;V4 S10/S99 创建来源通知。当前已开放 V4 工作台、订单任务列表 / 详情、来源通知详情查询接口、订单详情 V4 订单任务时间线、V4 卡片确认接口、S10/S99 来源通知 ack 接口、V4 `REVIEW_REQUIRED` 卡复核解阻接口、当前酒店数据库目录校验、卡片 `fields[]` 白名单,以及 Account / Room Type / Rate Code lookup API。真实 PMS 同步和目录管理后台继续后置,设计见 `M002-v4-real-catalog-lookup-api-design.md`。
|
||||
截至 CP14,后端已实现本文第 10、11、12 节中的持久化和查询基线,并已把 SuperAgent V4 入站结果写入新表:普通业务包创建 V4 订单任务、来源邮件展示卡、Basic Information 卡和业务卡;V4 S10/S99 创建来源通知。当前已开放 V4 工作台、订单任务列表 / 详情、来源通知详情查询接口、订单详情 V4 订单任务时间线、V4 卡片确认接口、S10/S99 来源通知 ack 接口、V4 `REVIEW_REQUIRED` 卡复核解阻接口、当前酒店数据库目录校验、卡片 `fields[]` 白名单、Account / Room Type / Rate Code lookup API、目录管理后台 CP1,以及订单列表 V4 继续处理入口字段。真实 PMS 同步继续后置,设计见 `M002-v4-real-catalog-lookup-api-design.md`。
|
||||
|
||||
后续如本文与 `M002-v4-agent-callback-field-contract.md` 的字段契约冲突,以字段契约为准;如与安全边界冲突,以 `security-access-control-boundary.md` 为准。
|
||||
|
||||
@@ -389,7 +389,7 @@ uk_reservation_v4_notification_message_batch(hotel_id, source_message_id, ai_bat
|
||||
| V4 草稿表 | V4 已确认不保存草稿 |
|
||||
| V4 OPERA operation 表 | 当前不做真实 OPERA / OHIP,也不生成 OPERA 模拟 |
|
||||
| 技术错误用户任务表 | 技术错误不进入用户任务体系,先用 AI transition 和 dispatch run |
|
||||
| 目录表 | CP11 已新增 `workflow_reservation_catalog_account`、`workflow_reservation_catalog_code`;真实同步 run 和目录管理后台后置 |
|
||||
| 目录表 | CP11 已新增 `workflow_reservation_catalog_account`、`workflow_reservation_catalog_code`;CP13 已完成目录管理后台 CP1;真实同步 run 后置 |
|
||||
|
||||
## 11. Entity / Mapper / Repository 边界草案
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOrderSnapsh
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationTaskDraft;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationV4OrderTaskDraft;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationV4OrderTaskSnapshot;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationV4SourceNotificationDraft;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationV4TaskCardDraft;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationV4TaskCardSnapshot;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationOrderKeyType;
|
||||
@@ -34,9 +35,11 @@ import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationOrderVisi
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationTaskStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4CardStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4CardType;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4NotificationStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4OrderTaskStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4TargetResolutionStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.repository.ReservationAiWorkflowRepository;
|
||||
import cn.nianxx.thhotel.workflows.reservation.repository.ReservationV4SourceNotificationRepository;
|
||||
import cn.nianxx.thhotel.workflows.reservation.repository.ReservationV4WorkflowRepository;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
@@ -86,6 +89,9 @@ class ReservationFrontendQueryControllerTest {
|
||||
@Autowired
|
||||
private ReservationV4WorkflowRepository v4WorkflowRepository;
|
||||
|
||||
@Autowired
|
||||
private ReservationV4SourceNotificationRepository sourceNotificationRepository;
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@@ -640,6 +646,11 @@ class ReservationFrontendQueryControllerTest {
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name(), null, "{}");
|
||||
insertV4TaskCard(basicFirstOrderTask, ReservationV4CardType.ROOM_INFORMATION.name(), "NEW_BOOKING", 1, 30,
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(), "PENDING", "{}");
|
||||
insertV4SourceNotification(
|
||||
source.inboxId(),
|
||||
930000000000004901L,
|
||||
"S10",
|
||||
Instant.parse("2026-07-08T06:45:00Z"));
|
||||
ReservationV4OrderTaskSnapshot laterOrderTask = insertV4OrderTask(
|
||||
930000000000004102L,
|
||||
source,
|
||||
@@ -700,6 +711,15 @@ class ReservationFrontendQueryControllerTest {
|
||||
completedOrderTask.id(),
|
||||
ReservationV4OrderTaskStatus.COMPLETED.name(),
|
||||
completedOrderTask.updatedAt());
|
||||
SourceMessageCaptureResult standaloneNotificationSource = captureSourceMessage(
|
||||
"mail-frontend-order-list-v4-cp14-s99-standalone",
|
||||
"GRP-FRONTEND-V4-CP14-S99 standalone notification",
|
||||
Instant.parse("2026-07-08T11:30:00Z"));
|
||||
insertV4SourceNotification(
|
||||
standaloneNotificationSource.inboxId(),
|
||||
930000000000004902L,
|
||||
"S99",
|
||||
Instant.parse("2026-07-08T11:30:00Z"));
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), get("/api/reservation/orders")
|
||||
.param("hotel_id", HOTEL_ID)
|
||||
@@ -707,6 +727,7 @@ class ReservationFrontendQueryControllerTest {
|
||||
.param("page_num", "1")
|
||||
.param("page_size", "20"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.page.total").value(5))
|
||||
.andExpect(jsonPath("$.items[?(@.order_id=='" + basicFirstOrderId + "')].next_processable_task_id")
|
||||
.value(contains(legacyTaskId.toString())))
|
||||
.andExpect(jsonPath("$.items[?(@.order_id=='" + basicFirstOrderId + "')].v4_open_order_task_count")
|
||||
@@ -857,6 +878,25 @@ class ReservationFrontendQueryControllerTest {
|
||||
now));
|
||||
}
|
||||
|
||||
private void insertV4SourceNotification(
|
||||
Long sourceMessageId,
|
||||
Long aiBatchId,
|
||||
String routeCode,
|
||||
Instant sourceReceivedAt) {
|
||||
sourceNotificationRepository.findOrCreateSourceNotification(new ReservationV4SourceNotificationDraft(
|
||||
HOTEL_ID,
|
||||
sourceMessageId,
|
||||
aiBatchId,
|
||||
null,
|
||||
routeCode,
|
||||
ReservationV4NotificationStatus.ACK_REQUIRED.name(),
|
||||
"""
|
||||
{"route_code":"%s","source_message":{"body":"S10/S99 notification should stay outside orders"}}
|
||||
""".formatted(routeCode),
|
||||
LocalDateTime.ofInstant(sourceReceivedAt, ZoneOffset.UTC),
|
||||
LocalDateTime.ofInstant(sourceReceivedAt.plusSeconds(20), ZoneOffset.UTC)));
|
||||
}
|
||||
|
||||
private ReservationV4TaskCardSnapshot insertV4TaskCard(
|
||||
ReservationV4OrderTaskSnapshot orderTask,
|
||||
String cardType,
|
||||
|
||||
Reference in New Issue
Block a user