diff --git a/src/main/java/com/example/RealMatch/chat/application/event/apply/CampaignApplySentEventListener.java b/src/main/java/com/example/RealMatch/chat/application/event/apply/CampaignApplySentEventListener.java index 96934c5e..c5d00b8b 100644 --- a/src/main/java/com/example/RealMatch/chat/application/event/apply/CampaignApplySentEventListener.java +++ b/src/main/java/com/example/RealMatch/chat/application/event/apply/CampaignApplySentEventListener.java @@ -1,7 +1,5 @@ package com.example.RealMatch.chat.application.event.apply; -import java.util.Optional; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; @@ -10,7 +8,7 @@ import org.springframework.transaction.event.TransactionalEventListener; import com.example.RealMatch.business.application.event.CampaignApplySentEvent; -import com.example.RealMatch.chat.application.service.room.ChatRoomQueryService; +import com.example.RealMatch.chat.application.service.room.ChatRoomCommandService; import com.example.RealMatch.chat.presentation.dto.response.ChatApplyCardPayloadResponse; import lombok.RequiredArgsConstructor; @@ -25,7 +23,7 @@ public class CampaignApplySentEventListener { private static final Logger LOG = LoggerFactory.getLogger(CampaignApplySentEventListener.class); - private final ChatRoomQueryService chatRoomQueryService; + private final ChatRoomCommandService chatRoomCommandService; private final ApplicationEventPublisher eventPublisher; @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) @@ -38,16 +36,8 @@ public void handleCampaignApplySent(CampaignApplySentEvent event) { LOG.info("[ApplyBoundary] Received business event. applyId={}, campaignId={}, creatorUserId={}, brandUserId={}", event.applyId(), event.campaignId(), event.creatorUserId(), event.brandUserId()); - Optional roomIdOpt = chatRoomQueryService.getRoomIdByUserPair( - event.brandUserId(), event.creatorUserId()); - - if (roomIdOpt.isEmpty()) { - LOG.debug("[ApplyBoundary] Chat room not found. brandUserId={}, creatorUserId={}", - event.brandUserId(), event.creatorUserId()); - return; - } - - Long roomId = roomIdOpt.get(); + // 채팅방이 없으면 생성 + Long roomId = ensureRoomAndGetId(event.brandUserId(), event.creatorUserId()); ChatApplyCardPayloadResponse payload = createPayload(event); String eventId = ApplySentEvent.generateEventId(event.applyId()); @@ -58,6 +48,16 @@ public void handleCampaignApplySent(CampaignApplySentEvent event) { eventId, roomId, event.applyId()); } + /** + * 채팅방이 없으면 생성하고, roomId를 반환합니다. + * 이 리스너는 AFTER_COMMIT 컨텍스트에서 실행되므로 createOrGetRoom이 별도 트랜잭션으로 처리됩니다. + */ + private Long ensureRoomAndGetId(Long brandUserId, Long creatorUserId) { + return chatRoomCommandService + .createOrGetRoom(brandUserId, brandUserId, creatorUserId) + .roomId(); + } + private ChatApplyCardPayloadResponse createPayload(CampaignApplySentEvent event) { return new ChatApplyCardPayloadResponse( event.applyId(), diff --git a/src/main/java/com/example/RealMatch/chat/application/event/proposal/CampaignProposalSentEventListener.java b/src/main/java/com/example/RealMatch/chat/application/event/proposal/CampaignProposalSentEventListener.java index 5de52f38..fb8a567c 100644 --- a/src/main/java/com/example/RealMatch/chat/application/event/proposal/CampaignProposalSentEventListener.java +++ b/src/main/java/com/example/RealMatch/chat/application/event/proposal/CampaignProposalSentEventListener.java @@ -1,7 +1,5 @@ package com.example.RealMatch.chat.application.event.proposal; -import java.util.Optional; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; @@ -12,7 +10,7 @@ import com.example.RealMatch.business.application.event.CampaignProposalSentEvent; import com.example.RealMatch.business.domain.enums.ProposalDirection; import com.example.RealMatch.business.domain.enums.ProposalStatus; -import com.example.RealMatch.chat.application.service.room.ChatRoomQueryService; +import com.example.RealMatch.chat.application.service.room.ChatRoomCommandService; import com.example.RealMatch.chat.domain.enums.ChatProposalDirection; import com.example.RealMatch.chat.presentation.dto.enums.ChatProposalDecisionStatus; import com.example.RealMatch.chat.presentation.dto.response.ChatProposalCardPayloadResponse; @@ -29,7 +27,7 @@ public class CampaignProposalSentEventListener { private static final Logger LOG = LoggerFactory.getLogger(CampaignProposalSentEventListener.class); - private final ChatRoomQueryService chatRoomQueryService; + private final ChatRoomCommandService chatRoomCommandService; private final ApplicationEventPublisher eventPublisher; @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) @@ -42,16 +40,8 @@ public void handleCampaignProposalSent(CampaignProposalSentEvent event) { LOG.info("[ProposalBoundary] Received business event. proposalId={}, isReProposal={}", event.proposalId(), event.isReProposal()); - Optional roomIdOpt = chatRoomQueryService.getRoomIdByUserPair( - event.brandUserId(), event.creatorUserId()); - - if (roomIdOpt.isEmpty()) { - LOG.debug("[ProposalBoundary] Chat room not found. brandUserId={}, creatorUserId={}", - event.brandUserId(), event.creatorUserId()); - return; - } - - Long roomId = roomIdOpt.get(); + // 채팅방이 없으면 생성 + Long roomId = ensureRoomAndGetId(event.brandUserId(), event.creatorUserId()); ChatProposalCardPayloadResponse payload = createPayload(event); String eventId = ProposalSentEvent.generateEventId(event.proposalId(), event.isReProposal()); @@ -88,6 +78,16 @@ private ChatProposalDecisionStatus toChatDecisionStatus(ProposalStatus proposalS }; } + /** + * 채팅방이 없으면 생성하고, roomId를 반환합니다. + * 이 리스너는 AFTER_COMMIT 컨텍스트에서 실행되므로 createOrGetRoom이 별도 트랜잭션으로 처리됩니다. + */ + private Long ensureRoomAndGetId(Long brandUserId, Long creatorUserId) { + return chatRoomCommandService + .createOrGetRoom(brandUserId, brandUserId, creatorUserId) + .roomId(); + } + private ChatProposalDirection toChatProposalDirection(ProposalDirection direction) { if (direction == null) { return ChatProposalDirection.NONE;