Conversation
Merged
kanghana1
added a commit
that referenced
this pull request
Jul 12, 2026
* [feat/#589] 안 읽은 메시지 조회 API 구현 (#619) * refactor: 기존 안 읽은 메시지 조회 로직을 별도 서비스로 분리 * feat: 안 읽은 메시지 조회 API 구현 * refactor: 안 읽은 메시지 조회 로직을 애플리케이션 로직 대신 DB 쿼리로 처리 * test: 안 읽은 메시지 조회 통합 테스트 보강 * chore: 안 읽은 메시지 조회 API는 자주 사용되므로 인덱스 도입하여 조회 성능 개선 * fix: 채팅 배지가 안읽은 메시지 개수가 아닌 단순 boolean 값만 필요하므로 전체 API 수정 * refactor: 채팅방 조회 API에서 안읽은 메시지 조회를 배치 쿼리로 개선 * refactor: 메시지 전송 시 안 읽은 메시지 count를 배치 쿼리로 개선 * fix: 안 읽은 메시지 카운트 업데이트에서 쿼리 실패시 fallback 대신 실패로 변경 * [refactor/#600] ExerciseQueryService 유스케이스별 서비스 분리 (#623) * refactor: Query 서비스에서 Repository를 직접 참조하지 않도록 변경 * refactor: 맵 쿼리 서비스 분리 * refactor: 추천 쿼리 서비스 분리 * refactor: 내 정보 관련 쿼리 서비스 분리 * refactor: 모임 운동 캘린더 조회 서비스 분리 * refactor: 게스트 조회 서비스 분리 * refactor: 라이프사이클 조회 서비스 분리 * refactor: Reader는 support/reader 패키지로 분리 * fix: 불필요한 Member 검증은 Jwt 필터에서 진행하므로 제거 * debug: 운동 수정용 상세 조회에서 모임장이나 부모임장 권한 로직이 없었떤 버그 제거 * refactor: 사용자 수 계산 쿼리를 운동이 없으면 호출하지 않도록 empty guard 추가 * refactor: contains를 loop를 돌며 호출하는걸 HashSet을 통해 시간복잡도 개선 * refactor: lookup 서비스의 에러는 그 도메인의 에러를 던지도록 변경 * test: Member를 사용하지 않는 서비스에서는 검증 로직을 JWT 필터에 의존하므로 관련 테스트 실패 로직 제거 * test: 시간 의존적인 테스트가 종종 실패하는 문제를 개선 * [refactor/#626] 채팅 REST/WebSocket presentation 계층 정리 (#627) * refactor: chat 도메인 presentation 계층 정리 * refactor: 웹소켓 메시지 전송 클래스 위치 변경 * refactor: 웹소켓 메시지 전송 클래스 네이밍 명확화 * refactor: Handler는 단순 웹소켓 생명주기 관리로 축소, 메시지 처리는 Dispatcher로 위임 * refactor: request 타입별 메시지 처리를 CommandHandler 책임으로 위임 * refactor: 컨버터에서 웹소켓 전용 로직은 별도 클래스로 분리 * refactor: service 계층에서 presentation 계층에 의존성이 생기므로 일단 converter 패키지 아래로 재이동 * fix: 웹소켓 디스패쳐 로깅 개선 - payload 전체 찍기 X, 에러를 사용자에게 그대로 보내기 X * docs: 로깅에서 메시지 타입이 아닌 멤버를 찍던 오류를 수정 * [chore/#628] 쿼리 카운트 테스트 인프라 구축 (#634) * chore: 쿼리 카운트 테스트 인프라 구축 * chore: 스모크 테스트 * chore: 테스트 정합성을 위해 배치사이즈 설정을 테스트 프로파일에 추가 * chore: 캐시로 인한 쿼리 수가 맞지 않는 문제 해결 * [refactor/#630] Bookmark 도메인 N+1 제거 (#636) * refactor: 관련 엔티티 fetch join * refactor: 찜한 운동 인원수 count 쿼리화 * refactor: 찜 목록 역방향 fetch join * test: Bookmark 찜 목록 N+1 쿼리카운트 테스트 추가 * chore: 불필요한 주석 제거 * refactor: set으로 묶기 * [refactor/#638] 운동 참여 인원 수 조회 로직 공통화 (#639) * feat: 운동 도메인에 운동 참여 멤버수 계산 서비스를 별도 구현 * refactor: 운동 도메인에서 멤버 수 계산 로직을 CountLookupService에 위임하도록 변경 이때 같은 도메인의 서비스가 lookup을 쓰는 건 공통 로직을 묶는 한 어쩔 수 없는 trade-off임 * refactor: Bookmark 도메인에서도 CountLookupService에 운동 참여 멤버 수 로직을 위임하도록 변경 * fix: 사용하지 않게 된 리포지토리 쿼리를 제거하고, N+1 체크 테스트도 반영 * refactor: 운동 북마크 조회를 운동 도메인에 두던 걸 북마크 도메인으로 변경 * [feat/#625] 채팅 unread status WebSocket 이벤트 발행 (#637) * feat: 채팅 전송 시 발신자를 제외하고 안 읽은 메시지 업데이트 이벤트 발송 * refactor: ChatSendService의 조회 메서드를 별도 Reader로 분리 * refactor: 채팅 전송 서비스에서 파일 첨부 로직을 별도 서비스로 분리 * refactor: 채팅 전송 서비스에서 첫 메시지 판별 로직을 별도로 분리 * refactor: 채팅 전송 서비스에서 이벤트 발행 책임을 별도 서비스로 분리 * refactor: send 관련 클래스들을 별도 패키지로 묶어서 정리 * improve: 시스템 메시지에서도 안 읽은 배지 업데이트 이벤트를 발행하도록 변경 * refactor: 이벤트 리스너는 service 하위로 이동 * refactor: 메시지 읽음 상태 처리 서비스도 send/support 하위로 이동 * refactor: 보낸 메시지 자동 읽음 처리 서비스를 네이밍을 명확하게 하고 메서드 명도 변경 * feat: 채팅방 입장 시 읽음 상태가 변동되므로 이벤트를 발행하도록 구현 * refactor: 구독 시 읽음 처리 서비스의 네이밍과 메서드명을 명확화 * refactor: redis 관련 클래스를 repository 아래로 이동 * refactor: 세션 관리 책임을 별도 서비스로 분리 * refactor: 웹소켓 전송 책임을 구독 서비스 밖으로 분리 * refactor: 브로드캐스트 로직을 별도 서비스로 분리 * refactor: 안 읽음 수 업데이트 브로드캐스트 로직을 별도로 분리 * refactor: 채팅방 목록 업데이트 브로드캐스트 로직도 별도로 분리 * refactor: 구독 서비스에서 redis store를 직접 참조하지 않도록 분리 * refactor: Subscription 서비스가 이름과 맞지 않게 너무 많은 책임을 가지고 있어 각 기능을 분리하고 네이밍을 명확화 * refactor: 이벤트 리스너를 별도로 분리 * improve: 탭을 여러 개 열었을 때, 같은 세션만 웹소켓을 닫도록 세션 정보도 전달 * improve: 안읽음 상태 업데이트를 활성 사용자 대상으로만 필터링 하도록 변경 * improve: 채팅 안읽음 메시지 조회 로직을 배치 쿼리로 변경 * refactor: 직렬화 책임을 별도 Encoder로 분리 * refactor: 메시지 전송은 SessionMessageSender에서만 진행하도록 변경 * docs: 현재 Redis 일관성 수준을 best-effort로 명시, 재시도 및 보상 정책은 추후 별도 이슈로 * test: AFTER-COMMIT 이후 실제 payload가 발행되는지 체크하는 서비스 추가 * chore: 불필요한 중복된 Transactional 어노테이션을 제거 * [debug/#611] 프로필 동시성 처리 문제 해결 (#642) * fix: ProfileImg에 memberId unique 제약 추가 * feat: 낙관적 락, 아웃박스 로직을 이용한 정합성 로직 추가 * chore: 주석수정 * test: outbox 테스트 정리 * feat: 온보딩에서 프로필 등록하는 로직에도 변경사항 추가할 수 있도록 도메인 로직으로 분리 * fix: 컨트롤러가 Executor를 이용하도록 수정 * fix: 예외 범위 축소 * chore: 중복 이미지를 gcs에서 삭제할 수 있도록 적재하는 쿼리 추가 * [refactor/#624] 채팅 읽음 처리 쿼리 배치화 (#641) * refactor: 구독 시 unread 배치 update + 배치 read로 변경 * refactor: 구독 후 lastReadMesageId 처리도 배치 쿼리로 변경 * refactor: 메시지 전송 시 자동 읽음 처리에서 활성 사용자의 lastReadMessageId 업데이트도 배치 쿼리로 변경 * refactor: 구독자 자동 읽음 서비스에서 메서드 추출을 통해 로직이 보이도록 변경 * refactor: 다른 클래스에서 참조하는 record를 클래수 내부 record에서 별도로 분리 * refactor: 읽음 상태 처리 repository 의존을 직접하는 대신 support 패키지의 클래스를 이용하도록 변경 * fix: 채팅 배치 읽음 처리에서 IN절이 너무 길어지는 것을 방지하여 500개 기준으로 CHUNK를 분리하도록 개선 * test: 배치 읽음 처리 및 count 로직을 리포지토리 단위 테스트로 검증 * fix: bulk 쿼리에서 제대로 처리되는지를 log로 검증 * fix: 마지막 메시지 Id를 stream.max()로 명확화 * refactor: 조회한 결과가 Id가 중간에 비어있을 수 있음을 메서드로 명시 * docs: 채팅방 멤버 테이블은 메시지 읽음 처리마다 updated_at 칼럼이 바뀔경우 부하가 될 수 있으므로 bulk 처리에서 배제하고 이를 명시 * fix: 채팅 멤버 읽음 상태 업데이트 클래스도 chunk 처리를 하도록 개선 * [refactor/#632] 안 읽은 알림 조회 최적화 (#645) * [refactor/#631] 메달 개수 쿼리 최적화 (#644) * refactor: 메달 개수 쿼리를 1개로 최적화 * chore: 주석 수정 * chore: 컨버터 롤백 * [chore/#582] 부하테스트용 FCM 인위적 지연 주입 (#652) * chore: 부하테스트용 FCM 인위적 지연 주입 * chore: fcm지연 주입 추가 * chore: FCM 지연주입 값을 env(GitHub Variable)로 토글 가능하게 배관 * [feat/#647] 로깅 인프라 구축 (#649) * feat: MDC 필터 추가 및 JWT 필터에서 MEMBER_ID 추가 및 삭제 로직 추가 * feat: 비동기 스레드의 MDC 전파를 위해 설정 및 TaskDecorator 추가 * chore: Logback 기반 콘솔 및 파일 로그 개선 * chore: 콘솔 로그에는 색상을 추가하여 가시성 개선 * chore: 로그 I/O를 비동기로 하도록 변경 * chore: 에러 로그는 별도로 중복 저장하여 운영 편리성 향상 * feat: 웹소켓에도 MDC를 별도로 적용 * chore: 도커 컴포즈 volume 설정으로 log 추가 * chore: local, staging, prod를 제외하고는 색상을 없애 xml 생성 오류 해결 * docs: 카카오 Authorization code를 로그에서 제거하여 보안 이슈 해결 * chore: 에러 로그에서는 ThresholdFilter를 통해 Error 로그만 받도록 변경 * chore: Error 제외 Appender는 block 되지 않도록 하고, 로그 레벨을 debug로 낮춤 * chore: 누락된 HTTP 메소드, uri, clientIp도 로깅하도록 변경 * test: MDC 로그 테스트 검증을 중복해서 하지 않도록 변경 * chore: 불필요한 줄바꿈 제거 * chore: 토큰 없는 요청의 경우 서버 에러가 인증 에러로 잘못 변환될 수 있으므로 별도 try-catch로 분리 * chore: Ai로 인해 줄바꿈이 잘못 변경된 걸 해결 * [refactor/#633] 회원 프로필 조회 최적화 (#646) * [refactor/#582] FCM과 채팅 스레드풀 분리 (#653) * feat: MDC 필터 추가 및 JWT 필터에서 MEMBER_ID 추가 및 삭제 로직 추가 * feat: 비동기 스레드의 MDC 전파를 위해 설정 및 TaskDecorator 추가 * refactor: 채팅과 fcm 스레드풀 분리 * fix: 포화로 거부된 작업은 로그만 찍도록 수정 --------- Co-authored-by: Dimo-2562 <chosehoon2@naver.com> * [refactor/#650] JWT 토큰 무효화 체계 및 RT 재사용 탐지 도입 (#651) * feat: tokenVersion 인프라 구축 * refactor: 인증 필터 tokenVersion 검증 전환 및 DB 조회 제거 * feat: 재사용 탐지 로직 추가 * fix: JWT claim에 type 추가 * fix: redis를 캐시로 사용하도록 수정 * fix: AT 무효화 검증 제거 * refactor: lua 스크립트를 이용해 동시성 이슈 방지 * test: 테스트 보강 * [feat/#654] Staging 계층 모니터링(OTLP) 도입 (#655) * feat: grafana 세팅 * chore: 부하테스트 결과 파일 추적 제외 * [refactor/#656] 도메인 값 SSOT 외부화 (#657) * refactor: 도메인값 SSOT 외부화 * refactor: terraform 도메인 변수화 * refactor: env 배선 * refactor: WS 포함 --------- Co-authored-by: Dmori <83327857+Dimo-2562@users.noreply.github.com> Co-authored-by: Dimo-2562 <chosehoon2@naver.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
❤️ 기능 설명
운영 모니터링(Observability) 을 도입합니다.
프로덕션에서 스레드풀·DB 커넥션(HikariCP)·JVM/GC·API 응답시간(P95/P99)을 상시 관측하기 위한
계측을 추가합니다. 표준 OpenTelemetry(OTLP)로 메트릭을 Grafana Cloud에 push합니다.
우선 staging에 도입 후, 안정성과 대시보드 검증이 되면 후속 PR에서 prod 확장 예정입니다.
변경사항
앱 계측
spring-boot-starter-actuator,micrometer-registry-otlpapplication.ymlmanagement설정:resource-attributes:service.name+deployment.environment(프로파일 기반) → 환경별 라벨링(prod/staging 구분 준비 완료)http.server.requests히스토그램(P95/P99)health)연결된 issue
연결된 issue를 자동으로 닫기 위해 아래 {이슈넘버}를 입력해주세요.
close #654
🩷 Approve 하기 전 확인해주세요!
✅ 체크리스트