diff --git a/notification/src/main/java/com/hubEleven/notification/slack/application/service/impl/SlackServiceImpl.java b/notification/src/main/java/com/hubEleven/notification/slack/application/service/impl/SlackServiceImpl.java index c49b80e8..7279f90c 100644 --- a/notification/src/main/java/com/hubEleven/notification/slack/application/service/impl/SlackServiceImpl.java +++ b/notification/src/main/java/com/hubEleven/notification/slack/application/service/impl/SlackServiceImpl.java @@ -4,6 +4,7 @@ import com.commonLib.common.request.CommonPageRequest; import com.commonLib.common.response.CommonPageResponse; import com.commonLib.common.utils.PagingUtils; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.hubEleven.notification.ai.domain.repository.AiRequestLogRepository; import com.hubEleven.notification.ai.exception.AiErrorCode; @@ -20,7 +21,6 @@ import com.hubEleven.notification.slack.domain.vo.SlackMessageContext; import com.hubEleven.notification.slack.domain.vo.SlackMessageItem; import com.hubEleven.notification.slack.exception.SlackErrorCode; -import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -48,11 +48,11 @@ public class SlackServiceImpl implements SlackService { public SlackMessageResult createMessage(CreateSlackMessageCommand command) { slackValidator.slackCreate(command.orderId()); - ResponsePayload payload = findAiPayloadOrThrow(command.orderId()); + SlackMessageContext context = buildSlackMessageContext(command); - SlackMessageContext context = buildSlackMessageContext(command.orderId(), payload); + AiPayload aiPayload = findAiPayloadOrThrow(command.orderId()); - String formattedMessage = slackDomainService.formatMessage(context, payload.messageBody); + String formattedMessage = slackDomainService.formatMessage(context, aiPayload.messageBody()); SlackMessage slackMessage = SlackMessage.create( @@ -124,25 +124,36 @@ public CommonPageResponse searchMessages( SlackMessageResult::from); } - private ResponsePayload findAiPayloadOrThrow(UUID orderId) { + private AiPayload findAiPayloadOrThrow(UUID orderId) { return aiRequestLogRepository .findByOrderId(orderId) .map( logEntry -> { + String messageBody = logEntry.getMessageBody(); + String finalDeadline = logEntry.getFinalDispatchDeadline(); + + if (messageBody != null && !messageBody.isBlank()) { + return new AiPayload(finalDeadline, messageBody); + } + String raw = logEntry.getRawResponse(); + if (raw == null || raw.isBlank()) { + throw new GlobalException(AiErrorCode.AI_RESPONSE_PARSE_FAIL); + } + String cleaned = cleanJsonResponse(raw); try { - ResponsePayload payload = objectMapper.readValue(cleaned, ResponsePayload.class); + JsonNode node = objectMapper.readTree(cleaned); - if (payload.finalDispatchDeadline == null - || payload.finalDispatchDeadline.isBlank()) { - throw new GlobalException(AiErrorCode.AI_RESPONSE_PARSE_FAIL); - } - if (payload.messageBody == null || payload.messageBody.isBlank()) { + String parsedDeadline = node.path("finalDispatchDeadline").asText(null); + String parsedBody = node.path("messageBody").asText(null); + + if (parsedBody == null || parsedBody.isBlank()) { throw new GlobalException(AiErrorCode.AI_RESPONSE_PARSE_FAIL); } - return payload; + + return new AiPayload(parsedDeadline, parsedBody); } catch (Exception e) { throw new GlobalException(AiErrorCode.AI_RESPONSE_PARSE_FAIL); } @@ -170,47 +181,34 @@ private String cleanJsonResponse(String rawJson) { return cleaned.trim(); } - private SlackMessageContext buildSlackMessageContext(UUID orderId, ResponsePayload payload) { - LocalDateTime orderDateTime = parseLocalDateTime(payload.orderDateTime); - - List viaHubs = (payload.viaHubs == null) ? Collections.emptyList() : payload.viaHubs; + private SlackMessageContext buildSlackMessageContext(CreateSlackMessageCommand cmd) { + List viaHubs = (cmd.viaHubs() == null) ? Collections.emptyList() : cmd.viaHubs(); List items = - (payload.items == null) + (cmd.items() == null) ? Collections.emptyList() - : payload.items.stream() + : cmd.items().stream() .map( it -> new SlackMessageItem( - nullToEmpty(it.name), it.quantity, nullToEmpty(it.note))) + nullToEmpty(it.name()), it.quantity(), nullToEmpty(it.note()))) .toList(); return new SlackMessageContext( - orderId, - blankToNull(payload.customerName), - blankToNull(payload.customerEmail), - orderDateTime, - blankToNull(payload.sourceHub), + cmd.orderId(), + blankToNull(cmd.customerName()), + blankToNull(cmd.customerEmail()), + cmd.orderDateTime(), + blankToNull(cmd.sourceHub()), viaHubs, - blankToNull(payload.destinationHub), - blankToNull(payload.destinationAddress), - blankToNull(payload.requestNote), - blankToNull(payload.deliveryManagerName), - blankToNull(payload.deliveryManagerEmail), + blankToNull(cmd.destinationHub()), + blankToNull(cmd.destinationAddress()), + blankToNull(cmd.requestNote()), + blankToNull(cmd.deliveryManagerName()), + blankToNull(cmd.deliveryManagerEmail()), items); } - private LocalDateTime parseLocalDateTime(String value) { - if (value == null || value.isBlank()) { - return null; - } - try { - return LocalDateTime.parse(value.trim()); - } catch (Exception ignore) { - return null; - } - } - private String blankToNull(String s) { return (s == null || s.isBlank()) ? null : s; } @@ -219,26 +217,5 @@ private String nullToEmpty(String s) { return (s == null) ? "" : s; } - private static final class ResponsePayload { - public String finalDispatchDeadline; - public String messageBody; - - public String customerName; - public String customerEmail; - public String orderDateTime; - public String sourceHub; - public List viaHubs; - public String destinationHub; - public String destinationAddress; - public String requestNote; - public String deliveryManagerName; - public String deliveryManagerEmail; - public List items; - } - - private static final class ItemPayload { - public String name; - public int quantity; - public String note; - } + private record AiPayload(String finalDispatchDeadline, String messageBody) {} } diff --git a/notification/src/main/java/com/hubEleven/notification/slack/domain/event/handler/SlackDomainEventHandler.java b/notification/src/main/java/com/hubEleven/notification/slack/domain/event/handler/SlackDomainEventHandler.java index 3da4e689..878a113d 100644 --- a/notification/src/main/java/com/hubEleven/notification/slack/domain/event/handler/SlackDomainEventHandler.java +++ b/notification/src/main/java/com/hubEleven/notification/slack/domain/event/handler/SlackDomainEventHandler.java @@ -11,6 +11,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionPhase; import org.springframework.transaction.event.TransactionalEventListener; @@ -23,6 +25,7 @@ public class SlackDomainEventHandler { private final SlackClient slackClient; @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + @Transactional(propagation = Propagation.REQUIRES_NEW) public void handle(SlackMessageSavedEvent event) { UUID messageId = event.messageId();