-
Notifications
You must be signed in to change notification settings - Fork 0
feat: 개인 알림 생성 메서드 확장 #120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cca00e3
f6e4d08
1ca9bbf
54e9956
ffa532e
8928c04
7127b2d
242c255
999b6fd
e377f89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,5 +8,7 @@ public enum NotificationTargetType { | |
| SCHEDULE, | ||
| PROJECT, | ||
| VIDEO, | ||
| RECRUITMENT | ||
| RECRUITMENT, | ||
| NOTICE, | ||
| PROJECT_FILE | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -184,70 +184,91 @@ public void createScheduleAssignedNotifications( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Users> recipients, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long writerId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotifications(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(recipients.stream() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map(Users::getId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .toList()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .projectId(project != null ? project.getId() : null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.SCHEDULE_ASSIGNED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createScheduleAssignedTitle(project != null ? project.getTitle() : null)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createScheduleAssignedContent(scheduleTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.SCHEDULE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(scheduleId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .excludeUserId(writerId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(scheduleId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(writerId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Set<Long> recipientIds = new HashSet<>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Notification> notifications = recipients.stream() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter(Objects::nonNull) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter(recipient -> recipientIds.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); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+199
to
+214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 중복 수신자를 제거하세요.
수정 예시+ 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트 초대 알림을 생성한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 클릭 대상은 프로젝트 상세 화면이다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @deprecated 알림 문구는 알림 도메인에서 관리하므로 projectTitle을 받는 메서드를 사용한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트 합류 알림을 프로젝트 참여자에게 생성한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 합류자 본인도 수신 대상에 포함할 수 있다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Deprecated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createProjectInvitationNotification( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long recipientId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createProjectJoinedNotifications( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String content | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String projectTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String joinerName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Long> recipientIds | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(recipientId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(projectId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(projectTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(joinerName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotification(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(List.of(recipientId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotifications(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(recipientIds) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .projectId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.PROJECT_INVITED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createFallbackTitle(NotificationType.PROJECT_INVITED)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(content) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.PROJECT_JOINED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createProjectJoinedTitle(projectTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createProjectJoinedContent(joinerName)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.PROJECT) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트 초대 알림 문구를 정책에 맞춰 생성한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트에 새 일정이 등록되었을 때 프로젝트 참여자에게 알림을 생성한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createProjectInvitationNotification( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long recipientId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createScheduleCreatedNotifications( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long scheduleId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String projectTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String inviterName | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String scheduleTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String creatorName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Long> recipientIds, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long actorUserId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(projectId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(recipientId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(scheduleId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(actorUserId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(projectTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(inviterName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(scheduleTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(creatorName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotification(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(List.of(recipientId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotifications(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(recipientIds) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .projectId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.PROJECT_INVITED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createProjectInvitationTitle(projectTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createProjectInvitationContent(projectTitle, inviterName)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.PROJECT) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.SCHEDULE_CREATED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createScheduleCreatedTitle(projectTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createScheduleCreatedContent(scheduleTitle, creatorName)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.SCHEDULE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(scheduleId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .excludeUserId(actorUserId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -320,7 +341,7 @@ public void createVideoFeedbackCommentedNotifications( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 새로운 지원자 발생 알림을 생성하거나 기존 미읽음 알림을 갱신한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 동일 공고 기준으로 그룹핑하므로 targetId는 recruitmentId를 사용한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @deprecated 알림 문구는 알림 도메인에서 관리하므로 recruitmentTitle과 applicantName을 받는 메서드를 사용한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @deprecated 알림 문구는 알림 도메인에서 관리하므로 projectTitle, recruitmentTitle, applicantName을 받는 메서드를 사용한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Deprecated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -349,18 +370,20 @@ public void createRecruitmentAppliedNotification( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createRecruitmentAppliedNotification( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long recipientId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long recruitmentId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String projectTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String recruitmentTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String applicantName | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(recipientId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(recruitmentId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(projectTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(recruitmentTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(applicantName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NotificationCreateCommand command = NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(List.of(recipientId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.RECRUITMENT_APPLIED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createRecruitmentAppliedTitle(recruitmentTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createRecruitmentAppliedTitle(projectTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createRecruitmentAppliedContent(recruitmentTitle, applicantName, 1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.RECRUITMENT) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(recruitmentId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -372,6 +395,88 @@ public void createRecruitmentAppliedNotification( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 공고 프로젝트명을 알 수 없는 기존 호출부에서 사용하는 지원자 알림 생성 메서드다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트명을 전달할 수 있는 경우에는 5개 인자 메서드를 사용한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createRecruitmentAppliedNotification( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long recipientId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long recruitmentId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String recruitmentTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String applicantName | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createRecruitmentAppliedNotification( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recipientId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recruitmentId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recruitmentTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recruitmentTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| applicantName | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트 공지가 등록되었을 때 프로젝트 참여자에게 알림을 생성한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createNoticeCreatedNotifications( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long noticeId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String projectTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String noticeTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String creatorName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Long> recipientIds, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long actorUserId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(projectId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(noticeId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(actorUserId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(projectTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(noticeTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(creatorName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotifications(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(recipientIds) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .projectId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.NOTICE_CREATED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createNoticeCreatedTitle(projectTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createNoticeCreatedContent(noticeTitle, creatorName)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.NOTICE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(noticeId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .excludeUserId(actorUserId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * 프로젝트 파일 등록 알림을 생성한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Transactional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void createFileUploadedNotifications( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String projectTitle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String fileName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String uploaderName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Long> recipientIds, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long actorUserId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(projectId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredId(actorUserId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(projectTitle); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(fileName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateRequiredText(uploaderName); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createNotifications(NotificationCreateCommand.builder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .recipientIds(recipientIds) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .projectId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .type(NotificationType.FILE_UPLOADED) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .title(createFileUploadedTitle(projectTitle)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .content(createFileUploadedContent(fileName, uploaderName)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetType(NotificationTargetType.PROJECT_FILE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .targetId(projectId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .excludeUserId(actorUserId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private void validateActiveUser(Long currentUserId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!userRepository.existsByIdAndDeletedAtIsNull(currentUserId)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new BaseException(CommonErrorCode.NOT_FOUND); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -555,20 +660,28 @@ private NotificationListResponse.NotificationSummary toSummary(Notification noti | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createScheduleAssignedContent(String scheduleTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "'" + scheduleTitle + "' 일정 담당자로 지정되었습니다."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createScheduleAssignedContent(String scheduleTitle, String assigneeName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정되었어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+663
to
665
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 담당자 지정 문구를 수동형으로 수정하세요.
수정 예시- return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정했어요";
+ return assigneeName + "님이 [" + scheduleTitle + "] 담당자로 지정되었어요";📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createScheduleAssignedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "일정 담당자 지정"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createProjectInvitationTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "프로젝트 초대"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createProjectJoinedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "합류"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createProjectInvitationContent(String projectTitle, String inviterName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return inviterName + "님이 [" + projectTitle + "] 프로젝트에 초대했어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createProjectJoinedContent(String joinerName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinerName + "님이 프로젝트에 합류했어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createScheduleCreatedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "새 일정"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createScheduleCreatedContent(String scheduleTitle, String creatorName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return creatorName + "님이 [" + scheduleTitle + "] 일정을 등록했어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createVideoFeedbackCommentedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -587,8 +700,8 @@ private String createVideoFeedbackCommentedContent( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "[" + videoTitle + "]에 새로운 피드백 " + groupCount + "건이 등록되었어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createRecruitmentAppliedTitle(String recruitmentTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(recruitmentTitle, "새로운 지원자"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createRecruitmentAppliedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "새로운 지원자"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createRecruitmentAppliedContent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -603,10 +716,26 @@ private String createRecruitmentAppliedContent( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "[" + recruitmentTitle + "]에 새로운 지원자 " + groupCount + "명이 지원했어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createNoticeCreatedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "새 공지"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createNoticeCreatedContent(String noticeTitle, String creatorName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return creatorName + "님이 새 공지를 등록했어요: " + noticeTitle; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createFileUploadedTitle(String projectTitle) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return joinTitle(projectTitle, "새 파일"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createFileUploadedContent(String fileName, String uploaderName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return uploaderName + "님이 [" + fileName + "] 파일을 등록했어요"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private String createFallbackTitle(NotificationType type) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return switch (type) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case SCHEDULE_ASSIGNED -> "일정 담당자 지정"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case PROJECT_INVITED -> "프로젝트 초대"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case PROJECT_JOINED -> "합류"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case VIDEO_FEEDBACK_COMMENTED -> "새로운 피드백"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case RECRUITMENT_APPLIED -> "새로운 지원자"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case SCHEDULE_CREATED -> "새 일정"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 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