feat: 개인 알림 도메인 이벤트 연결 - #138
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 Sequence Diagram(s)sequenceDiagram
participant ProjectNoticeService
participant ProjectMemberRepository
participant NotificationService
ProjectNoticeService->>ProjectMemberRepository: 활성 프로젝트 멤버 조회
ProjectMemberRepository-->>ProjectNoticeService: 사용자 ID 목록 반환
ProjectNoticeService->>NotificationService: 공지 생성 알림 요청
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 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: 1
🧹 Nitpick comments (1)
src/test/java/com/slatto/domain/notification/service/ProjectNoticeActivityFlowIntegrationTest.java (1)
60-61: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win공지 알림 연결과 저장을 검증하도록 테스트를 보강하세요.
Line 60의
@MockBean NotificationService는 실제 알림 생성과notification테이블 저장을 우회합니다. 현재 테스트는createProjectNotice가 알림 메서드를 호출하지 않아도 통과합니다.최소한
verify(notificationService).createNoticeCreatedNotifications(...)로 호출 인자와 수신자 목록을 검증하세요. 저장 여부까지 확인하려면 실제NotificationService를 포함한 별도@DataJpaTest를 추가하세요.🤖 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/test/java/com/slatto/domain/notification/service/ProjectNoticeActivityFlowIntegrationTest.java` around lines 60 - 61, ProjectNoticeActivityFlowIntegrationTest의 `@MockBean` notificationService가 실제 알림 생성과 저장을 우회하므로, createProjectNotice 테스트에서 notificationService.createNoticeCreatedNotifications(...) 호출을 수신자 목록과 함께 verify하도록 검증을 추가하세요. 저장까지 검증해야 한다면 실제 NotificationService를 사용하는 별도 `@DataJpaTest를` 추가하세요.
🤖 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/project/service/ProjectFileService.java`:
- Around line 130-137: Update the file-upload notification flow around
createFileUploadedNotifications to use savedFile.getId() as the PROJECT_FILE
targetId, and ensure NotificationService preserves that file ID when setting the
target. Do not use projectId as the target for PROJECT_FILE; if the intended
target remains the project, change the target type to PROJECT instead.
---
Nitpick comments:
In
`@src/test/java/com/slatto/domain/notification/service/ProjectNoticeActivityFlowIntegrationTest.java`:
- Around line 60-61: ProjectNoticeActivityFlowIntegrationTest의 `@MockBean`
notificationService가 실제 알림 생성과 저장을 우회하므로, createProjectNotice 테스트에서
notificationService.createNoticeCreatedNotifications(...) 호출을 수신자 목록과 함께
verify하도록 검증을 추가하세요. 저장까지 검증해야 한다면 실제 NotificationService를 사용하는 별도 `@DataJpaTest를`
추가하세요.
🪄 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: 8d9acd60-508f-423c-9c26-4400781e0506
📒 Files selected for processing (6)
src/main/java/com/slatto/domain/notification/service/NotificationService.javasrc/main/java/com/slatto/domain/project/service/ProjectFileService.javasrc/main/java/com/slatto/domain/project/service/ProjectInvitationService.javasrc/main/java/com/slatto/domain/project/service/ProjectNoticeService.javasrc/main/java/com/slatto/domain/schedule/service/ScheduleService.javasrc/test/java/com/slatto/domain/notification/service/ProjectNoticeActivityFlowIntegrationTest.java
| notificationService.createFileUploadedNotifications( | ||
| projectId, | ||
| project.getTitle(), | ||
| savedFile.getFileName(), | ||
| currentMember.getUser().getNickname(), | ||
| getActiveProjectMemberUserIds(projectId), | ||
| currentUserId | ||
| ); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 기대 결과: PROJECT_FILE 알림의 targetId가 파일 ID이며 모든 소비자가 같은 계약을 사용한다.
rg -n -C 6 \
'createFileUploadedNotifications|NotificationTargetType\.PROJECT_FILE|targetType|targetId' \
src/main/java src/test/javaRepository: SLAT-TO/SLATE-TO-BE
Length of output: 50375
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Candidate files =="
fd -p 'NotificationService\.java|NotificationTargetType\.java|ProjectFileService\.java|ProjectFile\.java|NotificationListProcessor|Notification.*Consumer|ActivityLogService\.java' src/main/java || true
echo
echo "== NotificationTargetType =="
rg -n -C 4 'enum NotificationTargetType|PROJECT_FILE|PROJECT_FILE' src/main/java src/test/java || true
echo
echo "== NotificationService file sections =="
file="$(fd 'NotificationService\.java' src/main/java | head -n1)"
if [ -n "${file}" ]; then
wc -l "$file"
rg -n -C 8 'createFileUploadedNotifications|createScheduleAssigned|createProjectJoined|createScheduleCreated|createVideoFeedbackCommented|targetType|targetId' "$file"
fi
echo
echo "== Processor/UserConsumer references =="
rg -n -C 5 'PROJECT_FILE|fileUploaded|SCHEDULE_CREATED|PROJECT|targetType|targetId|Notification.*EventListener|StreamListener|KafkaListener|Consumer' src/main/java/src/test java 2>/dev/null | head -n 200 || true
rg -n -C 5 'PROJECT_FILE|fileUploaded|SCHEDULE_CREATED|PROJECT|targetType|targetId|Notification.*EventListener|StreamListener|KafkaListener|Consumer' src/main/java src/test/java | head -n 240 || trueRepository: SLAT-TO/SLATE-TO-BE
Length of output: 50058
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== ProjectFileService upload section =="
file="$(fd 'ProjectFileService\.java' src/main/java | head -n1)"
if [ -n "${file}" ]; then
sed -n '1,150p' "$file" | cat -n
fi
echo
echo "== ActivityLogService file upload section =="
file="$(fd 'ActivityLogService\.java' src/main/java | head -n1)"
if [ -n "${file}" ]; then
rg -n -C 10 'createFileUploadedLog|createFileUploaded' "$file" || true
fi
echo
echo "== Read-only scan: PROJECT_FILE usages =="
rg -n -C 3 'NotificationTargetType\.PROJECT_FILE|PROJECT_FILE|PROJECT_FILE|PROJECT_FILE|targetType.*PROJECT_FILE|targetType.*"PROJECT_FILE"|type.*FILE_UPLOADED|FILE_UPLOADED' src/main/java src/test/java || true
echo
echo "== Read-only scan: Notification click/route helpers =="
rg -n -C 4 'targetType|targetId|get.*Route|navigate|router|FileUploaded|fileUploaded|FILE_UPLOADED|PROJECT_FILE' src/main/java src/test/java || trueRepository: SLAT-TO/SLATE-TO-BE
Length of output: 50376
PROJECT_FILE 알림의 대상 ID를 파일 ID로 맞추세요.
createFileUploadedNotifications()은 targetType을 PROJECT_FILE로 설정한 뒤 targetId에 projectId를 저장합니다. NotificationTargetType.PROJECT_FILE을 사용할 목적이라면 savedFile.getId()를 전달하고 NotificationService의 targetId도 해당 파일 id로 고정하세요. 프로젝트 ID가 실제 대상이면 PROJECT_FILE 대신 targetType을 PROJECT로 변경하세요.
수정 예시
notificationService.createFileUploadedNotifications(
projectId,
+ savedFile.getId(),
project.getTitle(), public void createFileUploadedNotifications(
Long projectId,
+ Long fileId,
String projectTitle,
...
- .targetId(projectId)
+ .targetId(fileId)🤖 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/project/service/ProjectFileService.java`
around lines 130 - 137, Update the file-upload notification flow around
createFileUploadedNotifications to use savedFile.getId() as the PROJECT_FILE
targetId, and ensure NotificationService preserves that file ID when setting the
target. Do not use projectId as the target for PROJECT_FILE; if the intended
target remains the project, change the target type to PROJECT instead.
| saveProjectRoles(projectMember, roleNames); | ||
| projectInvitation.accept(accepter); | ||
| activityLogService.createProjectMemberJoinedLog(project.getId(), accepter.getId()); | ||
| notificationService.createProjectJoinedNotifications( |
There was a problem hiding this comment.
excludeUserId를 추가하지 않아 다른 서비스들과 다르게 알림 대상에 행위자를 포함한 것은 의도하신 것일까요!?
🔗 관련 이슈 (Related Issue)
Closes #127
📝 작업 내용
개인 알림 생성 메서드를 실제 도메인 이벤트에 연결하고, 정책서 기준에 맞춰 알림 문구를 정리했습니다.
각 도메인에서는
NotificationService의 알림 생성 메서드만 호출하도록 구성했고, 알림 제목과 본문 생성은 알림 도메인에서 담당하도록 정리했습니다.주요 변경 사항
구현된 개인 알림
SCHEDULE_ASSIGNEDPROJECT_JOINEDVIDEO_FEEDBACK_COMMENTEDRECRUITMENT_APPLIEDSCHEDULE_CREATEDNOTICE_CREATEDFILE_UPLOADED알림 문구 기준
정책서 기준에 맞춰 알림
title,content를 알림 도메인 내부에서 생성하도록 정리했습니다.{사용자명}님이 [{일정명}] 담당자로 지명되었어요.{합류자명}님이 프로젝트에 합류했어요.{작성자명}님이 [{영상명}]에 새로운 피드백을 남겼어요.[{영상명}]에 새로운 피드백 {N}건이 등록되었어요.{지원자명}님이 [{공고명}]에 지원했어요.[{공고명}]에 새로운 지원자 {N}명이 지원했어요.{등록자명}님이 [{일정명}] 일정을 등록했어요.{등록자명}님이 새 공지를 등록했어요: {공지 제목}.{등록자명}님이 [{파일명}] 파일을 등록했어요.참고 사항
targetType,targetId,projectId를 기준으로 프론트에서 처리합니다.NotificationRepository나Notification엔티티를 직접 사용하지 않고NotificationService만 호출합니다.✅ PR 체크리스트
테스트
./gradlew testSummary by CodeRabbit
새 기능
개선