Skip to content

refactor: 메시지 조회 페이지 계산 책임 분리#593

Merged
dh2906 merged 5 commits intodevelopfrom
refactor/chat-message-read-service-592
Apr 27, 2026
Merged

refactor: 메시지 조회 페이지 계산 책임 분리#593
dh2906 merged 5 commits intodevelopfrom
refactor/chat-message-read-service-592

Conversation

@dh2906
Copy link
Copy Markdown
Contributor

@dh2906 dh2906 commented Apr 27, 2026

🔍 개요


🚀 주요 변경 내용

  • ChatMessagePageResolver를 추가해 messageId 조회 권한 검증, visibleMessageFrom 검증, 페이지 계산을 담당하도록 정리했습니다.
  • ChatService는 messageId가 있는 조회 요청에서 resolver에 위임하도록 단순화했습니다.
  • 기존 ChatService 단위 테스트가 실제 resolver를 사용하도록 구성해 기존 조회 정책 검증을 유지했습니다.

💬 참고 사항

  • #592의 1차 분리 작업이며, 이 PR만으로 이슈를 닫지 않습니다.
  • 검증: ./gradlew checkstyleMain
  • 검증: CI=true ./gradlew test --tests 'gg.agit.konect.unit.domain.chat.service.ChatServiceTest' --rerun-tasks
  • 검증: CI=true ./gradlew test --tests 'gg.agit.konect.integration.domain.chat.ChatApiTest' --rerun-tasks

✅ Checklist (완료 조건)

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

- ChatService에 남아 있던 messageId 접근 검증과 페이지 계산을 별도 서비스로 분리
- 권한 없음과 메시지 미존재를 같은 404로 처리하는 조회 정책을 한곳에 모음
- 기존 ChatService 단위 테스트가 실제 resolver를 사용하도록 구성해 기존 정책 검증을 유지
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Warning

Rate limit exceeded

@dh2906 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 45 minutes and 25 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3722bfcd-f769-4f6e-bbdf-0c57dc5a1dba

📥 Commits

Reviewing files that changed from the base of the PR and between 13255fe and 8c342de.

📒 Files selected for processing (4)
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatRoomSystemAdminService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatRoomSystemAdminServiceTest.java
📝 Walkthrough

Walkthrough

ChatService에서 메시지 접근·가시성·페이지 계산 책임을 분리하여 신규 서비스들로 위임했습니다: 메시지 페이지 계산은 ChatMessagePageResolver로, SYSTEM_ADMIN 방 판별은 ChatRoomSystemAdminService로 이동했습니다. 관련 테스트들이 이 변경에 맞춰 수정·추가되었습니다.

Changes

Cohort / File(s) Summary
새 리졸버 및 관련 도메인 로직
src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
room 유형별 접근성 검증(직접/클럽/일반), direct-room의 visibleMessageFrom 판정(시스템 관리자 멤버 기준 포함), 대상 메시지 검증 및 최신 메시지 카운트 후 페이지 계산을 구현한 신규 서비스 추가.
시스템 관리자 판별 서비스 추가
src/main/java/gg/agit/konect/domain/chat/service/ChatRoomSystemAdminService.java
지정된 방에 SYSTEM_ADMIN 멤버 존재 여부 확인(isSystemAdminRoom) 및 목록에서 시스템 관리자 멤버 추출(findSystemAdminMember) 기능 추가.
ChatService 리팩토링
src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
messageId 기반 흐름에서 직접 검사·계산 로직 제거 후 ChatMessagePageResolver 호출로 위임. SYSTEM_ADMIN 판별 호출을 로컬 로직 대신 ChatRoomSystemAdminService로 전환. 여러 private 헬퍼 제거.
ChatRoomMembershipService 변경
src/main/java/gg/agit/konect/domain/chat/service/ChatRoomMembershipService.java
SYSTEM_ADMIN 판별을 로컬 쿼리에서 ChatRoomSystemAdminService.isSystemAdminRoom(...) 호출로 위임.
단위/통합 테스트 추가·수정
src/test/java/gg/agit/konect/unit/domain/chat/service/...
ChatMessagePageResolverTest 추가로 접근제어·가시성·페이지 계산 시나리오 검증. ChatServiceTest, ChatRoomMembershipServiceTest 수정해 시스템 관리자 관련 스텁을 ChatRoomSystemAdminService로 전환. ChatRoomSystemAdminServiceTest 추가.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ChatService
    participant ChatMessagePageResolver as Resolver
    participant ChatRoomSystemAdminService as AdminSvc
    participant MessageRepo
    participant MessageCountRepo

    Client->>ChatService: getMessages(roomId, messageId, ...)
    ChatService->>Resolver: resolvePageForMessage(roomId, messageId, room, user, limit)
    Resolver->>AdminSvc: isSystemAdminRoom(roomId)?
    alt club/group room
        Resolver->>ChatRoomMembershipRepo: validate club membership
    else direct/normal room
        Resolver->>ChatRoomMembershipRepo: validate membership (non-left)
    end
    Resolver->>MessageRepo: findByIdWithChatRoom(messageId)
    Resolver->>AdminSvc: findSystemAdminMember(members) (if direct)
    Resolver->>MessageCountRepo: count newer messages with visibleMessageFrom cutoff
    MessageCountRepo-->>Resolver: newerCount
    Resolver-->>ChatService: pageIndex
    ChatService-->>Client: return messages page
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

리팩토링

개요 (업데이트된 기존 섹션)

채팅 메시지 페이지 해석 및 접근 제어 로직을 ChatService에서 새로운 ChatMessagePageResolver 클래스로 추출하는 리팩토링이 적용되었습니다. 메시지 조회 권한 검증, 가시성 규칙 적용, 페이지 번호 계산 로직이 전용 리졸버로 이관되었습니다.

변경 사항 (업데이트된 기존 표)

코호트 / 파일 요약
새로운 리졸버 구현
src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
메시지 페이지 인덱스 계산을 위한 새로운 클래스 추가. 사용자 접근 권한 검증(방 유형별 회원 확인), 메시지 가시성 확인(직접 메시지방의 경우 가시성 기준 시간 적용), 더 새로운 메시지 개수 계산을 통한 페이지 번호 반환 기능 구현.
ChatService 리팩토링
src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
getMessages(..., messageId) 메서드에서 ChatMessagePageResolver.resolvePageForMessage(...)로 페이지 계산 로직을 위임. 기존 private 헬퍼 메서드(ensureMessageLookupAccess, resolvePageForMessage, resolveVisibleMessageFromPure) 제거.
테스트 수정
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
@InjectMocks 자동 생성 대신 @BeforeEach에서 ChatMessagePageResolver 수동 생성 및 생성자 주입으로 변경. 명시적 의존성 조립 패턴 적용.

예상 검토 소요 시간 (업데이트된 기존 값)

🎯 4 (Complex) | ⏱️ ~45 minutes

🐰
코드 숲 속에서 토끼가 뛰네,
조각난 로직 모아 새 길 만들고,
페이지는 똑바로, 권한은 단단히,
테스트도 춤추며 환호하네! 🥕✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/chat-message-read-service-592

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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

🧪 JaCoCo Coverage Report (Changed Files)

Summary

  • Overall Coverage: 89.7% ✅
  • Covered Lines: 751 / 837
  • Changed Files: 4

Coverage by File

Class Coverage Lines Status
ChatService
gg.agit.konect.domain.chat.service
88.1% 620/704
ChatRoomMembershipService
gg.agit.konect.domain.chat.service
97.6% 82/84
ChatMessagePageResolver
gg.agit.konect.domain.chat.service
100.0% 44/44
ChatRoomSystemAdminService
gg.agit.konect.domain.chat.service
100.0% 5/5

📊 View Workflow Run

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java`:
- Around line 63-105: ensureMessageLookupAccess and resolveVisibleMessageFrom
perform duplicate DB lookups for the same (roomId, userId) and repeat
findRoomMemberIdsByChatRoomIds for admin/system-room checks; modify
resolveVisibleMessageFrom to accept the already-fetched ChatRoomMember Optional
(or the List<ChatRoomMember> for admin path) instead of querying inside it, and
have ensureMessageLookupAccess return or forward that Optional/List to
resolveVisibleMessageFrom so you reuse the result from
chatRoomMemberRepository.findByChatRoomIdAndUserId(...) (and
chatRoomMemberRepository.findByChatRoomId(...) in the admin branch) rather than
calling those repository methods again. Ensure method signatures updated (e.g.,
resolveVisibleMessageFrom(ChatRoom, User, Optional<ChatRoomMember>) or
resolveVisibleMessageFrom(ChatRoom, User, List<ChatRoomMember>)) and update
callers accordingly to remove the duplicated DB calls.
- Around line 107-121: The two private helpers isSystemAdminRoom and
findRoomMember in ChatMessagePageResolver duplicate logic already present in
ChatService; refactor by removing these methods from ChatMessagePageResolver and
delegating their behavior to the single authoritative implementation in
ChatService (or extract a new shared component like ChatRoomMembershipService
and call that from both places). Locate references to isSystemAdminRoom and
findRoomMember in ChatMessagePageResolver, replace direct calls to the removed
methods with calls to ChatService's corresponding methods (or the new shared
service), and update imports/constructor injection to obtain ChatService or the
new shared service so the resolver uses the single source of truth.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5c732b5b-87d7-4f0a-9b1f-98976a46a4f9

📥 Commits

Reviewing files that changed from the base of the PR and between abbc6ff and 718478a.

📒 Files selected for processing (3)
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📜 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). (3)
  • GitHub Check: coverage
  • GitHub Check: Code Style Check
  • 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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
**/*.{sql,java}

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

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

Files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.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/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
**/*

⚙️ CodeRabbit configuration file

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

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

Files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
🧠 Learnings (38)
📓 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,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
📚 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/ChatService.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,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
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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,message,search}/**/{find,search,jump,page}*.{ts,tsx} : Permission denied (no access) must not be exposed as message not found in messageId lookup and search paths to prevent information disclosure about hidden messages

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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/ChatService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.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/**/*.java : When modifying inbox functionality, verify: chat-related type exclusion set (`CHAT_MESSAGE`, `GROUP_CHAT_MESSAGE`, `UNREAD_CHAT_COUNT`), page size default of 20, sort order `createdAt DESC, id DESC`, userId ownership check for single read, and chat-type exclusion in bulk read operations.

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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,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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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,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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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,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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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,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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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,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/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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/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/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} : Reuse existing direct chat room if already present; create new one only if none exists for welcome message flow

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.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,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/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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/main/java/gg/agit/konect/domain/chat/service/ChatService.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/**/*{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/**/*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/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}/**/{list,summary}*.{ts,tsx} : Chat room list summaries must combine last message, last send time, unreadCount, room name, and mute status consistently without treating direct and group room construction separately

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.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/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.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-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/**/*.java : When modifying chat notification logic, verify: ChatPresenceService presence filtering, NotificationMuteSetting CHAT_ROOM mute filtering, sender exclusion for group chat, Unicode code point basis (not Java string length) for 30-character preview limit, payload path format `chats/{roomId}`, and that exceptions are caught in async boundary.

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,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/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,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/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,club}/**/{send,create}*.{ts,tsx} : Club group message send must verify sender is currently a club member and may need to ensure chat room membership is guaranteed

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,group,club}/**/{name,display}*.{ts,tsx} : Club_group room default name is the club name, and general group default name is 'group chat' - these must not be confused or swapped

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/**/{group,club}*.{ts,tsx} : When modifying group or club_group membership policy, ensure access permissions, member removal and kick policies, list visibility, and club membership synchronization remain consistent

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,club}/**/{create,find}*.{ts,tsx} : Concurrent room creation attempts for club_group must not produce duplicates - instead converge to the same room via re-query

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,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/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,group}/**/{send,create,validate}*.{ts,tsx} : Group room message send must reject messages from users with leftAt set (left members)

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/**/*ClubService* : Club creation is admin-exclusive. At creation, atomically: (1) save club entity, (2) create club group chat room, (3) register specified president as `PRESIDENT` member, (4) add president to chat membership, (5) create 2 default application questions: 'Phone number (required)' and 'Motivation (optional)'

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,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/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}/**/*group*.{ts,tsx} : Group chat room reuse must be based on requester-excluding non-duplicate user sets as the key, not including the requester themselves

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java

Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java Outdated
Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java Outdated
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

messageId 기반 메시지 조회에서 접근 검증/visibleMessageFrom 검증/페이지 계산 책임을 ChatService에서 분리해 읽기 흐름을 명확히 하는 리팩터링입니다(#592 1차 작업). 기존 조회 정책을 유지하면서, 관련 로직을 ChatMessagePageResolver로 위임해 ChatService의 복잡도를 낮춥니다.

Changes:

  • ChatMessagePageResolver를 추가하여 messageId 기반 조회 시 접근 검증, 가시성 검증, 페이지 계산을 담당
  • ChatService.getMessages()에서 messageId 케이스의 페이지 계산을 resolver로 위임
  • ChatServiceTest가 resolver 실구현을 사용하도록 테스트 구성 변경(수동 생성)

Reviewed changes

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

File Description
src/main/java/gg/agit/konect/domain/chat/service/ChatService.java messageId 기반 페이지 계산/접근 검증 로직을 ChatMessagePageResolver로 위임하도록 정리
src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java messageId 기반 조회의 접근 검증 + visibleMessageFrom 검증 + 페이지 계산 로직을 신규 서비스로 분리
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java 단위 테스트에서 ChatService를 수동 생성하고 실제 resolver를 주입하도록 변경

Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java Outdated
Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java Outdated
dh2906 added 2 commits April 27, 2026 14:48
- ChatMessagePageResolver의 방 타입별 접근 검증과 페이지 계산 분기를 단위 테스트로 보강
- direct visibleMessageFrom, system admin 문의방, club membership 예외 변환 정책을 직접 검증
- messageId 조회 전에 권한 없는 요청을 차단하는 오라클 방지 흐름을 유지
- 리뷰에서 지적된 ChatMessagePageResolver의 중복 멤버십 조회를 제거하기 위해 접근 검증 결과를 재사용

- SYSTEM_ADMIN 방 판별과 시스템 관리자 멤버 선택을 공용 서비스로 분리해 ChatService와 MembershipService의 중복 기준을 제거

- 관련 단위 테스트를 갱신하고 공용 서비스 테스트를 추가해 문의방 조회 정책을 유지
@dh2906 dh2906 requested a review from Copilot April 27, 2026 07:10
@dh2906 dh2906 self-assigned this Apr 27, 2026
@dh2906 dh2906 added the 리팩토링 리팩터링을 위한 이슈입니다. label Apr 27, 2026
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 8 out of 8 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/main/java/gg/agit/konect/domain/chat/service/ChatService.java:1158

  • getOrCreateDirectRoomMember()의 orElseGet 블록에서 if (admin && system-admin 방) 분기가 있지만, if/else 모두 동일하게 FORBIDDEN_CHAT_ROOM_ACCESS를 던지고 있어 조건문이 의미가 없습니다. 조건을 제거해 단순화하거나(항상 동일 예외라면), 분기를 유지할 의도가 있다면 각 케이스의 예외/처리 차이를 코드로 드러내는 편이 유지보수에 안전합니다.
        return chatRoomMemberRepository.findByChatRoomIdAndUserId(chatRoom.getId(), user.getId())
            .orElseGet(() -> {
                // 어드민은 SYSTEM_ADMIN 방에 멤버로 추가되지 않음
                if (user.isAdmin() && chatRoomSystemAdminService.isSystemAdminRoom(chatRoom.getId())) {
                    throw CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS);
                }
                throw CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS);
            });

Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatRoomSystemAdminService.java Outdated
Comment thread src/main/java/gg/agit/konect/domain/chat/service/ChatMessagePageResolver.java Outdated
- SYSTEM_ADMIN 방 판별은 멤버 목록 조회 대신 존재 여부 쿼리로 처리해 불필요한 로딩을 줄임

- direct room 멤버십이 이미 확인된 경우 SYSTEM_ADMIN 방 판별을 건너뛰어 일반 admin 조회 경로의 추가 쿼리를 방지

- 동일 예외만 던지던 직접방 멤버 조회 분기를 단순화해 조건 드리프트 여지를 제거
@dh2906
Copy link
Copy Markdown
Contributor Author

dh2906 commented Apr 27, 2026

getOrCreateDirectRoomMember()의 orElseGet 블록에서 if (admin && system-admin 방) 분기가 있지만, if/else 모두 동일하게 FORBIDDEN_CHAT_ROOM_ACCESS를 던지고 있어 조건문이 의미가 없습니다.

Addressed: 동일 예외만 던지는 분기를 제거하고 orElseThrow(() -> CustomException.of(FORBIDDEN_CHAT_ROOM_ACCESS))로 단순화했습니다.

- direct room 멤버가 없는 admin 문의방 경로에서 빈 멤버십 상태를 명시해 조건 추적을 줄임

- 이미 검증된 SYSTEM_ADMIN 방 접근 여부만 컨텍스트에 담아 기존 조회 정책은 그대로 유지
@dh2906 dh2906 merged commit 12fc544 into develop Apr 27, 2026
5 checks passed
@dh2906 dh2906 deleted the refactor/chat-message-read-service-592 branch April 27, 2026 07:27
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.

2 participants