diff --git a/src/main/java/com/dnd/gongmuin/chat_inquiry/dto/RejectedChatInquiryDto.java b/src/main/java/com/dnd/gongmuin/chat_inquiry/dto/ExpiredChatInquiryDto.java similarity index 85% rename from src/main/java/com/dnd/gongmuin/chat_inquiry/dto/RejectedChatInquiryDto.java rename to src/main/java/com/dnd/gongmuin/chat_inquiry/dto/ExpiredChatInquiryDto.java index d8bc89e0..063228d1 100644 --- a/src/main/java/com/dnd/gongmuin/chat_inquiry/dto/RejectedChatInquiryDto.java +++ b/src/main/java/com/dnd/gongmuin/chat_inquiry/dto/ExpiredChatInquiryDto.java @@ -4,13 +4,13 @@ import com.dnd.gongmuin.member.domain.Member; import com.querydsl.core.annotations.QueryProjection; -public record RejectedChatInquiryDto( +public record ExpiredChatInquiryDto( Long chatInquiryId, Member inquirer, Member answer ) { @QueryProjection - public RejectedChatInquiryDto( + public ExpiredChatInquiryDto( ChatInquiry chatInquiry ) { this( diff --git a/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepository.java b/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepository.java index e8a326e4..5e9fe904 100644 --- a/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepository.java +++ b/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepository.java @@ -7,15 +7,13 @@ import org.springframework.data.domain.Slice; import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryResponse; -import com.dnd.gongmuin.chat_inquiry.dto.RejectedChatInquiryDto; +import com.dnd.gongmuin.chat_inquiry.dto.ExpiredChatInquiryDto; import com.dnd.gongmuin.member.domain.Member; public interface ChatInquiryQueryRepository { Slice getChatInquiresByMember(Member member, Pageable pageable); - List getAutoRejectedInquirerIds(); + void updateChatInquiryStatusRejected(List expiredChatInquiryIds, LocalDateTime now); - void updateChatInquiryStatusRejected(LocalDateTime now); - - List getAutoRejectedChatInquiries(); + List getExpiredChatInquires(); } diff --git a/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepositoryImpl.java b/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepositoryImpl.java index eec76192..7171acfa 100644 --- a/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepositoryImpl.java +++ b/src/main/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryQueryRepositoryImpl.java @@ -11,9 +11,9 @@ import com.dnd.gongmuin.chat_inquiry.domain.InquiryStatus; import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryResponse; +import com.dnd.gongmuin.chat_inquiry.dto.ExpiredChatInquiryDto; import com.dnd.gongmuin.chat_inquiry.dto.QChatInquiryResponse; -import com.dnd.gongmuin.chat_inquiry.dto.QRejectedChatInquiryDto; -import com.dnd.gongmuin.chat_inquiry.dto.RejectedChatInquiryDto; +import com.dnd.gongmuin.chat_inquiry.dto.QExpiredChatInquiryDto; import com.dnd.gongmuin.member.domain.Member; import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -44,21 +44,9 @@ public Slice getChatInquiresByMember(Member member, Pageabl boolean hasNext = hasNext(pageable.getPageSize(), content); return new SliceImpl<>(content, pageable, hasNext); } - - public List getAutoRejectedInquirerIds() { - return queryFactory - .select(chatInquiry.inquirer.id) - .from(chatInquiry) - .where( - chatInquiry.createdAt.loe(LocalDateTime.now().minusWeeks(1)), - chatInquiry.status.eq(InquiryStatus.PENDING) - ) - .fetch(); - } - - public List getAutoRejectedChatInquiries() { + public List getExpiredChatInquires() { return queryFactory - .select(new QRejectedChatInquiryDto( + .select(new QExpiredChatInquiryDto( chatInquiry )) .from(chatInquiry) @@ -69,13 +57,12 @@ public List getAutoRejectedChatInquiries() { .fetch(); } - public void updateChatInquiryStatusRejected(LocalDateTime now) { + public void updateChatInquiryStatusRejected(List expiredChatInquiryIds, LocalDateTime now) { queryFactory.update(chatInquiry) .set(chatInquiry.status, InquiryStatus.REJECTED) .set(chatInquiry.updatedAt, now) .where( - chatInquiry.createdAt.loe(LocalDateTime.now().minusWeeks(1)), - chatInquiry.status.eq(InquiryStatus.PENDING) + chatInquiry.id.in(expiredChatInquiryIds) ) .execute(); } diff --git a/src/main/java/com/dnd/gongmuin/chat_inquiry/scheduler/ChatInquiryScheduler.java b/src/main/java/com/dnd/gongmuin/chat_inquiry/scheduler/ChatInquiryScheduler.java index b108effe..cf5cf730 100644 --- a/src/main/java/com/dnd/gongmuin/chat_inquiry/scheduler/ChatInquiryScheduler.java +++ b/src/main/java/com/dnd/gongmuin/chat_inquiry/scheduler/ChatInquiryScheduler.java @@ -19,6 +19,6 @@ public class ChatInquiryScheduler { @Transactional @Scheduled(cron = "0 0 0 * * *", zone = "Asia/Seoul") public void rejectChatInquiry() { - chatInquiryService.rejectChatAuto(LocalDateTime.now()); + chatInquiryService.autoRejectChatInquiry(LocalDateTime.now()); } } diff --git a/src/main/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryService.java b/src/main/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryService.java index 48eb268f..23cc3db3 100644 --- a/src/main/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryService.java +++ b/src/main/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryService.java @@ -19,7 +19,7 @@ import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryRequest; import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryResponse; import com.dnd.gongmuin.chat_inquiry.dto.RejectChatResponse; -import com.dnd.gongmuin.chat_inquiry.dto.RejectedChatInquiryDto; +import com.dnd.gongmuin.chat_inquiry.dto.ExpiredChatInquiryDto; import com.dnd.gongmuin.chat_inquiry.exception.ChatInquiryErrorCode; import com.dnd.gongmuin.chat_inquiry.repository.ChatInquiryRepository; import com.dnd.gongmuin.chatroom.domain.ChatRoom; @@ -133,16 +133,13 @@ public RejectChatResponse rejectChat(Long chatInquiryId, Member answerer) { } @Transactional - public void rejectChatAuto(LocalDateTime now) { - List rejectedChatInquiryDtos = chatInquiryRepository.getAutoRejectedChatInquiries(); - List rejectedInquirerIds = getRejectedInquirerIds(rejectedChatInquiryDtos); - chatInquiryRepository.updateChatInquiryStatusRejected(now); - memberRepository.refundInMemberIds(rejectedInquirerIds, CHAT_REWARD); - creditHistoryService.saveCreditHistoryInMemberIds( - rejectedInquirerIds, CreditType.CHAT_REFUND, CHAT_REWARD - ); + public void autoRejectChatInquiry(LocalDateTime now) { + List expiredChatInquiryDtos = chatInquiryRepository.getExpiredChatInquires(); + List expiredChatInquiryIds = getExpiredChatInquiryIds(expiredChatInquiryDtos); - autoRejectedChatInquiryNotification(rejectedChatInquiryDtos); + chatInquiryRepository.updateChatInquiryStatusRejected(expiredChatInquiryIds, now); + refundAutoRejectedInquiry(expiredChatInquiryDtos); + notifyAutoRejectedInquiry(expiredChatInquiryDtos); } private void validateChatAnswerer(Long questionPostId, Member answerer) { @@ -156,14 +153,28 @@ private void saveInquirerCreditHistory(Member inquirer) { creditHistoryService.saveCreditHistory(CreditType.CHAT_REQUEST, CHAT_REWARD, inquirer); } - private List getRejectedInquirerIds(List rejectedChatInquiryDtos) { - return rejectedChatInquiryDtos.stream() + private List getExpiredChatInquiryIds(List expiredChatInquiryDtos) { + return expiredChatInquiryDtos.stream() + .map(ExpiredChatInquiryDto::chatInquiryId) + .toList(); + } + + private List getRejectedInquirerIds(List expiredChatInquiryDtos) { + return expiredChatInquiryDtos.stream() .map(dto -> dto.inquirer().getId()) .toList(); } - private void autoRejectedChatInquiryNotification(List rejectedChatInquiryDtos) { - for (RejectedChatInquiryDto rejectChatInquiry : rejectedChatInquiryDtos) { + private void refundAutoRejectedInquiry(List expiredChatInquiryDtos) { + List rejectedInquirerIds = getRejectedInquirerIds(expiredChatInquiryDtos); + memberRepository.refundInMemberIds(rejectedInquirerIds, CHAT_REWARD); + creditHistoryService.saveCreditHistoryInMemberIds( + rejectedInquirerIds, CreditType.CHAT_REFUND, CHAT_REWARD + ); + } + + private void notifyAutoRejectedInquiry(List expiredChatInquiryDtos) { + for (ExpiredChatInquiryDto rejectChatInquiry : expiredChatInquiryDtos) { eventPublisher.publishEvent( // 채팅 요청자 알림 new NotificationEvent( NotificationType.AUTO_CHAT_REJECT, diff --git a/src/test/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryRepositoryTest.java b/src/test/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryRepositoryTest.java index 80f20646..397a6b40 100644 --- a/src/test/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryRepositoryTest.java +++ b/src/test/java/com/dnd/gongmuin/chat_inquiry/repository/ChatInquiryRepositoryTest.java @@ -70,7 +70,7 @@ void getChatInquiresByMember() { ); } - @DisplayName("요청중인 채팅방이 일주일이 지나면, 채팅방 상태를 거절함으로 바꾼다.") + @DisplayName("만료된 채팅 요청에 대해, 채팅 요청 상태를 거절함으로 바꾼다.") @Test void updateChatInquiryStatusRejected() { //given @@ -85,7 +85,10 @@ void updateChatInquiryStatusRejected() { ReflectionTestUtils.setField(chatInquiries.get(0), "createdAt", LocalDateTime.now().minusWeeks(1)); //when - chatInquiryRepository.updateChatInquiryStatusRejected(LocalDateTime.now()); + chatInquiryRepository.updateChatInquiryStatusRejected( + List.of(chatInquiries.get(0).getId()), + LocalDateTime.now() + ); em.flush(); em.clear(); diff --git a/src/test/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryServiceTest.java b/src/test/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryServiceTest.java index 9dbe0e58..27d739bd 100644 --- a/src/test/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryServiceTest.java +++ b/src/test/java/com/dnd/gongmuin/chat_inquiry/service/ChatInquiryServiceTest.java @@ -27,8 +27,8 @@ import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryResponse; import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryRequest; import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryResponse; +import com.dnd.gongmuin.chat_inquiry.dto.ExpiredChatInquiryDto; import com.dnd.gongmuin.chat_inquiry.dto.RejectChatResponse; -import com.dnd.gongmuin.chat_inquiry.dto.RejectedChatInquiryDto; import com.dnd.gongmuin.chat_inquiry.exception.ChatInquiryErrorCode; import com.dnd.gongmuin.chat_inquiry.repository.ChatInquiryRepository; import com.dnd.gongmuin.chatroom.domain.ChatRoom; @@ -326,22 +326,25 @@ void rejectChatAuto() { // given final LocalDateTime now = LocalDateTime.now(); - List rejectedChatInquiryDtos = List.of( - new RejectedChatInquiryDto(1L, MemberFixture.member(1L), MemberFixture.member(2L)), - new RejectedChatInquiryDto(2L, MemberFixture.member(3L), MemberFixture.member(4L)) + List expiredChatInquiryDtos = List.of( + new ExpiredChatInquiryDto(1L, MemberFixture.member(1L), MemberFixture.member(2L)), + new ExpiredChatInquiryDto(2L, MemberFixture.member(3L), MemberFixture.member(4L)) ); - List rejectedInquirerIds = rejectedChatInquiryDtos.stream() + List expiredChatInquiryIds = expiredChatInquiryDtos.stream() + .map(ExpiredChatInquiryDto::chatInquiryId) + .toList(); + List rejectedInquirerIds = expiredChatInquiryDtos.stream() .map(dto -> dto.inquirer().getId()) .toList(); - given(chatInquiryRepository.getAutoRejectedChatInquiries()).willReturn(rejectedChatInquiryDtos); + given(chatInquiryRepository.getExpiredChatInquires()).willReturn(expiredChatInquiryDtos); // when - chatInquiryService.rejectChatAuto(now); + chatInquiryService.autoRejectChatInquiry(now); // then - verify(chatInquiryRepository).getAutoRejectedChatInquiries(); - verify(chatInquiryRepository).updateChatInquiryStatusRejected(now); + verify(chatInquiryRepository).getExpiredChatInquires(); + verify(chatInquiryRepository).updateChatInquiryStatusRejected(expiredChatInquiryIds,now); verify(memberRepository).refundInMemberIds(rejectedInquirerIds, CHAT_REWARD); verify(creditHistoryService).saveCreditHistoryInMemberIds( rejectedInquirerIds, CreditType.CHAT_REFUND, CHAT_REWARD