实现M002 V4入站写入新模型
This commit is contained in:
@@ -1030,6 +1030,172 @@ class SuperAgentTaskResultControllerTest {
|
||||
AND ai_payload_json LIKE '%"v4_message_event"%'
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(transitionCount).isEqualTo(2L);
|
||||
|
||||
Long v4OrderTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
AND order_ref = 'order-1'
|
||||
AND order_context_index = 1
|
||||
AND target_booking_type = 'GROUP'
|
||||
AND target_locator_type = 'GROUP_CODE'
|
||||
AND target_locator_value = 'GRP-V4-001'
|
||||
AND target_resolution_status = 'RESOLVED'
|
||||
AND order_task_status = 'OPEN'
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(v4OrderTaskCount).isEqualTo(1L);
|
||||
|
||||
List<String> v4CardTypes = jdbcTemplate.queryForList("""
|
||||
SELECT card_type
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
ORDER BY card_sort_order, source_event_index
|
||||
""", String.class, source.inboxId());
|
||||
assertThat(v4CardTypes).containsExactly(
|
||||
"SOURCE_MESSAGE_DISPLAY",
|
||||
"BASIC_INFORMATION",
|
||||
"ROOM_INFORMATION",
|
||||
"PAYMENT");
|
||||
|
||||
Long v4CardStatusCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
AND (
|
||||
(card_type = 'SOURCE_MESSAGE_DISPLAY' AND card_status = 'READONLY' AND source_event_index = 0)
|
||||
OR (card_type = 'BASIC_INFORMATION' AND card_status = 'PENDING_CONFIRM' AND source_event_index = 0)
|
||||
OR (card_type = 'ROOM_INFORMATION' AND card_status = 'PENDING_CONFIRM' AND source_event_index = 1)
|
||||
OR (card_type = 'PAYMENT' AND card_status = 'PENDING_CONFIRM' AND source_event_index = 2)
|
||||
)
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(v4CardStatusCount).isEqualTo(4L);
|
||||
|
||||
String sourceDisplayPayload = jdbcTemplate.queryForObject("""
|
||||
SELECT display_payload_json
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
AND card_type = 'SOURCE_MESSAGE_DISPLAY'
|
||||
LIMIT 1
|
||||
""", String.class, source.inboxId());
|
||||
assertThat(sourceDisplayPayload)
|
||||
.contains("att-pay-1")
|
||||
.contains("payment-slip.jpg")
|
||||
.doesNotContain("https://oss.example.test");
|
||||
|
||||
mockMvc.perform(signedPost(body, "nonce-v4-business-root-replay-001"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.idempotent_replay").value(true));
|
||||
Long replayOrderTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
Long replayCardCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(replayOrderTaskCount).isEqualTo(1L);
|
||||
assertThat(replayCardCount).isEqualTo(4L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateV4OrderTasksForMultipleOrderRefs() throws Exception {
|
||||
SourceMessageCaptureResult source = captureSourceMessage("mail-v4-two-order-refs-001");
|
||||
String body = v4TwoOrderRefsBody("mail-v4-two-order-refs-001");
|
||||
|
||||
mockMvc.perform(signedPost(body, "nonce-v4-two-order-refs-001"))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.accepted_count").value(2))
|
||||
.andExpect(jsonPath("$.items[0].execution_order").value(1))
|
||||
.andExpect(jsonPath("$.items[1].execution_order").value(1));
|
||||
|
||||
List<String> orderRefs = jdbcTemplate.queryForList("""
|
||||
SELECT order_ref
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
ORDER BY order_context_index
|
||||
""", String.class, source.inboxId());
|
||||
Long resolvedOrderTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
AND target_resolution_status = 'RESOLVED'
|
||||
""", Long.class, source.inboxId());
|
||||
Long cardCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(orderRefs).containsExactly("order-1", "order-2");
|
||||
assertThat(resolvedOrderTaskCount).isEqualTo(2L);
|
||||
assertThat(cardCount).isEqualTo(6L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldKeepV4BookingCodeOrderTaskUnresolvedUntilBindingCheckpoint() throws Exception {
|
||||
SourceMessageCaptureResult source = captureSourceMessage("mail-v4-fit-booking-code-001");
|
||||
String body = v4FitBookingCodeBody("mail-v4-fit-booking-code-001");
|
||||
|
||||
mockMvc.perform(signedPost(body, "nonce-v4-fit-booking-code-001"))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.accepted_count").value(1))
|
||||
.andExpect(jsonPath("$.items[0].order_status").value("TEMPORARY"));
|
||||
|
||||
Long unresolvedCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
AND target_locator_type = 'BOOKING_CODE'
|
||||
AND target_locator_value = 'BK-V4-FIT-001'
|
||||
AND target_resolution_status = 'UNRESOLVED'
|
||||
AND order_id IS NULL
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(unresolvedCount).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldChooseResolvedV4TargetWhenEarlierEventIsUnresolved() throws Exception {
|
||||
SourceMessageCaptureResult source = captureSourceMessage("mail-v4-unresolved-then-resolved-001");
|
||||
String body = v4UnresolvedThenResolvedBody("mail-v4-unresolved-then-resolved-001");
|
||||
|
||||
mockMvc.perform(signedPost(body, "nonce-v4-unresolved-then-resolved-001"))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.accepted_count").value(2))
|
||||
.andExpect(jsonPath("$.items[0].route_code").value("R04_UPDATE_BOOKING_AMENDMENT_REVIEW"))
|
||||
.andExpect(jsonPath("$.items[1].route_code").value("R10_PAYMENT_EVIDENCE_NORMAL"));
|
||||
|
||||
Long resolvedCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
AND order_ref = 'order-1'
|
||||
AND target_locator_type = 'GROUP_CODE'
|
||||
AND target_locator_value = 'GRP-V4-RESOLVED-LATER-001'
|
||||
AND target_resolution_status = 'RESOLVED'
|
||||
AND order_id IS NOT NULL
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(resolvedCount).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMarkV4BasicInformationCardReviewRequired() throws Exception {
|
||||
SourceMessageCaptureResult source = captureSourceMessage("mail-v4-basic-review-001");
|
||||
String body = v4BasicInformationReviewBody("mail-v4-basic-review-001");
|
||||
|
||||
mockMvc.perform(signedPost(body, "nonce-v4-basic-review-001"))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.accepted_count").value(1));
|
||||
|
||||
Long basicReviewCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
AND card_type = 'BASIC_INFORMATION'
|
||||
AND card_status = 'REVIEW_REQUIRED'
|
||||
AND review_status = 'PENDING'
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(basicReviewCount).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1080,10 +1246,23 @@ class SuperAgentTaskResultControllerTest {
|
||||
)
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(transitionCount).isEqualTo(3L);
|
||||
|
||||
List<String> v4CardTypes = jdbcTemplate.queryForList("""
|
||||
SELECT card_type
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
ORDER BY card_sort_order, source_event_index
|
||||
""", String.class, source.inboxId());
|
||||
assertThat(v4CardTypes).containsExactly(
|
||||
"SOURCE_MESSAGE_DISPLAY",
|
||||
"BASIC_INFORMATION",
|
||||
"ROOM_INFORMATION",
|
||||
"TRACE_RESERVATION_NOTES",
|
||||
"ROOMING_LIST");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateReadOnlyTaskForV4S10WithoutLegacyResultType() throws Exception {
|
||||
void shouldCreateSourceNotificationForV4S10WithoutLegacyTask() throws Exception {
|
||||
SourceMessageCaptureResult source = captureSourceMessage("mail-v4-s10-entry-result-001");
|
||||
String body = v4S10Body("mail-v4-s10-entry-result-001");
|
||||
|
||||
@@ -1094,17 +1273,63 @@ class SuperAgentTaskResultControllerTest {
|
||||
.andExpect(jsonPath("$.items[0].route_code").value("S10"))
|
||||
.andExpect(jsonPath("$.items[0].system_process_category").value("SOURCE_MESSAGE_NOTIFICATION"))
|
||||
.andExpect(jsonPath("$.items[0].system_task_type").value("SOURCE_MESSAGE_ONLY"))
|
||||
.andExpect(jsonPath("$.items[0].task_status").value("COMPLETED"));
|
||||
.andExpect(jsonPath("$.items[0].task_id").doesNotExist())
|
||||
.andExpect(jsonPath("$.items[0].task_status").doesNotExist());
|
||||
|
||||
Long transitionCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_ai_transition
|
||||
WHERE source_message_id = ?
|
||||
AND result_type = 'source_message_review_notification'
|
||||
AND ai_task_type = 'S10'
|
||||
AND ai_task_type = 'Message Notification'
|
||||
AND task_subtype = 'S10'
|
||||
AND route_code = 'S10'
|
||||
""", Long.class, source.inboxId());
|
||||
Long legacyTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_task
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
Long sourceNotificationCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_source_notification
|
||||
WHERE source_message_id = ?
|
||||
AND route_code = 'S10'
|
||||
AND notification_status = 'ACK_REQUIRED'
|
||||
AND raw_payload_json LIKE '%"route_code":"S10"%'
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(transitionCount).isEqualTo(1L);
|
||||
assertThat(legacyTaskCount).isZero();
|
||||
assertThat(sourceNotificationCount).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateSourceNotificationForV4S99WithoutLegacyTask() throws Exception {
|
||||
SourceMessageCaptureResult source = captureSourceMessage("mail-v4-s99-entry-result-001");
|
||||
String body = v4S99Body("mail-v4-s99-entry-result-001");
|
||||
|
||||
mockMvc.perform(signedPost(body, "nonce-v4-s99-entry-result-001"))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.source_message_id").value("mail-v4-s99-entry-result-001"))
|
||||
.andExpect(jsonPath("$.accepted_count").value(1))
|
||||
.andExpect(jsonPath("$.items[0].route_code").value("S99"))
|
||||
.andExpect(jsonPath("$.items[0].system_process_category").value("SOURCE_MESSAGE_NOTIFICATION"))
|
||||
.andExpect(jsonPath("$.items[0].task_id").doesNotExist());
|
||||
|
||||
Long legacyTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_task
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
Long sourceNotificationCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_source_notification
|
||||
WHERE source_message_id = ?
|
||||
AND route_code = 'S99'
|
||||
AND notification_status = 'ACK_REQUIRED'
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(legacyTaskCount).isZero();
|
||||
assertThat(sourceNotificationCount).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1131,8 +1356,20 @@ class SuperAgentTaskResultControllerTest {
|
||||
AND system_process_category = 'ADAPTER_CONTRACT_ERROR'
|
||||
AND adapter_error_code = 'V4_ROOT_CONTRACT_INVALID'
|
||||
""", Long.class, source.inboxId());
|
||||
Long v4OrderTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
Long v4NotificationCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_source_notification
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(taskCount).isZero();
|
||||
assertThat(adapterErrorCount).isEqualTo(1L);
|
||||
assertThat(v4OrderTaskCount).isZero();
|
||||
assertThat(v4NotificationCount).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1186,8 +1423,14 @@ class SuperAgentTaskResultControllerTest {
|
||||
AND system_process_category = 'ADAPTER_CONTRACT_ERROR'
|
||||
AND adapter_error_code = 'PAYMENT_ATTACHMENT_ID_NOT_FOUND'
|
||||
""", Long.class, source.inboxId());
|
||||
Long v4OrderTaskCount = jdbcTemplate.queryForObject("""
|
||||
SELECT COUNT(*)
|
||||
FROM workflow_reservation_v4_order_task
|
||||
WHERE source_message_id = ?
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(taskCount).isZero();
|
||||
assertThat(adapterErrorCount).isEqualTo(1L);
|
||||
assertThat(v4OrderTaskCount).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1218,6 +1461,17 @@ class SuperAgentTaskResultControllerTest {
|
||||
""", Long.class, source.inboxId());
|
||||
assertThat(taskCount).isEqualTo(1L);
|
||||
assertThat(adapterErrorCount).isEqualTo(1L);
|
||||
|
||||
List<String> v4CardTypes = jdbcTemplate.queryForList("""
|
||||
SELECT card_type
|
||||
FROM workflow_reservation_v4_task_card
|
||||
WHERE source_message_id = ?
|
||||
ORDER BY card_sort_order, source_event_index
|
||||
""", String.class, source.inboxId());
|
||||
assertThat(v4CardTypes).containsExactly(
|
||||
"SOURCE_MESSAGE_DISPLAY",
|
||||
"BASIC_INFORMATION",
|
||||
"ROOM_INFORMATION");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3509,6 +3763,243 @@ class SuperAgentTaskResultControllerTest {
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4TwoOrderRefsBody(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
"route_code": null,
|
||||
"source_message": {
|
||||
"source_message_id": "%s",
|
||||
"conversation_id": "thread-v4-two-order-refs-001",
|
||||
"subject": "Two order refs",
|
||||
"sender": "agent@example.test",
|
||||
"sent_at": "2026-07-18T02:10:00Z",
|
||||
"body": "Please create one group and one FIT booking.",
|
||||
"body_content_type": "text/plain",
|
||||
"attachments": []
|
||||
},
|
||||
"order_contexts": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"basic_information": {
|
||||
"account_code": "QBD_TRAVEL",
|
||||
"manual_review": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"order_ref": "order-2",
|
||||
"basic_information": {
|
||||
"account_code": "LIAN_TAI",
|
||||
"manual_review": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"message_events": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"event_type": "NEW_BOOKING",
|
||||
"target_order": {
|
||||
"booking_type": "GROUP",
|
||||
"locator_type": "GROUP_CODE",
|
||||
"locator_value": "GRP-V4-MULTI-001"
|
||||
},
|
||||
"arrival_date": "2026-08-01",
|
||||
"departure_date": "2026-08-03",
|
||||
"rate_code": "BAR",
|
||||
"booking_scenario": "STANDARD",
|
||||
"room_items": [
|
||||
{
|
||||
"room_type_code": "TWN",
|
||||
"room_count": 2
|
||||
}
|
||||
],
|
||||
"manual_review": null
|
||||
},
|
||||
{
|
||||
"order_ref": "order-2",
|
||||
"event_type": "NEW_BOOKING",
|
||||
"target_order": {
|
||||
"booking_type": "FIT",
|
||||
"locator_type": "CONFIRMATION_NUMBER",
|
||||
"locator_value": "CNF-V4-MULTI-002"
|
||||
},
|
||||
"arrival_date": "2026-08-05",
|
||||
"departure_date": "2026-08-06",
|
||||
"rate_code": "BAR",
|
||||
"booking_scenario": "STANDARD",
|
||||
"guest_name": "TEST GUEST",
|
||||
"room_items": [
|
||||
{
|
||||
"room_type_code": "KING",
|
||||
"room_count": 1
|
||||
}
|
||||
],
|
||||
"manual_review": null
|
||||
}
|
||||
]
|
||||
}
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4FitBookingCodeBody(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
"route_code": null,
|
||||
"source_message": {
|
||||
"source_message_id": "%s",
|
||||
"conversation_id": "thread-v4-fit-booking-code-001",
|
||||
"subject": "FIT booking code",
|
||||
"sender": "agent@example.test",
|
||||
"sent_at": "2026-07-18T02:10:00Z",
|
||||
"body": "Please create or locate FIT booking by booking code.",
|
||||
"body_content_type": "text/plain",
|
||||
"attachments": []
|
||||
},
|
||||
"order_contexts": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"basic_information": {
|
||||
"account_code": "QBD_TRAVEL",
|
||||
"manual_review": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"message_events": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"event_type": "NEW_BOOKING",
|
||||
"target_order": {
|
||||
"booking_type": "FIT",
|
||||
"locator_type": "BOOKING_CODE",
|
||||
"locator_value": "BK-V4-FIT-001"
|
||||
},
|
||||
"arrival_date": "2026-08-05",
|
||||
"departure_date": "2026-08-06",
|
||||
"rate_code": "BAR",
|
||||
"booking_scenario": "STANDARD",
|
||||
"guest_name": "BOOKING CODE GUEST",
|
||||
"room_items": [
|
||||
{
|
||||
"room_type_code": "KING",
|
||||
"room_count": 1
|
||||
}
|
||||
],
|
||||
"manual_review": null
|
||||
}
|
||||
]
|
||||
}
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4UnresolvedThenResolvedBody(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
"route_code": null,
|
||||
"source_message": {
|
||||
"source_message_id": "%s",
|
||||
"conversation_id": "thread-v4-unresolved-then-resolved-001",
|
||||
"subject": "Unresolved event followed by payment",
|
||||
"sender": "agent@example.test",
|
||||
"sent_at": "2026-07-18T02:10:00Z",
|
||||
"body": "Please update something; payment evidence attached.",
|
||||
"body_content_type": "text/plain",
|
||||
"attachments": [
|
||||
{
|
||||
"id": "att-pay-1",
|
||||
"name": "payment-slip.jpg",
|
||||
"content_type": "image/jpeg",
|
||||
"url": "https://oss.example.test/payment-slip.jpg",
|
||||
"size": 251524
|
||||
}
|
||||
]
|
||||
},
|
||||
"order_contexts": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"basic_information": {
|
||||
"account_code": "QBD_TRAVEL",
|
||||
"manual_review": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"message_events": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"event_type": "UPDATE_BOOKING",
|
||||
"target_order": {
|
||||
"booking_type": null,
|
||||
"locator_type": null,
|
||||
"locator_value": null
|
||||
},
|
||||
"after": {
|
||||
"arrival_date": "2026-08-07"
|
||||
},
|
||||
"manual_review": true
|
||||
},
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"event_type": "PAYMENT",
|
||||
"target_order": {
|
||||
"booking_type": "GROUP",
|
||||
"locator_type": "GROUP_CODE",
|
||||
"locator_value": "GRP-V4-RESOLVED-LATER-001"
|
||||
},
|
||||
"attachment_ids": ["att-pay-1"],
|
||||
"manual_review": null
|
||||
}
|
||||
]
|
||||
}
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4BasicInformationReviewBody(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
"route_code": null,
|
||||
"source_message": {
|
||||
"source_message_id": "%s",
|
||||
"conversation_id": "thread-v4-basic-review-001",
|
||||
"subject": "Basic information needs review",
|
||||
"sender": "agent@example.test",
|
||||
"sent_at": "2026-07-18T02:10:00Z",
|
||||
"body": "Account code is not clear.",
|
||||
"body_content_type": "text/plain",
|
||||
"attachments": []
|
||||
},
|
||||
"order_contexts": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"basic_information": {
|
||||
"account_code": null,
|
||||
"manual_review": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"message_events": [
|
||||
{
|
||||
"order_ref": "order-1",
|
||||
"event_type": "NEW_BOOKING",
|
||||
"target_order": {
|
||||
"booking_type": "GROUP",
|
||||
"locator_type": "GROUP_CODE",
|
||||
"locator_value": "GRP-V4-BASIC-REVIEW-001"
|
||||
},
|
||||
"arrival_date": "2026-08-01",
|
||||
"departure_date": "2026-08-03",
|
||||
"rate_code": "BAR",
|
||||
"booking_scenario": "STANDARD",
|
||||
"room_items": [
|
||||
{
|
||||
"room_type_code": "TWN",
|
||||
"room_count": 2
|
||||
}
|
||||
],
|
||||
"manual_review": null
|
||||
}
|
||||
]
|
||||
}
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4CancelTraceRoomingListBody(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
@@ -3595,6 +4086,26 @@ class SuperAgentTaskResultControllerTest {
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4S99Body(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
"route_code": "S99",
|
||||
"source_message": {
|
||||
"source_message_id": "%s",
|
||||
"conversation_id": "thread-v4-s99-001",
|
||||
"subject": "Cannot form material package",
|
||||
"sender": "guest@example.test",
|
||||
"sent_at": "2026-07-18T02:10:00Z",
|
||||
"body": "The input does not contain enough business material.",
|
||||
"body_content_type": "text/plain",
|
||||
"attachments": []
|
||||
},
|
||||
"order_contexts": [],
|
||||
"message_events": []
|
||||
}
|
||||
""".formatted(externalSourceMessageId);
|
||||
}
|
||||
|
||||
private String v4MalformedMissingOrderContextsBody(String externalSourceMessageId) {
|
||||
return """
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user