From 2777c855c24613bd458b65e535ccf6f15793125b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Mon, 27 Apr 2026 16:33:20 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20direct=20room=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=20=EB=B3=B5=EC=9B=90=20=EC=B1=85=EC=9E=84=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - direct room의 멤버 접근 검증과 나간 방 복원 판단을 전용 서비스로 분리해 ChatService의 조회/전송 흐름 부담을 낮춤 - visibleMessageFrom을 복원 전 기준으로 반환하는 기존 정책을 유지해 메시지 조회 가시 범위가 바뀌지 않도록 함 - 분리한 정책의 단위 테스트를 추가해 나간 방 복원과 접근 거부 조건을 고정 --- .../service/ChatDirectRoomAccessService.java | 57 ++++++++ .../domain/chat/service/ChatService.java | 44 +----- .../ChatDirectRoomAccessServiceTest.java | 125 ++++++++++++++++++ .../domain/chat/service/ChatServiceTest.java | 7 +- 4 files changed, 194 insertions(+), 39 deletions(-) create mode 100644 src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java create mode 100644 src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java diff --git a/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java b/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java new file mode 100644 index 000000000..623b262e8 --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java @@ -0,0 +1,57 @@ +package gg.agit.konect.domain.chat.service; + +import static gg.agit.konect.global.code.ApiResponseCode.FORBIDDEN_CHAT_ROOM_ACCESS; + +import java.time.LocalDateTime; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.agit.konect.domain.chat.model.ChatRoom; +import gg.agit.konect.domain.chat.model.ChatRoomMember; +import gg.agit.konect.domain.chat.repository.ChatRoomMemberRepository; +import gg.agit.konect.domain.user.model.User; +import gg.agit.konect.global.exception.CustomException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ChatDirectRoomAccessService { + + private final ChatRoomMemberRepository chatRoomMemberRepository; + + public ChatRoomMember getAccessibleMember(ChatRoom chatRoom, User user) { + ChatRoomMember member = getMember(chatRoom, user); + restoreIfVisible(member, chatRoom); + return member; + } + + public LocalDateTime prepareAccessAndGetVisibleMessageFrom(ChatRoom chatRoom, User user) { + ChatRoomMember member = getMember(chatRoom, user); + LocalDateTime visibleMessageFrom = member.getVisibleMessageFrom(); + restoreIfVisible(member, chatRoom); + return visibleMessageFrom; + } + + private ChatRoomMember getMember(ChatRoom chatRoom, User user) { + return chatRoomMemberRepository.findByChatRoomIdAndUserId(chatRoom.getId(), user.getId()) + .orElseThrow(() -> CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS)); + } + + /** + * direct 채팅방에서 나간 사용자가 다시 볼 수 있는 상태인지 확인하고, + * 새 메시지가 이미 존재하면 나간 상태를 해제한다. + */ + private void restoreIfVisible(ChatRoomMember member, ChatRoom chatRoom) { + if (!member.hasLeft()) { + return; + } + + if (!member.hasVisibleMessages(chatRoom)) { + throw CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS); + } + + member.restoreDirectRoom(); + } +} diff --git a/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java b/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java index 9ba264b6e..31e46618c 100644 --- a/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java +++ b/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java @@ -84,6 +84,7 @@ public class ChatService { private final ChatSearchService chatSearchService; private final ChatMessagePageResolver chatMessagePageResolver; private final ChatRoomSystemAdminService chatRoomSystemAdminService; + private final ChatDirectRoomAccessService chatDirectRoomAccessService; private final NotificationService notificationService; private final ApplicationEventPublisher eventPublisher; @@ -410,7 +411,7 @@ public ChatMuteResponse toggleMute(Integer userId, Integer roomId) { boolean isAdminAccessingSystemAdminRoom = user.isAdmin() && chatRoomSystemAdminService.isSystemAdminRoom(room.getId()); if (!isAdminAccessingSystemAdminRoom) { - getAccessibleDirectRoomMember(room, user); + chatDirectRoomAccessService.getAccessibleMember(room, user); } } else { getAccessibleRoomMember(room, userId); @@ -627,8 +628,8 @@ private ChatMessagePageResponse getDirectChatRoomMessages( ChatRoom chatRoom = getDirectRoom(roomId); User user = userRepository.getById(userId); List members = chatRoomMemberRepository.findByChatRoomId(roomId); - LocalDateTime visibleMessageFrom = prepareDirectRoomAccess(getOrCreateDirectRoomMember(chatRoom, user), - chatRoom); + LocalDateTime visibleMessageFrom = + chatDirectRoomAccessService.prepareAccessAndGetVisibleMessageFrom(chatRoom, user); List sortedReadBaselines = toSortedReadBaselines(members); @@ -670,7 +671,7 @@ private ChatMessageDetailResponse sendDirectMessage( boolean senderHadLeft = false; if (!isAdminSendingToSystemAdminRoom) { - senderMember = getAccessibleDirectRoomMember(chatRoom, sender); + senderMember = chatDirectRoomAccessService.getAccessibleMember(chatRoom, sender); senderHadLeft = senderMember.hasLeft(); } @@ -994,7 +995,7 @@ private ChatRoomMember getAccessibleRoomMember(ChatRoom room, Integer userId) { if (room.isDirectRoom()) { User user = userRepository.getById(userId); - return getAccessibleDirectRoomMember(room, user); + return chatDirectRoomAccessService.getAccessibleMember(room, user); } ChatRoomMember member = getRoomMember(room.getId(), userId); @@ -1147,44 +1148,11 @@ private Map getRoomUnreadCountMap(List roomIds, Integ return unreadCountMap; } - private ChatRoomMember getOrCreateDirectRoomMember(ChatRoom chatRoom, User user) { - return chatRoomMemberRepository.findByChatRoomIdAndUserId(chatRoom.getId(), user.getId()) - .orElseThrow(() -> CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS)); - } - - private ChatRoomMember getAccessibleDirectRoomMember(ChatRoom chatRoom, User user) { - ChatRoomMember member = getOrCreateDirectRoomMember(chatRoom, user); - restoreDirectRoomIfVisible(member, chatRoom); - return member; - } - - private LocalDateTime prepareDirectRoomAccess(ChatRoomMember member, ChatRoom chatRoom) { - LocalDateTime visibleMessageFrom = member.getVisibleMessageFrom(); - restoreDirectRoomIfVisible(member, chatRoom); - return visibleMessageFrom; - } - private LocalDateTime resolveAdminSystemRoomVisibleMessageFrom(List members) { ChatRoomMember systemAdminMember = chatRoomSystemAdminService.findSystemAdminMember(members); return systemAdminMember != null ? systemAdminMember.getVisibleMessageFrom() : null; } - /** - * direct 채팅방에서 나간 사용자가 다시 볼 수 있는 상태인지 확인하고, - * 새 메시지가 이미 존재하면 나간 상태를 해제한다. - */ - private void restoreDirectRoomIfVisible(ChatRoomMember member, ChatRoom chatRoom) { - if (!member.hasLeft()) { - return; - } - - if (!member.hasVisibleMessages(chatRoom)) { - throw CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS); - } - - member.restoreDirectRoom(); - } - private boolean shouldDisplayAsOwnMessage( User currentUser, ChatMessage message, diff --git a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java new file mode 100644 index 000000000..651a4c4c5 --- /dev/null +++ b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java @@ -0,0 +1,125 @@ +package gg.agit.konect.unit.domain.chat.service; + +import static gg.agit.konect.global.code.ApiResponseCode.FORBIDDEN_CHAT_ROOM_ACCESS; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.given; + +import java.time.LocalDateTime; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.test.util.ReflectionTestUtils; + +import gg.agit.konect.domain.chat.model.ChatRoom; +import gg.agit.konect.domain.chat.model.ChatRoomMember; +import gg.agit.konect.domain.chat.repository.ChatRoomMemberRepository; +import gg.agit.konect.domain.chat.service.ChatDirectRoomAccessService; +import gg.agit.konect.domain.user.enums.UserRole; +import gg.agit.konect.domain.user.model.User; +import gg.agit.konect.global.exception.CustomException; +import gg.agit.konect.support.ServiceTestSupport; +import gg.agit.konect.support.fixture.UniversityFixture; +import gg.agit.konect.support.fixture.UserFixture; + +class ChatDirectRoomAccessServiceTest extends ServiceTestSupport { + + private static final LocalDateTime BASE_TIME = LocalDateTime.of(2026, 4, 27, 10, 0); + + @Mock + private ChatRoomMemberRepository chatRoomMemberRepository; + + @InjectMocks + private ChatDirectRoomAccessService chatDirectRoomAccessService; + + @Test + @DisplayName("접근 가능한 direct room 멤버를 반환한다") + void getAccessibleMemberReturnsMember() { + User user = user(10); + ChatRoom room = room(1); + ChatRoomMember member = member(room, user); + given(chatRoomMemberRepository.findByChatRoomIdAndUserId(room.getId(), user.getId())) + .willReturn(Optional.of(member)); + + ChatRoomMember result = chatDirectRoomAccessService.getAccessibleMember(room, user); + + assertThat(result).isSameAs(member); + } + + @Test + @DisplayName("나간 direct room에 새 메시지가 있으면 접근 시 나간 상태를 해제한다") + void getAccessibleMemberRestoresLeftMemberWhenVisibleMessageExists() { + User user = user(10); + ChatRoom room = room(1); + room.updateLastMessage("새 메시지", BASE_TIME.plusHours(2)); + ChatRoomMember member = member(room, user); + member.leaveDirectRoom(BASE_TIME.plusHours(1)); + given(chatRoomMemberRepository.findByChatRoomIdAndUserId(room.getId(), user.getId())) + .willReturn(Optional.of(member)); + + ChatRoomMember result = chatDirectRoomAccessService.getAccessibleMember(room, user); + + assertThat(result.hasLeft()).isFalse(); + } + + @Test + @DisplayName("나간 direct room에 새 메시지가 없으면 접근을 거부한다") + void getAccessibleMemberRejectsLeftMemberWithoutVisibleMessage() { + User user = user(10); + ChatRoom room = room(1); + ChatRoomMember member = member(room, user); + member.leaveDirectRoom(BASE_TIME.plusHours(1)); + given(chatRoomMemberRepository.findByChatRoomIdAndUserId(room.getId(), user.getId())) + .willReturn(Optional.of(member)); + + assertThatThrownBy(() -> chatDirectRoomAccessService.getAccessibleMember(room, user)) + .isInstanceOf(CustomException.class) + .satisfies(exception -> + assertThat(((CustomException)exception).getErrorCode()).isEqualTo(FORBIDDEN_CHAT_ROOM_ACCESS)); + } + + @Test + @DisplayName("접근 준비는 복원 전 visibleMessageFrom을 반환한다") + void prepareAccessAndGetVisibleMessageFromReturnsPreviousVisibilityBoundary() { + User user = user(10); + ChatRoom room = room(1); + room.updateLastMessage("새 메시지", BASE_TIME.plusHours(2)); + ChatRoomMember member = member(room, user); + LocalDateTime visibleMessageFrom = BASE_TIME.plusHours(1); + ReflectionTestUtils.setField(member, "leftAt", visibleMessageFrom); + ReflectionTestUtils.setField(member, "visibleMessageFrom", visibleMessageFrom); + given(chatRoomMemberRepository.findByChatRoomIdAndUserId(room.getId(), user.getId())) + .willReturn(Optional.of(member)); + + LocalDateTime result = chatDirectRoomAccessService.prepareAccessAndGetVisibleMessageFrom(room, user); + + assertThat(result).isEqualTo(visibleMessageFrom); + assertThat(member.hasLeft()).isFalse(); + } + + private User user(Integer id) { + return UserFixture.createUserWithId( + UniversityFixture.createWithId(1), + id, + "사용자" + id, + "2024" + String.format("%04d", id), + UserRole.USER + ); + } + + private ChatRoom room(Integer id) { + ChatRoom room = ChatRoom.directOf(); + ReflectionTestUtils.setField(room, "id", id); + ReflectionTestUtils.setField(room, "createdAt", BASE_TIME); + return room; + } + + private ChatRoomMember member(ChatRoom room, User user) { + ChatRoomMember member = ChatRoomMember.of(room, user, BASE_TIME); + ReflectionTestUtils.setField(member, "createdAt", BASE_TIME); + return member; + } +} diff --git a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java index 571223581..e2daaf3e6 100644 --- a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java +++ b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java @@ -51,11 +51,12 @@ import gg.agit.konect.domain.chat.repository.ChatRoomMemberRepository; import gg.agit.konect.domain.chat.repository.ChatRoomQueryRepository; import gg.agit.konect.domain.chat.repository.ChatRoomRepository; +import gg.agit.konect.domain.chat.service.ChatDirectRoomAccessService; +import gg.agit.konect.domain.chat.service.ChatMessagePageResolver; import gg.agit.konect.domain.chat.service.ChatPresenceService; import gg.agit.konect.domain.chat.service.ChatRoomMembershipService; import gg.agit.konect.domain.chat.service.ChatRoomSummaryService; import gg.agit.konect.domain.chat.service.ChatSearchService; -import gg.agit.konect.domain.chat.service.ChatMessagePageResolver; import gg.agit.konect.domain.chat.service.ChatRoomSystemAdminService; import gg.agit.konect.domain.chat.service.ChatService; import gg.agit.konect.domain.club.model.Club; @@ -125,10 +126,13 @@ class ChatServiceTest extends ServiceTestSupport { private ChatMessagePageResolver chatMessagePageResolver; + private ChatDirectRoomAccessService chatDirectRoomAccessService; + private ChatService chatService; @BeforeEach void setUp() { + chatDirectRoomAccessService = new ChatDirectRoomAccessService(chatRoomMemberRepository); chatMessagePageResolver = new ChatMessagePageResolver( chatMessageRepository, chatRoomMemberRepository, @@ -150,6 +154,7 @@ void setUp() { chatSearchService, chatMessagePageResolver, chatRoomSystemAdminService, + chatDirectRoomAccessService, notificationService, eventPublisher ); From f7ec71371e6c592eec21b3791ce99a74458a820c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Mon, 27 Apr 2026 16:42:53 +0900 Subject: [PATCH 2/4] =?UTF-8?q?test:=20direct=20room=20=EC=A0=91=EA=B7=BC?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=EC=84=B1=20=EB=8B=A8?= =?UTF-8?q?=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - setUp에서만 쓰는 보조 서비스 인스턴스를 지역 변수로 좁혀 테스트 상태를 줄임 - 복원 테스트는 반환 객체보다 변경 대상 멤버 상태를 직접 검증해 의도를 명확히 함 --- .../chat/service/ChatDirectRoomAccessServiceTest.java | 4 ++-- .../konect/unit/domain/chat/service/ChatServiceTest.java | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java index 651a4c4c5..ddff5a46e 100644 --- a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java +++ b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java @@ -60,9 +60,9 @@ void getAccessibleMemberRestoresLeftMemberWhenVisibleMessageExists() { given(chatRoomMemberRepository.findByChatRoomIdAndUserId(room.getId(), user.getId())) .willReturn(Optional.of(member)); - ChatRoomMember result = chatDirectRoomAccessService.getAccessibleMember(room, user); + chatDirectRoomAccessService.getAccessibleMember(room, user); - assertThat(result.hasLeft()).isFalse(); + assertThat(member.hasLeft()).isFalse(); } @Test diff --git a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java index e2daaf3e6..dba00c648 100644 --- a/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java +++ b/src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java @@ -124,16 +124,13 @@ class ChatServiceTest extends ServiceTestSupport { @Mock private ApplicationEventPublisher eventPublisher; - private ChatMessagePageResolver chatMessagePageResolver; - - private ChatDirectRoomAccessService chatDirectRoomAccessService; - private ChatService chatService; @BeforeEach void setUp() { - chatDirectRoomAccessService = new ChatDirectRoomAccessService(chatRoomMemberRepository); - chatMessagePageResolver = new ChatMessagePageResolver( + ChatDirectRoomAccessService chatDirectRoomAccessService = + new ChatDirectRoomAccessService(chatRoomMemberRepository); + ChatMessagePageResolver chatMessagePageResolver = new ChatMessagePageResolver( chatMessageRepository, chatRoomMemberRepository, clubMemberRepository, From ecf5033e7454a8ed2f6a5bcf1665ec73a86a7bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Mon, 27 Apr 2026 16:55:44 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20direct=20room=20=EB=B3=B5=EC=9B=90?= =?UTF-8?q?=20=ED=8A=B8=EB=9E=9C=EC=9E=AD=EC=85=98=20=EA=B2=BD=EA=B3=84=20?= =?UTF-8?q?=EB=B3=B4=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 메시지 조회는 lastReadAt 갱신과 direct room 복원을 수행하므로 readOnly 트랜잭션에서 제외 - direct room 접근 서비스가 나간 방 복원 상태를 변경할 수 있음을 트랜잭션 선언에 반영 - 조회 흐름에서 leftAt 해제가 영속화되지 않는 회귀를 방지 --- .../domain/chat/service/ChatDirectRoomAccessService.java | 2 +- .../java/gg/agit/konect/domain/chat/service/ChatService.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java b/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java index 623b262e8..cfc663571 100644 --- a/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java +++ b/src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java @@ -16,7 +16,7 @@ @Service @RequiredArgsConstructor -@Transactional(readOnly = true) +@Transactional public class ChatDirectRoomAccessService { private final ChatRoomMemberRepository chatRoomMemberRepository; diff --git a/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java b/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java index 31e46618c..f6191a6ef 100644 --- a/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java +++ b/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java @@ -335,12 +335,12 @@ record SectionKey(Integer clubId, String clubName) { return ChatInvitableUsersResponse.forClubSort(pagedInvitableUsers, sections); } - @Transactional(readOnly = true) + @Transactional public ChatMessagePageResponse getMessages(Integer userId, Integer roomId, Integer page, Integer limit) { return getMessages(userId, roomId, page, limit, null); } - @Transactional(readOnly = true) + @Transactional public ChatMessagePageResponse getMessages( Integer userId, Integer roomId, Integer page, Integer limit, Integer messageId ) { From a6ce20c5bdd51aac818b534b7d27f3c410e30345 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 08:11:41 +0000 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20sendDirectMessage=EC=97=90?= =?UTF-8?q?=EC=84=9C=20senderHadLeft=20dead=20code=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agent-Logs-Url: https://github.com/BCSDLab/KONECT_BACK_END/sessions/91332fd5-a703-4c88-a058-cdb3b9ed4ea8 Co-authored-by: dh2906 <64298482+dh2906@users.noreply.github.com> --- .../agit/konect/domain/chat/service/ChatService.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java b/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java index f6191a6ef..6b55a0351 100644 --- a/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java +++ b/src/main/java/gg/agit/konect/domain/chat/service/ChatService.java @@ -667,12 +667,8 @@ private ChatMessageDetailResponse sendDirectMessage( boolean isAdminSendingToSystemAdminRoom = sender.isAdmin() && chatRoomSystemAdminService.isSystemAdminRoom(chatRoom.getId()); - ChatRoomMember senderMember = null; - boolean senderHadLeft = false; - if (!isAdminSendingToSystemAdminRoom) { - senderMember = chatDirectRoomAccessService.getAccessibleMember(chatRoom, sender); - senderHadLeft = senderMember.hasLeft(); + chatDirectRoomAccessService.getAccessibleMember(chatRoom, sender); } List members = chatRoomMemberRepository.findByChatRoomId(roomId); @@ -682,10 +678,6 @@ private ChatMessageDetailResponse sendDirectMessage( ChatMessage.of(chatRoom, sender, request.content()) ); - if (senderHadLeft && senderMember != null) { - senderMember.restoreDirectRoom(); - } - syncLastMessage(chatRoom, chatMessage); members.stream() .filter(member -> !member.getUserId().equals(userId))