Conversation
…stParam -> @RequestHeader 수정
Project코드 Dev 병합
## Walkthrough
이번 변경 사항은 알림(Alarm) 시스템의 엔티티 구조를 리팩토링하고, 알림 처리 로직을 세분화된 엔티티 및 DTO로 분리하는 데 중점을 두었습니다. 기존의 오타가 있던 AlramEntity 및 AlramFilter는 AlarmEntity와 AlarmFilter로 명확하게 교체되었으며, 알림 유형별로 ApplicantAlarmEntity, ProjectAlarmEntity, CommentAlarmEntity 등 하위 엔티티가 도입되었습니다. 서비스 레이어에서는 알림 전송 메서드가 각 알림 유형에 맞게 분리·추가되었고, DTO 계층에도 CommentAlarmDto가 신설되었습니다. 또한, 알림 저장소, 필터 상수, Enum, 서비스 전반에 걸쳐 일관된 네이밍 및 타입 개선이 이루어졌습니다.
## Changes
| 파일/경로 요약 | 변경 내용 요약 |
|---|---|
| .../service/ApplyService.java, .../service/ProjectService.java | AlramFilter → AlarmFilter로 import 및 사용명 변경. alarmService.sendAlarm 호출 시 불필요한 enum 파라미터 제거 및 파라미터 수정. |
| .../service/ProjectCommentService.java | AlarmService 의존성 주입 및 댓글/대댓글 작성 시 알림 전송 로직 추가. |
| .../dto/AlarmDto.java | AlramEntity → AlarmEntity로 타입 변경, CommentAlarmEntity 처리 분기 추가, 필드 접근 및 alarm filter 값 반환 방식 개선. |
| .../dto/CommentAlarmDto.java | 신규 클래스 추가. CommentAlarmEntity 기반의 DTO로 replier, reCommentUserId 필드 및 관련 생성자 구현. |
| .../entity/AlramEntity.java | AlramEntity 클래스 전체 삭제. |
| .../entity/alarm/AlarmEntity.java | AlarmEntity 추상 클래스 신설. JPA 상속 구조, 공통 필드, 추상 메서드(getAlarmFilterIntValue) 정의. |
| .../entity/alarm/ApplicantAlarmEntity.java, .../entity/alarm/ProjectAlarmEntity.java, .../entity/alarm/CommentAlarmEntity.java | 각각 지원자, 프로젝트, 댓글 알림을 위한 엔티티 신설. AlarmEntity 상속, 각 알림 유형에 맞는 필드와 생성자, 필터값 반환 메서드 구현. |
| .../entity/alarm/constants/AlarmFilterConstants.java | 알림 필터 관련 문자열 및 정수 상수 정의 클래스 신설. |
| .../repository/AlarmRepository.java | AlramEntity → AlarmEntity로 교체, 메서드명 및 쿼리에서 userId → receiverId로 변경, 삭제 쿼리에서 타입 기반 필터링 적용. |
| .../service/AlarmService.java | 알림 전송 메서드가 알림 유형별로 분리·추가. 엔티티별 알림 생성 및 SSE 전송 로직 개선. |
| .../service/UserAlarmService.java | AlarmEntity, AlarmFilter 기반으로 네이밍, 필터 비교, 쿼리 등 일관성 있게 수정. |
| .../enums/AlarmFilter.java | Enum명 및 관련 메서드, 생성자, 맵 등 AlramFilter → AlarmFilter로 일괄 수정. |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant User
participant ProjectService
participant AlarmService
participant AlarmRepository
User->>ProjectService: 프로젝트 지원/댓글/대댓글 작성
ProjectService->>AlarmService: sendAlarm(알림 유형별 파라미터)
AlarmService->>AlarmRepository: save(AlarmEntity 하위 클래스)
AlarmService-->>User: SSE로 알림 전송sequenceDiagram
participant User
participant ProjectCommentService
participant AlarmService
participant AlarmRepository
User->>ProjectCommentService: 댓글/대댓글 작성
ProjectCommentService->>AlarmService: sendAlarm(comment, project, user 또는 recomment, comment, project)
AlarmService->>AlarmRepository: save(CommentAlarmEntity)
AlarmService-->>User: SSE로 알림 전송
Poem
|
There was a problem hiding this comment.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
src/main/java/hs/kr/backend/devpals/global/common/enums/AlarmFilter.java (1)
30-37:⚠️ Potential issue
@JsonValue애너테이션이 두 곳에 중복 지정되어 있습니다.
@JsonValue는 직렬화 시 하나의 속성만을 대표 값으로 선택하도록 설계되었습니다.
동일 클래스(혹은 enum) 내에서 두 곳(30, 34라인)에 붙어 있으면 Jackson 매퍼가 어떤 값을 직렬화해야 하는지 결정하지 못해InvalidDefinitionException이 발생할 수 있습니다.- @JsonValue - public String getDisplayName() { - return displayName; - } - @JsonValue - public Integer getValue() { - return value; - } + @JsonValue + public Integer getValue() { + return value; + } + + public String getDisplayName() { + return displayName; + }
🧹 Nitpick comments (7)
src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java (1)
70-70: 용어 일관성 확인 필요코드 전체에서는 '알림'으로 용어를 사용하지만, 여기서는 '알람'으로 표현하고 있습니다. 용어를 일관되게 사용하는 것이 좋습니다.
- ApiResponse<String> response = new ApiResponse<>(true, "알람 삭제 성공", null); + ApiResponse<String> response = new ApiResponse<>(true, "알림 삭제 성공", null);src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java (1)
16-17: 주석 포맷 개선 필요한글 주석과 빈 줄이 분리되어 있어 코드 가독성이 떨어집니다. 주석을 한 줄로 통합하거나 Javadoc 스타일로 변경하는 것이 좋습니다.
-//공고에 지원자가 지원할 시 공고생성자가 수신받는 알림 - +// 공고에 지원자가 지원할 시 공고생성자가 수신받는 알림src/main/java/hs/kr/backend/devpals/global/common/enums/AlarmFilter.java (1)
21-24:VALUE_MAP초기화 시 중복 키 예외 처리 고려현재 구현은
Collectors.toMap기본 동작을 사용하므로, 추후 enum 값이 잘못 수정되어 동일한value가 두 개 생기면 런타임 시IllegalStateException이 발생합니다.
중복 키를 덮어쓰도록 하거나, 테스트 케이스로 사전에 잡아두는 방법을 고려해 주세요.- Arrays.stream(AlarmFilter.values()) - .collect(Collectors.toMap(AlarmFilter::getValue, f -> f)); + Arrays.stream(AlarmFilter.values()) + .collect(Collectors.toMap( + AlarmFilter::getValue, + f -> f, + (a, b) -> a // 중복 시 기존 값 유지 + ));src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java (4)
3-8: 사용되지 않는 import 정리
ApplicantEntity,CommentEntity,ProjectEntity,AlarmFilter는 본 클래스에서 사용되지 않습니다.
IDE 레벨에서 워닝이 뜨고, 빌드 규칙에 따라 실패할 수 있으므로 삭제해 주세요.
21-22: 테이블명 대소문자 및 예약어 충돌 위험
@Table(name = "Alarm")처럼 대문자를 포함하거나 DB 예약어와 충돌할 가능성이 있는 이름은 일부 RDBMS(MySQL, PostgreSQL)에서 이스케이프가 필요합니다.
스네이크 케이스(alarm) 혹은 접두어를 붙여 충돌을 피하는 것이 안전합니다.
36-37: DB 독립적인 Boolean 기본값 지정 방식 권장
columnDefinition = "BOOLEAN DEFAULT FALSE"는 DB마다 DDL 방언이 달라 호환성 문제가 발생할 수 있습니다.
Hibernate/JPA 어노테이션@Column(nullable = false)+ 필드 기본값(false)만으로도 의도는 충분히 표현됩니다.- @Column(nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE") + @Column(nullable = false)
47-48: 생성 시각 필드에@CreationTimestamp사용 고려
createdAt = LocalDateTime.now()는 애플리케이션 서버 시간이 DB 시간과 불일치할 때 데이터 정합성이 깨질 수 있습니다.
Hibernate 의@CreationTimestamp를 사용하면 DB 레벨에서 일관된 시간이 기록됩니다.- @Column(updatable = false) - private LocalDateTime createdAt = LocalDateTime.now(); + @CreationTimestamp + @Column(updatable = false) + private LocalDateTime createdAt;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
src/main/java/hs/kr/backend/devpals/domain/project/service/ApplyService.java(2 hunks)src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectCommentService.java(4 hunks)src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectService.java(3 hunks)src/main/java/hs/kr/backend/devpals/domain/user/dto/AlarmDto.java(2 hunks)src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java(1 hunks)src/main/java/hs/kr/backend/devpals/domain/user/entity/AlramEntity.java(0 hunks)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java(1 hunks)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java(1 hunks)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java(1 hunks)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java(1 hunks)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java(1 hunks)src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java(2 hunks)src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java(2 hunks)src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java(4 hunks)src/main/java/hs/kr/backend/devpals/global/common/enums/AlarmFilter.java(3 hunks)
💤 Files with no reviewable changes (1)
- src/main/java/hs/kr/backend/devpals/domain/user/entity/AlramEntity.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java (4)
src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java (1)
AlarmFilterConstants(3-11)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/AlarmEntity.java (1)
Entity(14-56)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java (1)
Entity(11-36)src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java (1)
Entity(13-55)
🔇 Additional comments (26)
src/main/java/hs/kr/backend/devpals/domain/project/service/ApplyService.java (2)
14-14: 알림 필터 임포트 수정 완료알람(Alram) → 알림(Alarm)으로 이름 수정이 올바르게 적용되었습니다.
55-55: 알림 서비스 호출 방식 개선알림 서비스 호출 시 필터 파라미터를 제거하고 엔티티 중심으로 변경하여 코드가 더 간결해졌습니다. 이제
AlarmFilter.APPLICANT_CHECK파라미터 없이project와applicant객체만으로 알림을 전송할 수 있습니다.src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectCommentService.java (4)
13-13: 알림 서비스 임포트 추가댓글 관련 알림 기능 구현을 위한 알림 서비스 임포트가 적절히 추가되었습니다.
32-32: 알림 서비스 의존성 주입댓글 서비스에 알림 서비스 의존성을 추가하여 댓글 작성 시 알림 기능을 구현할 수 있게 되었습니다.
48-48: 댓글 작성 시 알림 발송 로직 추가댓글이 저장된 후 알림 서비스를 호출하여 프로젝트 소유자에게 알림을 전송하는 기능이 구현되었습니다.
130-130: 대댓글 작성 시 알림 발송 로직 추가대댓글 저장 후 댓글 작성자에게 알림을 전송하는 기능이 적절히 구현되었습니다.
src/main/java/hs/kr/backend/devpals/domain/project/service/ProjectService.java (3)
17-17: 알림 필터 임포트 수정 완료알람(Alram) → 알림(Alarm)으로 이름 수정이 올바르게 적용되었습니다.
193-193: 프로젝트 종료 시 알림 전송 로직 개선프로젝트 종료 시 알림 전송 메서드 호출 방식이 개선되었습니다. 필터 파라미터를 제거하고 엔티티 중심으로 변경하여 코드가 더 간결해졌습니다.
220-220: 일괄 프로젝트 종료 시 알림 전송 로직 개선여러 프로젝트를 일괄 종료하는 로직에서도 알림 전송 메서드 호출 방식이 적절히 개선되었습니다.
src/main/java/hs/kr/backend/devpals/domain/user/service/UserAlarmService.java (2)
33-39: 변수명 수정이 잘 이루어졌습니다.
cachedAlrams에서cachedAlarms로 변수명이 수정되어 일관성이 개선되었습니다. 또한findByUserId에서findByReceiverId로 메서드 호출이 변경되어 새로운 엔티티 구조와 잘 일치합니다.
42-49: 필터 검증 로직이 개선되었습니다.
AlarmFilterenum을 사용한 필터 검증 및 필터링 로직이 명확하게 개선되었습니다.src/main/java/hs/kr/backend/devpals/domain/user/dto/CommentAlarmDto.java (1)
16-20: 생성자 구현이 잘 되었습니다.부모 클래스의 생성자를 호출하고 필요한 필드를 적절히 설정하고 있습니다. 특히 안전한 getter 호출을 위해 도우미 메서드를 활용한 점이 좋습니다.
src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java (3)
8-9: 필터 상수 임포트가 적절합니다.정적 임포트를 통해 코드 가독성이 향상되었습니다.
11-15: 엔티티 정의가 명확합니다.엔티티 클래스, 식별자 값, 테이블 이름 등이 명확하게 정의되어 있어 JPA 매핑이 올바르게 동작할 것입니다.
26-31: 생성자 구현이 잘 되었습니다.적절한 인자를 받아 부모 클래스의 생성자를 호출하고, 필요한 필드를 설정하고 있습니다.
src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java (1)
26-31: 생성자 구현이 명확합니다.적절한 인자를 받아 부모 클래스의 생성자를 호출하고, 필요한 필드를 설정하고 있습니다.
src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java (1)
1-55: 적절한 엔티티 설계와 구현이 이루어졌습니다.알람 엔티티의 상속 구조와 연관 관계가 명확하게 정의되어 있고, 필요한 생성자와 메서드가 잘 구현되었습니다. 댓글(CommentEntity)과 대댓글(RecommentEntity)에 대한 알람을 구분하여 처리할 수 있는 구조가 잘 설계되었습니다.
src/main/java/hs/kr/backend/devpals/domain/user/repository/AlarmRepository.java (3)
3-3: 알람 엔티티 임포트 수정이 올바르게 되었습니다.기존
AlramEntity에서AlarmEntity로 올바르게 수정되었습니다.
15-17: 리포지토리 타입과 메소드 수정이 적절합니다.
JpaRepository<AlarmEntity, Long>로 타입 변경과findByReceiverId메소드명이 일관되게 수정되었습니다.
22-24: 엔티티 타입 기반 필터링이 잘 구현되었습니다.
TYPE()를 사용하여ApplicantAlarmEntity타입을 제외하는 쿼리가 적절하게 구현되었습니다.src/main/java/hs/kr/backend/devpals/domain/user/service/AlarmService.java (6)
4-6: 알람 관련 임포트 수정이 잘 이루어졌습니다.알람 엔티티 클래스들에 대한 임포트가 올바르게 추가되었습니다.
Also applies to: 8-12
78-89: 지원자 결과 알람 전송 메소드가 잘 수정되었습니다.
ApplicantAlarmEntity를 사용하여 지원자 결과 알람을 전송하는 로직이 깔끔하게 구현되었습니다.
91-96: 프로젝트 작성자 알람 전송 메소드가 잘 구현되었습니다.
ProjectAlarmEntity를 사용하여 프로젝트 작성자에게 지원자 알람을 전송하는 로직이 적절하게 구현되었습니다.
98-105: 대댓글 알람 전송 메소드가 잘 구현되었습니다.대댓글 작성 시 원 댓글 작성자에게 알람을 전송하는 로직이 적절하게 구현되었습니다.
117-133: 메시지 생성 메소드들이 잘 구현되었습니다.각각의 알람 유형에 맞는 메시지 생성 메소드가 적절하게 구현되었습니다.
136-147: 알람 전송 메소드가 잘 수정되었습니다.새로운
AlarmEntity클래스와 함께 작동하도록sendToUser메소드가 적절하게 수정되었습니다.
| AlarmEntity alarmEntity | ||
| = alarmRepository.findByUserIdAndAlarmId(userId, alarmId).orElseThrow(() -> new CustomException(ErrorException.ALARM_NOT_FOUND)); | ||
| if(alramEntity.getAlramFilter().equals(AlramFilter.APPLIED_PROJECTS)) | ||
| if(alarmEntity.getAlarmFilterIntValue().equals(AlarmFilter.APPLIED_PROJECTS.getValue())) | ||
| throw new CustomException(ErrorException.CAN_NOT_DELETE_ALARM); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
필터 값 비교 로직 확인 필요
AlarmFilterConstants에 정의된 모든 필터 값(APPLIED_PROJECT_INT_VALUE, APPLICANT_CHECK_INT_VALUE, COMMENT_AND_REPLY_INT_VALUE)이 모두 1로 설정되어 있어 실제 필터 구분에 혼란이 생길 수 있습니다.
🏁 Script executed:
#!/bin/bash
# AlarmFilterConstants에 정의된 필터 값을 확인합니다.
grep -n "INT_VALUE" src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.javaLength of output: 301
AlarmFilterConstants 값 중복으로 인한 필터 구분 불가
AlarmFilterConstants.java(7~9) 확인 결과:
- APPLIED_PROJECT_INT_VALUE = 1
- APPLICANT_CHECK_INT_VALUE = 1
- COMMENT_AND_REPLY_INT_VALUE = 1
이로 인해 AlarmFilter.APPLIED_PROJECTS.getValue() 등 필터별 분기 로직이 정확히 작동하지 않습니다.
각 필터에 고유한 정수 값을 할당하거나, enum 타입 사용을 통해 필터 구분이 명확해지도록 수정이 필요합니다.
| public Integer getAlarmFilterIntValue() { | ||
| return APPLIED_PROJECT_INT_VALUE; | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
필터 값 중복 확인 필요
getAlarmFilterIntValue() 메서드가 반환하는 APPLIED_PROJECT_INT_VALUE 값이 다른 필터 값(APPLICANT_CHECK_INT_VALUE, COMMENT_AND_REPLY_INT_VALUE)과 모두 1로 동일합니다. 이로 인해 프론트엔드에서 필터링 시 구분이 어려울 수 있습니다.
🏁 Script executed:
#!/bin/bash
# 필터 상수 파일의 내용을 확인합니다.
cat src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.javaLength of output: 597
다른 AlarmEntity 클래스들의 getAlarmFilterIntValue() 반환 상수를 확인합니다.
🏁 Script executed:
#!/bin/bash
# 각 AlarmEntity 클래스의 getAlarmFilterIntValue 반환 값을 조사합니다.
rg -n "getAlarmFilterIntValue" -A2 src/main/java/hs/kr/backend/devpals/domain/user/entity/alarmLength of output: 1404
AlarmFilterConstants의 필터 값에 고유한 정수 할당 필요
현재 모든 필터 상수(APPLIED_PROJECT_INT_VALUE, APPLICANT_CHECK_INT_VALUE, COMMENT_AND_REPLY_INT_VALUE)가 1로 중복되어 있어, 프론트엔드에서 필터링 시 구분이 불가능합니다.
조치 사항:
- src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java
- 각 상수에 서로 다른 정수 값 할당 (예:
APPLIED_PROJECT_INT_VALUE = 1,APPLICANT_CHECK_INT_VALUE = 2,COMMENT_AND_REPLY_INT_VALUE = 3)
- 각 상수에 서로 다른 정수 값 할당 (예:
엔티티 클래스의 getAlarmFilterIntValue()는 상수를 그대로 반환하므로, 상수 값만 수정하면 됩니다.
| public Integer getAlarmFilterIntValue() { | ||
| return APPLICANT_CHECK_INT_VALUE; | ||
| } |
There was a problem hiding this comment.
필터 값 중복 확인 필요
getAlarmFilterIntValue() 메서드가 반환하는 APPLICANT_CHECK_INT_VALUE 값이 다른 필터 값(APPLIED_PROJECT_INT_VALUE, COMMENT_AND_REPLY_INT_VALUE)과 모두 1로 동일합니다. 이는 알림 유형 구분에 혼란을 줄 수 있습니다.
#!/bin/bash
# AlarmEntity의 자식 클래스들이 반환하는 필터 값을 확인합니다.
echo "ApplicantAlarmEntity returns:"
grep -n "return.*INT_VALUE" src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ApplicantAlarmEntity.java
echo -e "\nProjectAlarmEntity returns:"
grep -n "return.*INT_VALUE" src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/ProjectAlarmEntity.java
echo -e "\nCommentAlarmEntity returns:"
grep -n "return.*INT_VALUE" src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/CommentAlarmEntity.java
echo -e "\nAlarmFilterConstants defines:"
grep -n "INT_VALUE" src/main/java/hs/kr/backend/devpals/domain/user/entity/alarm/constants/AlarmFilterConstants.java| //댓글 작성시 프로젝트 작성자에게 알림 전송 | ||
| public void sendAlarm(CommentEntity comment, ProjectEntity project, UserEntity commenter) { | ||
| String content = makeMessage(project, commenter); | ||
| UserEntity receiver = userRepository.findById(project.getUserId()).orElseThrow(() -> new CustomException(ErrorException.USER_NOT_FOUND)); | ||
| CommentAlarmEntity commentAlarmEntity = new CommentAlarmEntity(comment, content, project, receiver); | ||
| AlarmEntity saved = alarmRepository.save(commentAlarmEntity); | ||
| sendToUser(project.getUserId(),saved); | ||
| } |
There was a problem hiding this comment.
댓글 알람 전송 메소드에 불일치 이슈가 있습니다.
111번 줄에서는 userRepository.findById(project.getUserId())로 사용자를 조회하고 있으나, 114번 줄에서는 project.getUserId()를 직접 사용하고 있습니다. 일관성을 위해 receiver.getId()를 사용하는 것이 좋습니다.
- sendToUser(project.getUserId(),saved);
+ sendToUser(receiver.getId(),saved);
Summary by CodeRabbit
신규 기능
버그 수정
리팩터링
기타