feat: 개인 알림 생성 메서드 확장 - #120
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough알림 대상과 유형을 확장했습니다. Changes알림 정책 및 생성 흐름
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/slatto/domain/notification/service/NotificationService.java`:
- Around line 187-200: 작성자 제외 로직에 사용되는 ID가 null이 되지 않도록 검증을 추가하세요.
NotificationService.java의 187-200행에서는 writerId를 validateRequiredId로 검증하고,
253-267행·407-421행·437-450행에서는 각각 actorUserId를 validateRequiredId로 검증하세요.
- Around line 637-639: createScheduleAssignedContent 메서드의 알림 문구를 수동형으로 수정하세요.
assigneeName이 지정된 사용자로 표시되도록 현재 “담당자로 지정했어요” 표현을 “담당자로 지정되었어요”로 변경하고, 나머지 조합 형식은
유지하세요.
- Around line 197-211: Update the recipient stream in the notification creation
flow to remove duplicate recipients by recipient ID before invoking
Notification.create. Preserve the existing null filtering, writer exclusion,
notification construction, and saveAll behavior for unique recipients.
🪄 Autofix
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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c1b8d6ce-3910-46bc-a4c1-1521051874ae
📒 Files selected for processing (3)
src/main/java/com/slatto/domain/notification/enums/NotificationTargetType.javasrc/main/java/com/slatto/domain/notification/enums/NotificationType.javasrc/main/java/com/slatto/domain/notification/service/NotificationService.java
| validateRequiredId(scheduleId); | ||
| validateRequiredText(scheduleTitle); | ||
| if (recipients == null) { | ||
| throw new BaseException(CommonErrorCode.BAD_REQUEST); | ||
| } | ||
|
|
||
| Project notificationProject = getProjectOrNull(project != null ? project.getId() : null); | ||
| String title = createScheduleAssignedTitle(project != null ? project.getTitle() : null); | ||
| String targetType = getTargetTypeName(NotificationTargetType.SCHEDULE); | ||
|
|
||
| List<Notification> notifications = recipients.stream() | ||
| .filter(Objects::nonNull) | ||
| .filter(recipient -> !Objects.equals(recipient.getId(), writerId)) | ||
| .map(recipient -> Notification.create( |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
작성자 제외를 보장하도록 작성자 ID를 검증하세요.
writerId 또는 actorUserId가 null이면 제외 로직이 적용되지 않습니다. 이 경우 작성자가 자신의 알림을 수신합니다.
src/main/java/com/slatto/domain/notification/service/NotificationService.java#L187-L200:writerId를validateRequiredId로 검증하세요.src/main/java/com/slatto/domain/notification/service/NotificationService.java#L253-L267:actorUserId를validateRequiredId로 검증하세요.src/main/java/com/slatto/domain/notification/service/NotificationService.java#L407-L421:actorUserId를validateRequiredId로 검증하세요.src/main/java/com/slatto/domain/notification/service/NotificationService.java#L437-L450:actorUserId를validateRequiredId로 검증하세요.
📍 Affects 1 file
src/main/java/com/slatto/domain/notification/service/NotificationService.java#L187-L200(this comment)src/main/java/com/slatto/domain/notification/service/NotificationService.java#L253-L267src/main/java/com/slatto/domain/notification/service/NotificationService.java#L407-L421src/main/java/com/slatto/domain/notification/service/NotificationService.java#L437-L450
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/slatto/domain/notification/service/NotificationService.java`
around lines 187 - 200, 작성자 제외 로직에 사용되는 ID가 null이 되지 않도록 검증을 추가하세요.
NotificationService.java의 187-200행에서는 writerId를 validateRequiredId로 검증하고,
253-267행·407-421행·437-450행에서는 각각 actorUserId를 validateRequiredId로 검증하세요.
| List<Notification> notifications = recipients.stream() | ||
| .filter(Objects::nonNull) | ||
| .filter(recipient -> !Objects.equals(recipient.getId(), writerId)) | ||
| .map(recipient -> Notification.create( | ||
| recipient, | ||
| notificationProject, | ||
| NotificationType.SCHEDULE_ASSIGNED, | ||
| title, | ||
| createScheduleAssignedContent(scheduleTitle, recipient.getNickname()), | ||
| targetType, | ||
| scheduleId | ||
| )) | ||
| .toList(); | ||
|
|
||
| notificationRepository.saveAll(notifications); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
중복 수신자를 제거하세요.
recipients에 동일 사용자가 두 번 있으면 알림도 두 건 저장됩니다. 이 경로는 getRecipientIds의 중복 제거를 사용하지 않습니다. Notification.create 전에 수신자 ID를 기준으로 중복을 제거하세요.
수정 예시
+ Set<Long> uniqueRecipientIds = new HashSet<>();
List<Notification> notifications = recipients.stream()
.filter(Objects::nonNull)
+ .filter(recipient -> recipient.getId() != null)
+ .filter(recipient -> uniqueRecipientIds.add(recipient.getId()))
.filter(recipient -> !Objects.equals(recipient.getId(), writerId))
.map(recipient -> Notification.create(📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| List<Notification> notifications = recipients.stream() | |
| .filter(Objects::nonNull) | |
| .filter(recipient -> !Objects.equals(recipient.getId(), writerId)) | |
| .map(recipient -> Notification.create( | |
| recipient, | |
| notificationProject, | |
| NotificationType.SCHEDULE_ASSIGNED, | |
| title, | |
| createScheduleAssignedContent(scheduleTitle, recipient.getNickname()), | |
| targetType, | |
| scheduleId | |
| )) | |
| .toList(); | |
| notificationRepository.saveAll(notifications); | |
| Set<Long> uniqueRecipientIds = new HashSet<>(); | |
| List<Notification> notifications = recipients.stream() | |
| .filter(Objects::nonNull) | |
| .filter(recipient -> recipient.getId() != null) | |
| .filter(recipient -> uniqueRecipientIds.add(recipient.getId())) | |
| .filter(recipient -> !Objects.equals(recipient.getId(), writerId)) | |
| .map(recipient -> Notification.create( | |
| recipient, | |
| notificationProject, | |
| NotificationType.SCHEDULE_ASSIGNED, | |
| title, | |
| createScheduleAssignedContent(scheduleTitle, recipient.getNickname()), | |
| targetType, | |
| scheduleId | |
| )) | |
| .toList(); | |
| notificationRepository.saveAll(notifications); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/slatto/domain/notification/service/NotificationService.java`
around lines 197 - 211, Update the recipient stream in the notification creation
flow to remove duplicate recipients by recipient ID before invoking
Notification.create. Preserve the existing null filtering, writer exclusion,
notification construction, and saveAll behavior for unique recipients.
| private String createScheduleAssignedContent(String scheduleTitle, String assigneeName) { | ||
| return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정했어요"; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
담당자 지정 문구를 수동형으로 수정하세요.
assigneeName은 지정한 사용자가 아니라 지정된 사용자입니다. 현재 문구는 담당자가 지정 행위를 수행한 것으로 표시합니다. "지정되었어요"를 사용하세요.
수정 예시
- return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정했어요";
+ return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정되었어요";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private String createScheduleAssignedContent(String scheduleTitle, String assigneeName) { | |
| return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정했어요"; | |
| } | |
| private String createScheduleAssignedContent(String scheduleTitle, String assigneeName) { | |
| return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정되었어요"; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/slatto/domain/notification/service/NotificationService.java`
around lines 637 - 639, createScheduleAssignedContent 메서드의 알림 문구를 수동형으로 수정하세요.
assigneeName이 지정된 사용자로 표시되도록 현재 “담당자로 지정했어요” 표현을 “담당자로 지정되었어요”로 변경하고, 나머지 조합 형식은
유지하세요.
chazy-d
left a comment
There was a problem hiding this comment.
수고하셨습니다! 프론트엔드 화면 라우팅을 위해서 저도 조회시 targetType, targetId를 동일하게 응답하는 구조로 만들었습니다.
🔗 관련 이슈 (Related Issue)
Closes #111
📝 작업 내용
개인 알림 정책에 맞춰 각 도메인에서 호출할 수 있는 알림 생성 메서드를 확장했습니다.
각 도메인에서는
Notification엔티티나 Repository를 직접 사용하지 않고,NotificationService의 메서드만 호출하면 알림 문구 생성과notification테이블 저장까지 처리되도록 구성했습니다.주요 변경 사항
구현/정리 내용
프로젝트에 사용자가 합류했을 때 프로젝트 참여자에게 알림을 생성할 수 있도록 메서드를 추가했습니다.
type:PROJECT_JOINEDtargetType:PROJECTtargetId:projectIdtitle:{프로젝트명} · 합류content:{합류자명}님이 프로젝트에 합류했어요프로젝트 일정이 새로 등록되었을 때 프로젝트 참여자에게 알림을 생성할 수 있도록 메서드를 추가했습니다.
type:SCHEDULE_CREATEDtargetType:SCHEDULEtargetId:scheduleIdtitle:{프로젝트명} · 새 일정content:{등록자명}님이 [{일정명}] 일정을 등록했어요프로젝트 공지가 등록되었을 때 프로젝트 참여자에게 알림을 생성할 수 있도록 메서드를 추가했습니다.
type:NOTICE_CREATEDtargetType:NOTICEtargetId:noticeIdtitle:{프로젝트명} · 새 공지content:{등록자명}님이 새 공지를 등록했어요: {공지 제목}프로젝트 파일이 등록되었을 때 프로젝트 참여자에게 알림을 생성할 수 있도록 메서드를 추가했습니다.
type:FILE_UPLOADEDtargetType:PROJECT_FILEtargetId:projectIdtitle:{프로젝트명} · 새 파일content:{등록자명}님이 [{파일명}] 파일을 등록했어요현재 파일 업로드는 단건 등록 기준이므로 그룹핑은 적용하지 않았습니다.
영상 피드백 또는 답글이 등록되었을 때 프로젝트 참여자에게 알림을 생성할 수 있도록 정리했습니다.
type:VIDEO_FEEDBACK_COMMENTEDtargetType:VIDEOtargetId:videoIdcontent:{작성자명}님이 [{영상명}]에 새로운 피드백을 남겼어요content:[{영상명}]에 새로운 피드백 {N}건이 등록되었어요동일 영상 기준의 읽지 않은 알림이 이미 있으면 새 알림을 만들지 않고 기존 알림의
title,content,groupCount를 갱신합니다.공고에 새로운 지원자가 발생했을 때 공고 작성자에게 알림을 생성할 수 있도록 정리했습니다.
type:RECRUITMENT_APPLIEDtargetType:RECRUITMENTtargetId:recruitmentIdcontent:{지원자명}님이 [{공고명}]에 지원했어요content:[{공고명}]에 새로운 지원자 {N}명이 지원했어요동일 공고 기준의 읽지 않은 알림이 이미 있으면 새 알림을 만들지 않고 기존 알림의
title,content,groupCount를 갱신합니다.초대 링크 생성 시점에는 수신자를 특정할 수 없고, 정책이 프로젝트 합류 알림 기준으로 정리되어 기존 프로젝트 초대 알림 타입과 생성 메서드를 제거했습니다.
참고 사항
NotificationService메서드만 호출하면 됩니다.✅ PR 체크리스트
테스트
./gradlew testSummary by CodeRabbit