diff --git a/src/main/java/com/daramg/server/aicomment/application/AiCommentService.java b/src/main/java/com/daramg/server/aicomment/application/AiCommentService.java index 9033c94..7a5201c 100644 --- a/src/main/java/com/daramg/server/aicomment/application/AiCommentService.java +++ b/src/main/java/com/daramg/server/aicomment/application/AiCommentService.java @@ -145,7 +145,12 @@ public void scheduleForPost(Post post) { } @Transactional - public void scheduleReplyForAiComment(Comment aiComment, Post post) { + public void scheduleReplyForAiComment(Long aiCommentId, Long postId) { + Comment aiComment = commentRepository.findById(aiCommentId).orElse(null); + if (aiComment == null) { + return; + } + if (aiComment.getAiReplyCount() >= MAX_AI_REPLY_COUNT) { return; } @@ -160,6 +165,11 @@ public void scheduleReplyForAiComment(Comment aiComment, Post post) { return; } + Post post = postRepository.findById(postId).orElse(null); + if (post == null) { + return; + } + aiComment.incrementAiReplyCount(); Instant scheduledAt = Instant.now().plusSeconds(replyDelayMinutes * 60L); diff --git a/src/main/java/com/daramg/server/aicomment/event/AiReplyScheduleEvent.java b/src/main/java/com/daramg/server/aicomment/event/AiReplyScheduleEvent.java new file mode 100644 index 0000000..09cf084 --- /dev/null +++ b/src/main/java/com/daramg/server/aicomment/event/AiReplyScheduleEvent.java @@ -0,0 +1,7 @@ +package com.daramg.server.aicomment.event; + +public record AiReplyScheduleEvent( + Long aiCommentId, + Long postId +) { +} diff --git a/src/main/java/com/daramg/server/aicomment/event/AiReplyScheduleEventListener.java b/src/main/java/com/daramg/server/aicomment/event/AiReplyScheduleEventListener.java new file mode 100644 index 0000000..b523afb --- /dev/null +++ b/src/main/java/com/daramg/server/aicomment/event/AiReplyScheduleEventListener.java @@ -0,0 +1,26 @@ +package com.daramg.server.aicomment.event; + +import com.daramg.server.aicomment.application.AiCommentService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionalEventListener; + +import static org.springframework.transaction.event.TransactionPhase.AFTER_COMMIT; + +@Slf4j +@Component +@RequiredArgsConstructor +public class AiReplyScheduleEventListener { + + private final AiCommentService aiCommentService; + + @TransactionalEventListener(phase = AFTER_COMMIT) + public void handleAiReplyScheduleEvent(AiReplyScheduleEvent event) { + try { + aiCommentService.scheduleReplyForAiComment(event.aiCommentId(), event.postId()); + } catch (Exception e) { + log.warn("AI 답글 잡 등록 실패 - aiCommentId={}, postId={}", event.aiCommentId(), event.postId(), e); + } + } +} diff --git a/src/main/java/com/daramg/server/comment/application/CommentService.java b/src/main/java/com/daramg/server/comment/application/CommentService.java index cbb57b8..a0f44c0 100644 --- a/src/main/java/com/daramg/server/comment/application/CommentService.java +++ b/src/main/java/com/daramg/server/comment/application/CommentService.java @@ -1,6 +1,6 @@ package com.daramg.server.comment.application; -import com.daramg.server.aicomment.application.AiCommentService; +import com.daramg.server.aicomment.event.AiReplyScheduleEvent; import com.daramg.server.comment.domain.Comment; import com.daramg.server.comment.domain.CommentLike; import com.daramg.server.comment.dto.CommentLikeResponseDto; @@ -30,7 +30,6 @@ public class CommentService { private final CommentRepository commentRepository; private final CommentLikeRepository commentLikeRepository; private final ApplicationEventPublisher eventPublisher; - private final AiCommentService aiCommentService; public void createComment(Long postId, CommentCreateDto request, User user){ Post post = entityUtils.getEntity(postId, Post.class); @@ -80,7 +79,7 @@ public void createReply(Long commentId, CommentReplyCreateDto request, User user } if (parentComment.isAi()) { - aiCommentService.scheduleReplyForAiComment(parentComment, post); + eventPublisher.publishEvent(new AiReplyScheduleEvent(parentComment.getId(), post.getId())); } } diff --git a/src/test/java/com/daramg/server/aicomment/application/AiCommentServiceTest.java b/src/test/java/com/daramg/server/aicomment/application/AiCommentServiceTest.java index 3ba1420..8075e4d 100644 --- a/src/test/java/com/daramg/server/aicomment/application/AiCommentServiceTest.java +++ b/src/test/java/com/daramg/server/aicomment/application/AiCommentServiceTest.java @@ -220,14 +220,14 @@ class ScheduleReplyTest { commentRepository.save(aiComment); // when - aiCommentService.scheduleReplyForAiComment(aiComment, post); + aiCommentService.scheduleReplyForAiComment(aiComment.getId(), post.getId()); // then List jobs = aiCommentJobRepository.findAll(); assertThat(jobs).hasSize(1); assertThat(jobs.get(0).getTriggerType()).isEqualTo(AiCommentJobTriggerType.USER_REPLY); assertThat(jobs.get(0).getParentComment().getId()).isEqualTo(aiComment.getId()); - assertThat(aiComment.getAiReplyCount()).isEqualTo((byte) 1); + assertThat(commentRepository.findById(aiComment.getId()).get().getAiReplyCount()).isEqualTo((byte) 1); } @Test @@ -240,9 +240,10 @@ class ScheduleReplyTest { Comment aiComment = Comment.ofAi(post, botUser, "AI 댓글", null, composer); commentRepository.save(aiComment); ReflectionTestUtils.setField(aiComment, "aiReplyCount", (byte) 2); + commentRepository.save(aiComment); // when - aiCommentService.scheduleReplyForAiComment(aiComment, post); + aiCommentService.scheduleReplyForAiComment(aiComment.getId(), post.getId()); // then assertThat(aiCommentJobRepository.findAll()).isEmpty();