Skip to content

Comments

[REFACTOR] 채팅·첨부파일 도메인 개선 및 S3 private-only 전환 (#127)#159

Merged
1000hyehyang merged 15 commits intodevfrom
refactor/127-chat
Feb 1, 2026
Merged

[REFACTOR] 채팅·첨부파일 도메인 개선 및 S3 private-only 전환 (#127)#159
1000hyehyang merged 15 commits intodevfrom
refactor/127-chat

Conversation

@1000hyehyang
Copy link
Member

Summary

채팅과 첨부파일 도메인을 전반적으로 개선하고, S3를 private-only 구조로 전환했습니다. Redis 기반 채팅방 캐시, 메시지 읽음 이벤트 처리, Attachment 용도별 S3 경로 분리, 고아 파일 정리 스케줄러 등을 추가·개선했습니다.

Changes

첨부파일(Attachment) 도메인

  • AttachmentUsage enum 추가 (CHAT, PUBLIC): S3 경로 prefix 분리 및 향후 TTL·캐싱 정책 분리용
  • AttachmentStatus에 DELETE_PENDING 추가: 배치 정리용 내부 상태
  • AttachmentUploadRequest에 usage 필드 필수화: 업로드 시 용도 지정 필수
  • accessUrl 제거 → presigned URL 전용: private-only 전환, AttachmentResponseMapper에서 accessUrl null 처리
  • AttachmentQueryService.findByIdOrThrow 추가: 조회 시 예외 발생용 메서드
  • S3 key 생성 시 AttachmentUsage 기반 prefix 적용: chat/, public/ 경로 분리
  • S3FileUploadService에 deleteFile, isAvailable() 추가
  • publicBucket 설정 제거: 단일 private 버킷 사용
  • ProdS3BootGuard 추가: prod 환경에서 S3 설정 필수 검증
  • S3FileNameSanitizer 추가: 파일명 sanitize 유틸
  • AttachmentUploadPolicy, S3AttachmentUploadPolicy 추가: 업로드 정책 인터페이스 분리
  • AttachmentCleanupService + AttachmentCleanupScheduler: 고아 파일 정리 배치
  • NoOpS3FileUploadService: isAvailable() false 반환

채팅(Chat) 도메인

  • ChatMessagesViewedEvent + ChatMessagesViewedEventListener: 메시지 조회 시 읽음 처리 (lastReadMessage 업데이트)
  • ChatRoomUpdateService 분리: ChatRoomCommandService에서 updateLastMessage, updateProposalStatusByUsers 분리
  • Redis 캐시 도입: ChatCachePolicy, ChatRoomListCache, ChatRoomDetailCache, ChatCacheEvictor, ChatCacheKeys, ChatCacheStore, ChatCacheInvalidationService
    • 목록 TTL 30초, 상세 TTL 60초
    • 메시지 생성·읽음 처리·제안 상태 변경 시 캐시 무효화
  • ChatRoomMemberQueryService: findActiveMembers → findActiveMemberUserIds (반환 타입을 List<Long>로 변경)
  • 계층 구조 정리: ChatErrorCode, ChatRoomFilterStatus를 presentation → domain/code로 이동
  • ChatSystemMessageKind에 payloadRequired 필드 추가
  • SpringAfterCommitExecutor: 비트랜잭션 시 IllegalStateException throw (즉시 실행 제거)
  • ChatUserIdResolver: IllegalArgumentException → CustomException(GeneralErrorCode.UNAUTHORIZED)
  • EnableScheduling 추가: AttachmentCleanupScheduler 등 스케줄러 동작용

기타

  • TestController에 /test/token 엔드포인트 추가: 테스트용 JWT 토큰 생성 (userId, role, email 파라미터)
  • .githooks/commit-msg 삭제
  • ChatRoomRepositoryCustomImpl: roomIds null/empty 체크 추가

Type of Change

  • Bug fix (기존 기능에 영향을 주지 않는 버그 수정)
  • New feature (기존 기능에 영향을 주지 않는 새로운 기능 추가)
  • Breaking change (기존 기능에 영향을 주는 수정)
  • Refactoring (기능 변경 없는 코드 개선)
  • Documentation (문서 수정)
  • Chore (빌드, 설정 등 기타 변경)
  • Release (develop → main 배포)

Related Issues

Closes #127

참고 사항

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @1000hyehyang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 Pull Request는 첨부파일 및 채팅 도메인의 핵심 기능을 대대적으로 리팩토링하고 개선합니다. 첨부파일의 경우, S3 스토리지를 완전히 private-only 모델로 전환하여 보안을 강화하고, Presigned URL을 통한 접근을 표준화했습니다. 또한, 고아 파일 정리를 위한 스케줄러와 업로드 정책 관리 기능을 추가하여 파일 관리의 견고성을 높였습니다. 채팅 도메인에서는 Redis 기반의 캐싱 시스템을 도입하여 채팅방 목록 및 상세 조회 성능을 최적화했으며, 메시지 읽음 처리 로직을 이벤트 기반으로 전환하고 서비스 계층을 명확하게 분리하여 코드의 유지보수성과 확장성을 향상시켰습니다.

Highlights

  • S3 Private-Only 전환: S3 스토리지 모델을 private-only로 전환하여, 모든 파일 접근은 이제 Presigned URL을 통해서만 가능합니다. AttachmentResponseMapper에서 accessUrl 필드를 제거하고, S3Properties에서 publicBucket 설정을 삭제했습니다. 프로덕션 환경에서는 ProdS3BootGuard를 통해 S3 설정이 필수적으로 검증되도록 했습니다.
  • 첨부파일(Attachment) 도메인 개선: AttachmentUsage enum을 추가하여 S3 경로 접두사를 분리하고 향후 용도별 정책 적용을 위한 기반을 마련했습니다. AttachmentStatusDELETE_PENDING 상태를 추가하여 고아 파일 정리 스케줄러를 도입했으며, AttachmentUploadRequestusage 필드를 필수로 지정하도록 변경했습니다. 또한, AttachmentUploadPolicy 인터페이스와 S3AttachmentUploadPolicy 구현체를 통해 업로드 정책을 분리하고, S3FileNameSanitizer 유틸리티를 추가했습니다.
  • 채팅(Chat) 도메인 Redis 캐시 도입: 채팅방 목록 및 상세 정보에 Redis 캐시를 도입하여 성능을 개선했습니다. ChatCachePolicy, ChatRoomListCache, ChatRoomDetailCache, ChatCacheEvictor, ChatCacheKeys, ChatCacheStore, ChatCacheInvalidationService 등 관련 캐싱 인프라를 구축했습니다. 메시지 생성 및 읽음 처리, 제안 상태 변경 시 캐시가 무효화되도록 설정했습니다.
  • 채팅 메시지 읽음 이벤트 처리: ChatMessagesViewedEventChatMessagesViewedEventListener를 도입하여 메시지 조회 시 lastReadMessage를 업데이트하는 비동기 이벤트를 처리하도록 변경했습니다.
  • 채팅 도메인 서비스 계층 분리 및 리팩토링: ChatRoomCommandService에서 updateLastMessageupdateProposalStatusByUsers 로직을 ChatRoomUpdateService로 분리했습니다. ChatRoomMemberQueryService.findActiveMembersfindActiveMemberUserIds로 변경되어 List<Long>을 반환하도록 개선했습니다. ChatSystemMessageKindpayloadRequired 필드를 추가하여 시스템 메시지 유효성 검사를 강화했습니다.
  • 트랜잭션 후 작업 및 예외 처리 개선: SpringAfterCommitExecutor가 활성 트랜잭션 외부에서 사용될 경우 IllegalStateException을 발생시키도록 변경하여 트랜잭션 무결성을 강화했습니다. ChatUserIdResolver는 인증 실패 시 IllegalArgumentException 대신 CustomException(GeneralErrorCode.UNAUTHORIZED)을 던지도록 수정했습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

전반적으로 매우 훌륭한 리팩토링입니다. 채팅 및 첨부파일 도메인을 개선하고 S3를 private-only로 전환하면서 많은 부분이 향상되었습니다. 특히 트랜잭션 경계를 명확히 하고, S3 파일 업로드/삭제 로직을 견고하게 개선했으며, Redis를 이용한 캐싱 전략을 도입하고, 고아 파일 정리를 위한 스케줄러를 추가한 점이 인상적입니다. 코드의 안정성과 유지보수성이 크게 향상될 것으로 보입니다. 몇 가지 개선점을 제안드렸지만, 전체적으로 매우 완성도 높은 변경 사항입니다.

@1000hyehyang 1000hyehyang merged commit 434b233 into dev Feb 1, 2026
1 check passed
@1000hyehyang 1000hyehyang deleted the refactor/127-chat branch February 1, 2026 06:32
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.

[REFACTOR] 채팅 기능 Redis 캐시 적용

1 participant