Skip to content

refactor: 초대 후보 조회 책임 분리#602

Merged
dh2906 merged 2 commits intodevelopfrom
refactor/chat-invite-service-596
Apr 28, 2026
Merged

refactor: 초대 후보 조회 책임 분리#602
dh2906 merged 2 commits intodevelopfrom
refactor/chat-invite-service-596

Conversation

@dh2906
Copy link
Copy Markdown
Contributor

@dh2906 dh2906 commented Apr 28, 2026

🔍 개요


🚀 주요 변경 내용

  • ChatInviteService를 추가해 이름 정렬과 동아리 정렬 초대 후보 응답 생성을 담당하도록 분리
  • ChatService는 getInvitableUsers 요청을 새 서비스에 위임하도록 축소
  • ChatInviteServiceTest를 추가해 이름 정렬 목록 응답과 동아리 섹션 조립을 검증

💬 참고 사항

  • checkstyleTest는 기존 테스트 파일의 120자 초과 위반으로 실패합니다. 이번 변경 파일에서는 신규 위반이 없습니다.
  • CI=true를 붙인 특정 통합 테스트 실행은 기존 테스트 소스 일부가 메인 클래스를 찾지 못하는 컴파일 실패가 재현되어, 동일 대상은 CI=true 없이 별도로 통과 확인했습니다.

✅ Checklist (완료 조건)

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

- ChatService에 남아 있던 초대 후보 조회와 응답 섹션 조립 책임을 ChatInviteService로 이동
- 메시지/방 상태 변경 중심 서비스에서 조회 전용 흐름을 분리해 후속 채팅 리팩토링 범위를 줄임
- 이름 정렬과 동아리 정렬 응답 조립 테스트를 추가해 기존 API 응답 구조를 보존
@dh2906 dh2906 added the 리팩토링 리팩터링을 위한 이슈입니다. label Apr 28, 2026
@dh2906 dh2906 self-assigned this Apr 28, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Warning

Rate limit exceeded

@dh2906 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 34 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: 03ee1c19-f140-44de-8863-e30c88d8fe45

📥 Commits

Reviewing files that changed from the base of the PR and between c0b4368 and fc8c669.

📒 Files selected for processing (1)
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.java
📝 Walkthrough

Walkthrough

채팅 초대 로직을 별도의 ChatInviteService로 분리하는 리팩토링입니다. 사용자 검증, 페이지 요청 구성, 초대 가능 사용자 조회(이름/클럽 정렬 포함), 클럽별 섹션 구성을 새 서비스로 이동하고, ChatService는 이 기능에 위임합니다.

Changes

Cohort / File(s) Summary
ChatInviteService 신규 추가
src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.java
초대 가능 사용자 조회 로직을 담당하는 새로운 트랜잭션 읽기 전용 서비스. 사용자 검증, 페이지 요청 구성, 이름/클럽 정렬별 응답 구성(클럽별 섹션 그룹핑 포함)을 수행합니다.
ChatService 리팩토링
src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
초대 사용자 조회 기능을 ChatInviteService에 위임하도록 변경. 직접 사용하던 ChatInviteQueryRepository 의존성과 관련 로직 제거.
ChatInviteService 테스트
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.java
새로운 서비스에 대한 단위 테스트 추가. 이름 정렬 및 클럽 정렬 시나리오에 대한 응답 검증, 클럽별 섹션 그룹핑 및 순서 검증.
ChatService 테스트 업데이트
src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
테스트 설정 변경: ChatInviteQueryRepository 모킹 제거, ChatInviteService 모킹 추가.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 초대 로직 분리하니 맑고 깔끔,
채팅 서비스 책임 줄이고 단정,
클럽 묶음 섹션도 새로운 집에서 빛나고,
페이지 나누며 사용자 맞춤 정렬,
테스트도 든든히 지켜내니 모두 행복! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 제목은 변경사항의 핵심을 명확하게 요약하고 있으며, ChatService의 초대 후보 조회 책임을 ChatInviteService로 분리한 리팩토링의 주요 목적을 정확히 반영합니다.
Description check ✅ Passed PR 설명은 변경사항과 관련된 명확한 개요, 주요 변경 내용, 참고 사항을 포함하고 있으며, 링크된 이슈 #596과의 연계성을 제시하고 있습니다.
Linked Issues check ✅ Passed 변경사항이 이슈 #596의 모든 주요 요구사항을 충족합니다: ChatInviteService 추가로 getInvitableUsers 흐름 분리, 이름/CLUB 정렬 응답 조립을 새 서비스로 이동, 기존 API 응답 구조와 페이징 유지, ChatInviteServiceTest와 ChatServiceTest 추가로 단위 테스트 검증.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #596의 책임 분리 요구사항 범위 내에 있으며, 불필요한 추가 리팩토링이나 범위 외의 기능 변경은 없습니다.

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

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

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 28, 2026

🧪 JaCoCo Coverage Report (Changed Files)

Summary

  • Overall Coverage: 88.2% ✅
  • Covered Lines: 606 / 687
  • Changed Files: 2

Coverage by File

Class Coverage Lines Status
ChatService
gg.agit.konect.domain.chat.service
87.8% 559/637
ChatInviteService
gg.agit.konect.domain.chat.service
94.0% 47/50

📊 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/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.java`:
- Around line 70-114: Update the test getInvitableUsersReturnsClubSections in
ChatInviteServiceTest to include a candidate who shares two clubs with the
requester and verify representative-club selection and "기타" grouping: create a
third User (e.g., dualSharedUser) and two Club/ClubMember fixtures (e.g., clubA
and clubB with ClubMemberFixture.createMember for the dualSharedUser), update
the mock for chatInviteQueryRepository.findInvitableUserIdsGroupedByClub to
return ids including the dualSharedUser, update userRepository.findAllByIdIn and
chatInviteQueryRepository.findSharedClubMemberships to return both shared
memberships for that user (and no shared memberships for the non-shared
candidate), call service.getInvitableUsers as before, and add assertions that
the dualSharedUser is placed into the expected representative club section (one
of the shared clubs you choose deterministically) while the truly non-shared
candidate ends up in the "기타" section; adjust the verify on
userRepository.findAllByIdIn to include the new ids.
- Around line 38-68: The test getInvitableUsersReturnsNameSortedUsers only
asserts content but not paging metadata; update this test (and the CLUB-sorted
counterpart) to assert ChatInvitableUsersResponse pagination fields (totalCount,
currentCount, totalPage, currentPage) match the PageImpl you stubbed (e.g.,
totalElements=1, page size=20, page index=0), so the API paging contract is
validated; locate assertions around ChatInvitableUsersResponse.response and add
checks for response.totalCount(), response.currentCount(), response.totalPage(),
and response.currentPage() to reflect the PageRequest/PageImpl values.
🪄 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: 8ccae329-ad29-4d29-96fb-7834ae519f69

📥 Commits

Reviewing files that changed from the base of the PR and between 38eebb3 and c0b4368.

📒 Files selected for processing (4)
  • src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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). (2)
  • GitHub Check: coverage
  • 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/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.java
**/*.{sql,java}

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

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

Files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.java
**/*

⚙️ CodeRabbit configuration file

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

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

Files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/ChatInviteService.java
🧠 Learnings (35)
📓 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,member,invite}/**/*.{ts,tsx} : Invite eligible user club section sorting must be based on actual shared primary clubs between requester and candidate, with non-shared candidates falling into 'other' section
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
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
📚 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} : Invite eligible user club section sorting must be based on actual shared primary clubs between requester and candidate, with non-shared candidates falling into 'other' section

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/ChatInviteServiceTest.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,invite}/**/*.{ts,tsx} : Invite eligible users must exclude the requester themselves, left members, deleted users, and admin users, drawing from active chat room members the requester shares

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.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/gg/agit/konect/domain/chat/service/ChatInviteService.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/ChatInviteServiceTest.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/ChatInviteServiceTest.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-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/test/java/gg/agit/konect/unit/domain/chat/service/ChatInviteServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.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/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
  • 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-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/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,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}/**/{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
  • 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*|**/*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
  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.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
  • 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/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/**/*ClubMember* : For operations modifying member state (role changes, removals, pre-member conversion, sheet import), verify: (1) all constraints apply (cardinality limits, self-exclusion, position removal restrictions), (2) chat membership is updated atomically, (3) current documentation matches actual implementation (do not trust API docs alone)

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
📚 Learning: 2026-04-24T12:50:59.743Z
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.743Z
Learning: Applies to src/main/java/gg/agit/konect/domain/user/**/*user*/**/*.{ts,tsx,js,jsx} : When ClubPreMember is matched during signup (same university, student ID, name), convert to actual ClubMember and add to club group chat membership

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/**/*UserService*|**/*ClubMember* : During user join, automatically convert `ClubPreMember` entries to `ClubMember` using same 3-dimensional matching (university + student number + name). If converted pre-member was `PRESIDENT`, demote existing president to `MEMBER` first, then promote new joiner. Always add new member to relevant club group chat membership.

Applied to files:

  • src/test/java/gg/agit/konect/unit/domain/chat/service/ChatServiceTest.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.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
📚 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
  • 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}/**/*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/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
📚 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
📚 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/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/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/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
📚 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/**/*ClubQuery*Repository|**/*ClubService* : For club list queries: (1) filter by same university as requester, (2) when no recruitment filter applied, show recruiting clubs first then others, (3) when recruitment filter applied, show only currently recruiting clubs. A club is recruiting when: `isRecruitmentEnabled=true` AND recruitment post exists AND (`isAlwaysRecruiting=true` OR `startAt <= now <= endAt`)

Applied to files:

  • src/main/java/gg/agit/konect/domain/chat/service/ChatService.java
  • src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.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*|**/*ClubQuery*Repository : For managed clubs query: return only clubs where requester is `MANAGER` or above (non-admin). For admin requesters, return all clubs in the same university context.

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
  • src/main/java/gg/agit/konect/domain/chat/service/ChatInviteService.java

@dh2906 dh2906 requested a review from Copilot April 28, 2026 01:21
- 초대 후보 응답의 페이징 메타데이터를 테스트로 고정해 리팩터링 중 API 계약이 흔들리지 않도록 함
- 동아리 정렬에서 후보가 여러 공유 동아리에 속한 경우 첫 대표 동아리 섹션으로 유지되는 경계를 검증함
- 공유 동아리가 없는 후보는 기타 섹션으로 분리되는 기존 정책을 함께 보장함
@dh2906 dh2906 merged commit aef886c into develop Apr 28, 2026
5 checks passed
@dh2906 dh2906 deleted the refactor/chat-invite-service-596 branch April 28, 2026 02:10
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.

채팅 리팩토링: 초대 후보 조회 책임 분리

1 participant