[김지예] sprint11#166
Hidden character warning
Conversation
- BinaryContent 생성 이벤트(BinaryContentCreatedEvent) 클래스 추가 - 이벤트 리스너(BinaryContentCreatedEventListener) 구현 및 저장 처리 로직 추가 - BinaryContent 상태 관리를 위한 BinaryContentStatus 열거형 추가 - 파일 저장 실패 시 예외(BinaryContentUploadFailException) 처리 로직 구현
- Message 생성 시 MessageCreatedEvent 이벤트 발행 로직 구현 - ApplicationEventPublisher 의존성 추가 - MessageCreatedEvent 레코드 클래스 생성
- BinaryContent에 BinaryContentStatus 열거형 필드 추가 - 상태 변경 메서드(uploadSucceed, uploadFailed) 및 확인 메서드(isUploaded) 구현 - 생성자 변경 및 BaseUpdatableEntity 상속으로 변경 - 기본 업로드 상태를 PROCESSING으로 설정
- 파일 저장 로직을 이벤트 기반(BinaryContentCreatedEvent)로 변경 - ApplicationEventPublisher 의존성 추가 - BinaryContent 생성 시 파일 업로드 이벤트 발행 및 상태 관리 개선 - BinaryContentCreatedEventListener에서 파일 저장과 상태 업데이트 처리 - BinaryContentStorage 의존성 제거 및 관련 코드 삭제
- notificationEnabled 필드 추가 및 기본값 설정 로직 구현 - 채널 유형에 따라 알림 활성화 여부 초기화 - 알림 활성화된 사용자를 조회하는 쿼리 메서드 추가 - ReadStatusUpdateRequest에 알림 설정 요청 필드 추가
- Notification 엔티티 생성 및 JPA 매핑 정의 - NotificationService 인터페이스 및 기본 구현체 추가 - NotificationDto 및 NotificationCreateRequest 레코드 클래스 생성 - NotificationRequiredEventListener 클래스 추가하여 메시지 생성 이벤트 처리 - 알림 수신 설정된 사용자 조회 및 알림 전송 로직 초기 구현
- 테이블 및 Foreign Key 정의 가독성 개선을 위한 포맷팅 수정 - notifications 테이블 스키마 추가 - ReadStatus 테이블에 notification_enabled 필드 추가 및 관련 인덱스 생성 - BinaryContents 테이블에 status 필드 추가 - users, channels 등 일부 테이블의 컬럼 정의 포맷 개선 및 인덱스 추가
- NotificationService 의존성을 NotificationRepository로 교체 - 메시지 생성 이벤트 시 알림 저장 로직 수정 및 간소화 - Notification 엔티티 생성 및 저장 처리 로직 스트림 활용으로 변경
- Notification 엔티티를 관리하기 위한 JpaRepository 구현 - UUID를 기본 키로 사용하는 Notification 엔티티 지원
- DTO와 엔티티 간 매핑을 간소화하기 위해 MapStruct 추가 - build.gradle 파일에 MapStruct 라이브러리 및 어노테이션 프로세서 설정
- 사용자별 알림 리스트 조회 메서드(getAllByUserId) 추가 - NotificationMapper 인터페이스 생성 및 MapStruct 매핑 설정 - 알림 확인(confirm) 로직 구현 및 권한 체크 추가 - NotificationRepository에 사용자(receiver) 기준 조회 메서드 추가
- RoleUpdatedEvent 레코드 클래스 생성 - NotificationRequiredEventListener에 권한 변경 이벤트 처리 메서드 추가 - BasicUserService에서 권한 변경 시 RoleUpdatedEvent 발행하도록 수정
- NotificationCreateRequest 삭제로 사용되지 않는 DTO 정리 - NotificationService에서 NotificationCreateRequest 사용 코드 제거 및 메서드 시그니처 수정
- 알림 전체 조회 메서드(getAllNotifications) 추가 - 알림 단건 확인(confirm) 메서드 및 사용자 인증 정보 활용 로직 구현 - NotificationService와 연동하여 알림 데이터 처리
- NotificationException 및 NotificationNotFoundException 구현 - 알림 ID와 에러 코드 기반 예외 처리 로직 지원
- @timed를 사용해 message.create.async 메트릭 타이머 구현 - 메시지 생성 요청에 대한 성능 데이터를 수집 및 모니터링 가능하도록 설정
- Spring Security와 MDC(Context Map) 컨텍스트를 유지하는 TaskDecorator 구현 - 다중 스레드 환경에서 실행 컨텍스트를 안전하게 전파하도록 설정
- NotificationRequiredEventListener와 BinaryContentCreatedEventListener 메서드에 @async 어노테이션 추가 - 비동기 처리로 이벤트 리스너 성능 개선
- ThreadPoolTaskExecutor를 활용한 AsyncConfig 구현 - 이벤트 리스너에서 사용될 eventTaskExecutor 빈 등록 - 성능 최적화를 위해 비동기 처리 스레드풀 구성
- index-COLcXNzv.js 및 관련 정적 파일 제거 - 빌드 결과물에서 사용되지 않는 파일 정리
- management.observations.annotations.enabled 설정값 추가 - 메트릭 관리 활성화를 위한 설정 변경 수행
- 네트워크 요청 재시도 로직 구현을 위해 spring-retry 라이브러리 추가
- BinaryContentCreatedEventListener에 Spring Retry를 활용한 재시도 로직(@retryable) 구현 - 재시도 실패 시 BinaryContentCreateFailedEvent를 발행하도록 @recover 메서드 추가 - BinaryContentCreateFailedEvent 처리 로직(NotificationRequiredEventListener)에 관리자 알림 기능 구현 - RetryConfig를 추가해 Spring Retry 설정 활성화 - 이벤트 리스너 패키지명 오타 수정 (lilstener → listener)
- findAllByRole(Roles roles) 메서드 추가로 역할별 사용자 리스트 조회 기능 지원
jinho-yoo-jack
left a comment
There was a problem hiding this comment.
전반적으로 모두 잘 작성하셨습니다.
다만, 코드 작성 스타일에서 약간의 아쉬움 부분들이 있어서 그러한 부분들을 위주로 리뷰 드렸습니다.
고생하셨습니다.
| @Getter | ||
| @AllArgsConstructor | ||
| public class BinaryContent extends BaseEntity { | ||
| public class BinaryContent extends BaseUpdatableEntity { |
There was a problem hiding this comment.
BaseUpdatableEntity 업데이트 할 수 있는 없는 기준으로 BaseEntity를 분기를 나눠야 했던 이유가 있을까요?!!
| ApplicationEventPublisher publisher; | ||
|
|
||
| @TransactionalEventListener | ||
| @Transactional(propagation = Propagation.REQUIRES_NEW) |
There was a problem hiding this comment.
트랜잭션 격리 부분까지 아주 휼륭하게 잘 작성하셨네요!
좋습니다.
| String title = channel.getType() == ChannelScope.PUBLIC | ||
| ? String.format("%s (#%s)", author.getUsername(), channel.getName()) | ||
| : author.getUsername(); | ||
| String summary = event.content().length() > 30 ? |
There was a problem hiding this comment.
이런 제목 길이 한정하고 요약하는 부분은 StringUtils와 같은 클래스로 따로 빼서 구현 및 관리하면 코드의 가독성과 유지보수성이 더 좋아질 수 있을 것 같네요.
| public void on(RoleUpdatedEvent event) { | ||
| User user = userRepository.findById(event.userId()) | ||
| .orElseThrow(() -> new UserNotFoundException(event.userId())); | ||
| String title = "권한이 변경되었습니다."; |
There was a problem hiding this comment.
"권한이 변경되었습니다."와 같은 변하지 않는 문자열은 public static final로 표현하는 것도 하나의 방법
| messageCreateRequest.channelId(), | ||
| attachmentFiles == null ? 0 : attachmentFiles.size()); | ||
| files == null ? 0 : files.size()); | ||
| Message message = messageRepository.save(new Message( |
There was a problem hiding this comment.
메서드 파라미터로 할당할 인자 값들을 메서드 호출부를 선언함으로써 변수명을 선언하지 않는 이점(?)을 얻고자 이렇게 작성한 것 같은데, 파라미터가 많은 경우에는 가독성이 떨어져 좋지 않을 수 있습니다.
지금 처럼 파라미터가 많은 경우에는 적절하게 변수에 값을 담아서 인자로 전달하는 것이 더 좋습니다.
요구사항
기본
BinaryContentStorage.put직접 호출 대신BinaryContentCreatedEvent를 발행하여 파일 업로드 로직 분리@TransactionalEventListener로 트랜잭션 커밋 후 바이너리 데이터 저장BinaryContent에status필드 추가 (PROCESSING → SUCCESS / FAIL)MessageCreatedEvent,RoleUpdatedEvent정의 및 발행으로 알림 기능 구현ReadStatus에notificationEnabled필드 추가Notification엔티티 + 조회/삭제 API 구현AsyncConfig+@EnableAsync+TaskExecutorBean 등록으로 비동기 전환TaskDecorator로 MDC, SecurityContext 비동기 스레드 전파@Retryable로 재시도 정책 설정 및@Recover로 최종 실패 시 관리자 알림 생성@Cacheable,@CacheEvict,@CachePut)심화
주요 변경사항
@Async로 이벤트 리스너를 비동기 전환하여 응답 속도 개선멘토에게