Skip to content

refactor: direct room 접근 복원 책임 분리#595

Merged
dh2906 merged 4 commits intodevelopfrom
refactor/chat-direct-room-access-service-594
Apr 28, 2026
Merged

refactor: direct room 접근 복원 책임 분리#595
dh2906 merged 4 commits intodevelopfrom
refactor/chat-direct-room-access-service-594

Conversation

@dh2906
Copy link
Copy Markdown
Contributor

@dh2906 dh2906 commented Apr 27, 2026

🔍 개요


🚀 주요 변경 내용

  • direct room 멤버 조회, 접근 가능 여부 확인, visibleMessageFrom 기준 반환을 전용 서비스로 이동
  • ChatService의 메시지 조회/전송/뮤트 접근 검증 경로가 새 서비스를 사용하도록 정리
  • 나간 direct room 복원/접근 거부 조건을 단위 테스트로 보강

💬 참고 사항

  • API 응답 스펙 변경은 없습니다.
  • 검증:
    • ./gradlew compileJava compileTestJava
    • CI=true ./gradlew test --tests 'gg.agit.konect.unit.domain.chat.service.ChatDirectRoomAccessServiceTest' --tests 'gg.agit.konect.unit.domain.chat.service.ChatServiceTest' --rerun-tasks
    • ./gradlew checkstyleMain --rerun-tasks
    • CI=true ./gradlew test --tests 'gg.agit.konect.integration.domain.chat.ChatApiTest' --rerun-tasks
  • checkstyleTest는 기존 ClubMemberManagementServiceTest, NotificationInboxServiceTest, ChatApiTest의 120자 초과 위반으로 실패하며, 이번 변경 파일에는 별도 위반이 없습니다.

✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함됨
  • Reviewers / Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증 (API 키, 환경 변수, 개인정보 등)

- direct room의 멤버 접근 검증과 나간 방 복원 판단을 전용 서비스로 분리해 ChatService의 조회/전송 흐름 부담을 낮춤

- visibleMessageFrom을 복원 전 기준으로 반환하는 기존 정책을 유지해 메시지 조회 가시 범위가 바뀌지 않도록 함

- 분리한 정책의 단위 테스트를 추가해 나간 방 복원과 접근 거부 조건을 고정
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 306d3422-6ec2-4393-a75e-8d9269ac4523

📥 Commits

Reviewing files that changed from the base of the PR and between 12fc544 and a6ce20c.

📒 Files selected for processing (4)
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (java-kotlin)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Java 코드에서 import로 해결할 수 있는 경우 FQCN(Full Qualified Class Name)을 사용하지 않도록 지적한다
JPA/QueryDSL 조회 변경 시 N+1, 잘못된 fetch join, count 쿼리 왜곡, pagination 깨짐, distinct 누락을 확인한다
권한 로직은 관리자 우회, 요청자와 대상자 관계, 클럽/채팅방/공지/일정의 소속 검증이 빠지지 않았는지 확인한다
soft delete, 탈퇴 사용자, 차단/제외 조건, 중복 제거가 필요한 조회에서는 응답에 노출되면 안 되는 데이터가 포함되는지 확인한다
DTO 응답 변경은 기존 클라이언트가 기대하는 필드명, nullability, enum/string 값, 정렬 순서를 깨지 않는지 확인한다
조건이 2개 이상 결합된 비즈니스 규칙, 권한 조건, soft delete 제외, 중복 제거, fallback 우선순위, 대표값 선택, DTO 변환, count 쿼리 분리, fetch join 선택 이유처럼 코드만으로 의도가 숨겨지는 지점에는 주석을 권장한다
단순 생성자 호출, 필드 매핑, 컬렉션 반환, 이름만으로 명확한 분기에는 주석을 요구하지 않는다

Files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
**/*.{sql,java}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

데이터베이스 변경에서는 마이그레이션 순서, 기존 데이터 호환성, nullable/default 처리, 롤백 난이도, 인덱스 필요성을 확인한다

Files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
**/*

⚙️ CodeRabbit configuration file

**/*: 공통 리뷰 톤 가이드:

  • 모든 코멘트는 첫 줄에 [LEVEL: ...] 태그를 포함한다.
  • 과장된 표현 없이 사실 기반으로 작성한다.
  • 한 코멘트에는 하나의 이슈만 다룬다.
  • 코드 예시가 필요하면 최소 수정 예시를 제시한다.
  • 가독성/단순화/확장성 이슈를 발견하면 우선순위를 높여 코멘트한다.

Files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

src/main/java/**/*.java: 아래 원칙으로 리뷰 코멘트를 작성한다.

  • 코멘트는 반드시 한국어로 작성한다.
  • 반드시 수정이 필요한 항목만 코멘트로 남기고, 단순 취향 차이는 지적하지 않는다.
  • 각 코멘트 첫 줄에 심각도를 [LEVEL: high|medium|low] 형식으로 반드시 표기한다.
  • 심각도 기준: high=운영 장애 가능, medium=품질 저하, low=개선 권고.
  • 각 코멘트는 "문제 -> 영향 -> 제안" 순서로 3문장 이내로 간결하게 작성한다.
  • 가능하면 재현 조건 및 실패 시나리오도 포함한다.
  • 제안은 현재 코드베이스(Spring Boot + JPA + Flyway) 패턴과 일치해야 한다.
  • 보안, 트랜잭션 경계, 예외 처리, N+1, 성능 회귀 가능성을 우선 점검한다.
  • 가독성: 변수/메서드 이름이 의도를 바로 드러내는지, 중첩과 메서드 길이가 과도하지 않은지 점검한다.
  • 단순화: 불필요한 추상화, 중복 로직, 과한 방어 코드가 있으면 더 단순한 대안을 제시한다.
  • 확장성: 새 요구사항 추가 시 변경 범위가 최소화되는 구조인지(하드코딩 분기/값 여부 포함) 점검한다.

Files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
🧠 Learnings (42)
📓 Common learnings
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/chat/**/*direct*member*.{ts,tsx} : When modifying direct membership policy, verify that leftAt, visibleMessageFrom, lastReadAt states, room re-exposure conditions, past message visibility range, search/message jump visibility, and list re-exposure conditions remain consistent
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message}/**/*.{ts,tsx} : When modifying message storage logic, verify that last message metadata, direct room restoration conditions, sender's read status updates, list summary sorting, inquiry room special handling, and notification/event side effects remain consistent
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,direct}/**/{send,receive,create}*.{ts,tsx} : Direct room visibility may be restored when a new message arrives even if the receiving user has leftAt set
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member,service}/**/chat-room-membership*.{ts,tsx} : ChatRoomMembershipService must handle club_group member guarantee, direct/group membership updates, inquiry room read status exceptions, and concurrent creation/duplicate membership absorption
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/chat/**/*direct*member*.{ts,tsx} : Direct chat room states (leftAt, visibleMessageFrom, lastReadAt) must not be treated as independent values and must move together according to the leave->restore->reopen policy
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member}/**/*.{ts,tsx} : When modifying read status logic, ensure unreadCount calculation, direct room visibility range consistency, list badge and summary values, and inquiry room SYSTEM_ADMIN read status handling remain aligned
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Before modifying chat domain code, answer whether the change breaks direct's leave->restore->reopen policy, misaligns last message with unreadCount, exposes invisible messages, overgeneralizes direct/group policies, breaks SYSTEM_ADMIN reuse, leaks message existence info, or omits list metadata
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,direct}/**/*.{ts,tsx} : Direct chat room message visibility must be determined by visibleMessageFrom combined with leftAt status, not by simple member existence
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,message}/**/{repository,query,list,search}*.{ts,tsx} : When modifying list/search queries, verify custom room name priority, mute status composition, search target room type scope, direct room visible message criteria, messageId page calculation sort consistency, and inquiry room list optimization query conditions remain correct
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member}/**/chat-room-member*.{ts,tsx} : ChatRoomMember must maintain direct room visibility state (lastReadAt, visibleMessageFrom, leftAt, custom name, owner flag) with coordinated updates
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,service}/**/chat.service.{ts,tsx} : Chat service must be the central point where message sending, list summaries, access handling, and membership changes interact, coordinating all state updates
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/notification/AGENTS.md:0-0
Timestamp: 2026-04-25T06:58:54.393Z
Learning: Applies to src/main/java/gg/agit/konect/domain/notification/**/*ChatPresenceService*.java : Chat presence service tracks which users are currently viewing specific chat rooms. During chat push notification sending, check presence state to exclude users already present in the target chatroom from receiving push notifications.
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member,service}/**/chat-room-membership*.{ts,tsx} : ChatRoomMembershipService must handle club_group member guarantee, direct/group membership updates, inquiry room read status exceptions, and concurrent creation/duplicate membership absorption

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/chat/**/*direct*member*.{ts,tsx} : When modifying direct membership policy, verify that leftAt, visibleMessageFrom, lastReadAt states, room re-exposure conditions, past message visibility range, search/message jump visibility, and list re-exposure conditions remain consistent

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member}/**/chat-room-member*.{ts,tsx} : ChatRoomMember must maintain direct room visibility state (lastReadAt, visibleMessageFrom, leftAt, custom name, owner flag) with coordinated updates

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,direct}/**/*.{ts,tsx} : Direct chat room message visibility must be determined by visibleMessageFrom combined with leftAt status, not by simple member existence

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,member}/**/*.{ts,tsx} : The direct chat room leave->restore->reopen policy must not be generalized to group or club_group room types

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/chat/**/*direct*member*.{ts,tsx} : Direct chat room states (leftAt, visibleMessageFrom, lastReadAt) must not be treated as independent values and must move together according to the leave->restore->reopen policy

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,direct}/**/{send,receive,create}*.{ts,tsx} : Direct room visibility may be restored when a new message arrives even if the receiving user has leftAt set

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,message,club}/**/*.{ts,tsx} : Club group room access must validate both chat member records AND current club membership status, not just chat member table alone

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message}/**/*.{ts,tsx} : When modifying message storage logic, verify that last message metadata, direct room restoration conditions, sender's read status updates, list summary sorting, inquiry room special handling, and notification/event side effects remain consistent

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member}/**/*.{ts,tsx} : When modifying read status logic, ensure unreadCount calculation, direct room visibility range consistency, list badge and summary values, and inquiry room SYSTEM_ADMIN read status handling remain aligned

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,club}/**/{access,validate,query}*.{ts,tsx} : Club group message queries must verify both chat member existence AND current club membership status to determine access, not member table alone

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,club,member}/**/*.{ts,tsx} : When club membership changes (add/remove), chat room membership must be synchronized to maintain consistent access guarantees for club_group rooms

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member}/**/{group,club}*.{ts,tsx} : Group chat membership queries must only return active members where leftAt IS NULL, excluding deleted users

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java
📚 Learning: 2026-04-25T06:58:54.393Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/notification/AGENTS.md:0-0
Timestamp: 2026-04-25T06:58:54.393Z
Learning: Applies to src/main/java/gg/agit/konect/domain/notification/**/*ChatPresenceService*.java : Chat presence service tracks which users are currently viewing specific chat rooms. During chat push notification sending, check presence state to exclude users already present in the target chatroom from receiving push notifications.

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,service}/**/chat.service.{ts,tsx} : Chat service must be the central point where message sending, list summaries, access handling, and membership changes interact, coordinating all state updates

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-13T00:26:23.225Z
Learnt from: dh2906
Repo: BCSDLab/KONECT_BACK_END PR: 533
File: src/main/java/gg/agit/konect/domain/chat/service/ChatService.java:1511-1516
Timestamp: 2026-04-13T00:26:23.225Z
Learning: In ChatService.java (Spring Boot + JPA, MySQL InnoDB), within a `Transactional(readOnly = true)` method, retrying a repository count query (e.g., `countNewerMessagesByChatRoomId`) to handle concurrent inserts is ineffective under REPEATABLE READ isolation: the same DB snapshot is used throughout the transaction, so the retry always returns the same result. A new transaction (`Propagation.REQUIRES_NEW`) would be required for a true retry, but accepting a 1-page offset as a UX tradeoff is preferred for search navigation in this codebase.

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,direct}/**/{send,create}*.{ts,tsx} : Sending a message in a direct room must update the sender's lastReadAt to the new message timestamp and may restore the room visibility if the sender was in leftAt state

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member,message}/**/{unread,count}*.{ts,tsx} : UnreadCount calculation for direct chat rooms must consider both lastReadAt and actual visible message range (visibleMessageFrom), not just lastReadAt alone

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,group,club}/**/{send,create}*.{ts,tsx} : Sending a message in group or club_group room must update the sender's read status (lastReadAt) immediately upon send

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,direct,inquiry}/**/{create,find,reuse}*.{ts,tsx} : Direct room reuse must match the same two-user combination; admin direct chats must follow SYSTEM_ADMIN inquiry room reuse policy

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,message}/**/{repository,query,list,search}*.{ts,tsx} : When modifying list/search queries, verify custom room name priority, mute status composition, search target room type scope, direct room visible message criteria, messageId page calculation sort consistency, and inquiry room list optimization query conditions remain correct

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-25T06:58:54.393Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/notification/AGENTS.md:0-0
Timestamp: 2026-04-25T06:58:54.393Z
Learning: Applies to src/main/java/gg/agit/konect/domain/notification/**/*IntegrationTest*.java : Add regression tests for: club application event rollback resulting in zero notifications created (AFTER_COMMIT integration test), inbox list/unread count/bulk read excluding chat-related types (repository integration test), Expo push partial ticket failures logged without whole-request exception propagation, group chat token vs target user count mismatch in current policy.

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,list}/**/{query,construct,list}*.{ts,tsx} : Direct and group room types have fundamentally different list construction logic - direct uses chat_room.last_message_* directly while group/club_group combines latest message queries - these must not be unified into identical query paths

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T09:44:01.804Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/club/AGENTS.md:0-0
Timestamp: 2026-04-22T09:44:01.804Z
Learning: Applies to src/main/java/gg/agit/konect/domain/club/**/*ClubMemberManagement*|**/*ClubApplication*|**/*SheetImport* : When members are created through multiple paths (direct approval, pre-member conversion, sheet import), always add them to club group chat membership. When members are removed or demoted from leadership, remove their chat membership. Maintain consistency between `ClubMember` state and chat group membership.

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,repository}/**/*.{ts,tsx} : Repository layer must implement optimized queries for latest message retrieval, unreadCount calculation, list optimization, and distinct handling of direct vs group list logic

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,inquiry,admin,system}/**/{send,create}*.{ts,tsx} : Inquiry room (SYSTEM_ADMIN) message send by general admin must not add the admin as a room member and must use special handling

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,list,inquiry,admin}/**/*.{ts,tsx} : Admin inquiry room list must use separate optimized query returning only rooms where the admin has actually sent responses, distinct from regular direct list logic

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,search}/**/{query,filter}*.{ts,tsx} : Search results must filter by room type scope (currently direct and club_group only, excluding general group rooms)

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member,message}/**/*{inquiry,admin,system}*.{ts,tsx} : Inquiry room (SYSTEM_ADMIN type) unreadCount and read status must be aggregated/updated by SYSTEM_ADMIN user record, not by individual admin users

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,search}/**/*.{ts,tsx} : Search results must apply custom room name and default room name policies consistently across both room name search and message content search

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,room}/**/{create,send,save,update}*.{ts,tsx} : Last message metadata (chat_room.last_message_*) must always reflect the actual latest message visible to users, even under concurrent send conditions

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,page,jump}/**/*.{ts,tsx} : MessageId page calculation must validate room access permission and message visibility range before calculating pagination position to prevent information disclosure

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member,invite}/**/*.{ts,tsx} : When modifying invite eligible user queries, ensure only active members are included, admin/deleted users are excluded, club section criteria reflects actual shared clubs, and 'other' section classification is maintained

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-25T06:58:54.393Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/notification/AGENTS.md:0-0
Timestamp: 2026-04-25T06:58:54.393Z
Learning: Applies to src/main/java/gg/agit/konect/domain/notification/**/*NotificationInboxService*.java : Inbox list retrieval: default page 1, page size 20, sort by `createdAt DESC, id DESC`. Exclude chat-related types (`CHAT_MESSAGE`, `GROUP_CHAT_MESSAGE`, `UNREAD_CHAT_COUNT`) from list queries, unread count queries, and bulk read operations. Single read operation only allows reading user's own notification; other users' notification ids are treated as not found. Bulk read operation only marks unread notifications of non-chat types as read.

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/chat/**/*{inquiry,admin,system}*.{ts,tsx} : SYSTEM_ADMIN inquiry room reuse policy (SYSTEM_ADMIN + regular user pair) must not be broken by adding general admins as room members

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,member,setting}/**/{mute,toggle}*.{ts,tsx} : Mute setting changes must only be allowed in rooms the current user has access to; for inquiry rooms, admins not listed as members must still be allowed to toggle mute if they access the same SYSTEM_ADMIN inquiry room

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,message,search}/**/{list,summary,search}*.{ts,tsx} : Direct chat rooms must not expose invisible messages (based on visibleMessageFrom) in list summaries or search results

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T09:44:01.804Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/club/AGENTS.md:0-0
Timestamp: 2026-04-22T09:44:01.804Z
Learning: Applies to src/main/java/gg/agit/konect/domain/club/**/*ClubMemberManagement* : Club member removal is not a generic role removal operation. Invariants: (1) cannot remove self, (2) leader access required, (3) cannot remove president, (4) only `MEMBER` can be removed directly, (5) non-admin requesters must pass `canManage(target)` check, (6) admin bypasses hierarchy but not `MEMBER`-only constraint. Always remove from club group chat membership simultaneously.

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-24T12:50:59.744Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/user/AGENTS.md:0-0
Timestamp: 2026-04-24T12:50:59.744Z
Learning: Applies to src/main/java/gg/agit/konect/domain/user/**/*user*/**/*.{ts,tsx,js,jsx} : Ensure direct chat membership before saving operator welcome message; sync saved message to `chat_room.last_message_*` using latest message conditions

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,message,group}/**/{send,create,validate}*.{ts,tsx} : Group room message send must reject messages from users with leftAt set (left members)

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
📚 Learning: 2026-04-22T08:07:59.395Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/chat/AGENTS.md:0-0
Timestamp: 2026-04-22T08:07:59.395Z
Learning: Applies to src/main/java/gg/agit/konect/domain/chat/**/{chat,room,member,direct}/**/{name,display}*.{ts,tsx} : Direct room name resolution must prioritize custom per-user names over default peer user names

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
🔇 Additional comments (3)
src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java (1)

17-57: [LEVEL: low] LGTM — direct room 접근/복원 책임 분리 의도 명확.

getAccessibleMemberprepareAccessAndGetVisibleMessageFromhasLeft/hasVisibleMessages 조합으로 가시성을 판정하고, restoreDirectRoom()leftAt만 해제(visibleMessageFrom 유지)하는 도메인 정책과 일관됩니다. 모든 호출처가 writable @Transactional 상태이므로 dirty-tracking 복원이 정상 영속화되며, restoreIfVisible의 FORBIDDEN 분기로 leave→복원 정책의 음의 케이스도 잘 막아집니다.

src/main/java/gg/agit/konect/domain/chat/service/ChatService.java (2)

338-343: [LEVEL: low] @Transactional 변경 적절.

getMessages 경로가 prepareAccessAndGetVisibleMessageFromrestoreDirectRoom()(dirty-tracking으로 leftAt 해제)을 수행하므로, 클래스 기본값 readOnly=true에서는 Hibernate의 MANUAL flush로 영속화가 누락되는 회귀가 발생합니다. 두 오버로드 모두 writable로 승격되어 복원 상태 변경이 정상 커밋되며, 내부에서 호출되는 chatDirectRoomAccessService 또한 REQUIRED 전파로 같은 트랜잭션에 합류하므로 일관됩니다.


414-414: [LEVEL: low] direct room 접근 검증 위임 일관성 OK.

toggleMute(414), getDirectChatRoomMessages(631-632), sendDirectMessage(670-672), getAccessibleRoomMember(988-990) 네 진입점이 동일한 chatDirectRoomAccessService 메서드 쌍으로 수렴합니다. 특히 671의 admin↔SYSTEM_ADMIN 분기 가드가 보존돼 SYSTEM_ADMIN 문의방 정책(일반 admin을 멤버로 추가하지 않음)이 깨지지 않고, 674의 findByChatRoomId 결과는 직전 복원으로 dirty 상태인 sender를 JPA AUTO flush로 반영합니다.

Also applies to: 631-632, 671-671, 990-990


📝 Walkthrough

Walkthrough

새로운 ChatDirectRoomAccessService 도메인 서비스를 도입하여 직접 채팅방 접근 권한을 검증하고 멤버의 가시성 상태를 관리합니다. ChatService에서 관련 로직을 추출하여 이 새로운 서비스에 위임함으로써 관심사를 분리합니다.

Changes

Cohort / File(s) Summary
새로운 도메인 서비스
src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java
직접 채팅방 멤버 접근 권한 검증 및 복구 로직을 담당하는 새로운 공개 서비스. ChatRoomMember 조회, 떠난 멤버 복구 여부 판단, 가시 메시지 존재 여부 확인을 담당합니다.
서비스 리팩토링
src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
직접 채팅방 접근 및 복구 로직을 ChatDirectRoomAccessService로 위임. getMessages 메서드들의 트랜잭션 범위를 읽기 전용에서 일반 트랜잭션으로 변경하여 부작용 허용. 내부 헬퍼 메서드 제거.
테스트 추가 및 업데이트
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java, src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
새로운 서비스의 핵심 플로우(멤버 반환, 떠난 멤버 복구, 접근 거부) 3가지를 검증하는 테스트 추가. ChatService 테스트 설정에 새로운 서비스 의존성 주입.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels

테스트

Poem

🐰 홉홉 차팅방 로직을 옮기니
서비스는 깔끔하게, 책임은 명확하게,
새 집 ChatDirectRoomAccessService에서
멤버들의 접근을 우아하게 지키네!
리팩토링의 마술, 코드가 춤춘다 ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경 사항인 direct room 접근 복원 책임의 분리를 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 변경 사항, 테스트 검증, 그리고 체크리스트를 포함하여 충분한 맥락을 제공합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/chat-direct-room-access-service-594

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dh2906 dh2906 added the 리팩토링 리팩터링을 위한 이슈입니다. label Apr 27, 2026
@dh2906 dh2906 self-assigned this Apr 27, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

🧪 JaCoCo Coverage Report (Changed Files)

Summary

  • Overall Coverage: 88.4% ✅
  • Covered Lines: 620 / 701
  • Changed Files: 2

Coverage by File

Class Coverage Lines Status
ChatService
gg.agit.konect.domain.chat.service
88.2% 605/686
ChatDirectRoomAccessService
gg.agit.konect.domain.chat.service
100.0% 15/15

📊 View Workflow Run

- setUp에서만 쓰는 보조 서비스 인스턴스를 지역 변수로 좁혀 테스트 상태를 줄임

- 복원 테스트는 반환 객체보다 변경 대상 멤버 상태를 직접 검증해 의도를 명확히 함
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

ChatService에 남아 있던 direct room 접근 검증/복원(visibleMessageFrom 기준 포함) 책임을 ChatDirectRoomAccessService로 분리해, 메시지 조회/전송/뮤트 등에서 재사용하도록 리팩터링한 PR입니다. (Refs #594)

Changes:

  • direct room 멤버 접근 가능 여부 확인 및 “나간 방 복원” 판단 로직을 ChatDirectRoomAccessService로 이동
  • ChatService에서 direct room 관련 접근 검증 호출부를 신규 서비스로 치환하고 기존 private helper 제거
  • direct room 접근/복원 정책에 대한 단위 테스트(ChatDirectRoomAccessServiceTest) 추가 및 기존 ChatServiceTest 생성자 구성 갱신

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/main/java/gg/agit/konect/domain/chat/service/ChatService.java direct room 접근/복원 로직을 신규 서비스로 위임하도록 경로 정리 및 기존 helper 제거
src/main/java/gg/agit/konect/domain/chat/service/ChatDirectRoomAccessService.java direct room 멤버 조회/접근 검증/복원 로직을 캡슐화한 전용 서비스 추가
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java ChatService 생성자 변경(신규 의존성 주입) 반영
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatDirectRoomAccessServiceTest.java direct room 접근 및 “나간 방 복원/거부” 정책 단위 테스트 추가

Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
- 메시지 조회는 lastReadAt 갱신과 direct room 복원을 수행하므로 readOnly 트랜잭션에서 제외

- direct room 접근 서비스가 나간 방 복원 상태를 변경할 수 있음을 트랜잭션 선언에 반영

- 조회 흐름에서 leftAt 해제가 영속화되지 않는 회귀를 방지
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatService.java Outdated
@dh2906 dh2906 merged commit 38eebb3 into develop Apr 28, 2026
5 checks passed
@dh2906 dh2906 deleted the refactor/chat-direct-room-access-service-594 branch April 28, 2026 00:12
@dh2906 dh2906 linked an issue Apr 28, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

리팩토링 리팩터링을 위한 이슈입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

채팅 리팩토링: direct room 접근/복원 책임 분리

3 participants