Skip to content

feat: 알림 단계 설정과 자동 알림 발송 구현#77

Merged
deli-minju merged 4 commits into
developfrom
feat/#76-notification-settings-auto
May 27, 2026
Merged

feat: 알림 단계 설정과 자동 알림 발송 구현#77
deli-minju merged 4 commits into
developfrom
feat/#76-notification-settings-auto

Conversation

@deli-minju
Copy link
Copy Markdown
Contributor

@deli-minju deli-minju commented May 27, 2026

📌 작업 요약

  • 요약:
    • 알림 수신 단계를 URGENT_ONLY, IMPORTANT, ALL, OFF로 확장
    • 회원가입/설정에서 알림 단계를 저장하고 변경할 수 있도록 API를 추가
    • 알림 목록 응답에 level, childId, childName을 추가하고, childId 기준 필터 조회를 지원
    • 가정통신문 분석 완료 시 알림을 자동 생성하도록 연결
    • 마감 D-1, 체크리스트 D-3/D-1, 주간 요약 알림을 생성하는 스케줄러를 추가
    • 사용자 알림 단계에 따라 Expo 푸시 발송 여부를 필터링하도록 변경
    • 기존 데이터 마이그레이션을 위한 V16 Flyway migration을 추가
  • 관련 이슈: closes [FEAT] 알림 설정 단계/알림함 필터/자동 알림 발송 보강 #76

🌿 브랜치 정보

  • Source: feat/#76-notification-settings-auto
  • Target: develop (기본)

✅ 체크리스트

  • 브랜치 컨벤션 준수 (feat/refac/hotfix/chore/design/bugfix)
  • 커밋 컨벤션 준수 (feat/fix/refactor/docs/style/chore)
  • self-review 완료
  • 테스트 및 로컬 실행 확인 완료

🧪 테스트 결과

./gradlew.bat --no-daemon compileJava
BUILD SUCCESSFUL

./gradlew.bat --no-daemon compileTestJava
BUILD SUCCESSFUL

./gradlew.bat --no-daemon spotlessCheck
BUILD SUCCESSFUL

Summary by CodeRabbit

  • 새로운 기능
    • 자동 알림 시스템 도입: 마감 리마인더, 체크리스트 알림, 주간 요약, 뉴스레터 분석 완료 알림이 스케줄에 따라 발송됩니다.
    • 알림에 중요도(level)와 자녀(child) 정보가 포함되어 표시됩니다.
  • 변경 사항
    • 알림 수신 단계가 4단계(긴급만/중요/전체/차단)로 확장되어 세분화된 수신 설정 가능.
    • 알림 목록 조회에서 자녀별 필터링(childId) 가능.
    • 마이페이지에 알림 단계 표시 및 알림 설정 변경 API 추가.
  • 데이터베이스
    • 사용자·알림 관련 필드와 제약이 추가되어 기본값 및 검증 강화되었습니다.

Review Change Stack

@deli-minju deli-minju self-assigned this May 27, 2026
@deli-minju deli-minju added the feat 새로운 기능 추가 작업 label May 27, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Warning

Review limit reached

@deli-minju, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 34 minutes and 47 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ffd43274-8f48-4aff-bd34-134dfca9e004

📥 Commits

Reviewing files that changed from the base of the PR and between d0d5fd2 and 309cea9.

📒 Files selected for processing (2)
  • src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java
  • src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineStatusService.java
📝 Walkthrough

Walkthrough

사용자 알림 선호도를 enum으로 확장하고 알림 엔터티/응답에 level·child 컨텍스트를 추가했습니다. 저장소·서비스·컨트롤러와 회원가입/뉴스레터 통합을 업데이트하고 NotificationScheduler를 추가해 마감·체크리스트·주간 알림을 자동 생성합니다.

변경사항

알림 설정 단계 및 자동 알림 생성

Layer / File(s) Summary
알림 관련 열거형 정의
src/main/java/com/gachi/be/domain/user/entity/enums/NotificationPreference.java, src/main/java/com/gachi/be/domain/notification/entity/enums/NotificationLevel.java, src/main/java/com/gachi/be/domain/notification/entity/enums/NotificationType.java
NotificationPreference(URGENT_ONLY, IMPORTANT, ALL, OFF)과 허용 로직, NotificationLevel(URGENT, IMPORTANT, NORMAL), NotificationType에 DEADLINE_REMINDER·WEEKLY_SUMMARY 추가.
User 엔티티 및 DB 마이그레이션
src/main/java/com/gachi/be/domain/user/entity/User.java, src/main/resources/db/migration/V16__notification_preference_and_context.sql, src/main/java/com/gachi/be/domain/user/repository/UserRepository.java
User에 notificationPreference 필드·변환/동기화 로직 추가, users 테이블에 notification_preference 컬럼 마이그레이션 및 상태별 조회 추가.
Notification 엔티티·DTO·마이그레이션
src/main/java/com/gachi/be/domain/notification/entity/Notification.java, src/main/java/com/gachi/be/domain/notification/dto/response/NotificationResponse.java, src/main/java/com/gachi/be/domain/notification/service/NotificationCreateCommand.java, src/main/resources/db/migration/V16__notification_preference_and_context.sql
Notification 엔티티에 level/childId/childName 추가 및 기본값 보장. NotificationResponse·NotificationCreateCommand에 새 필드 포함. notifications 테이블 컬럼·제약·인덱스 변경.
저장소 조회 메서드 확장
src/main/java/com/gachi/be/domain/calendar/repository/CalendarEventRepository.java, src/main/java/com/gachi/be/domain/checklist/repository/ChecklistRepository.java, src/main/java/com/gachi/be/domain/newsletter/repository/NewsletterRepository.java, src/main/java/com/gachi/be/domain/child/repository/ChildRepository.java, src/main/java/com/gachi/be/domain/notification/repository/NotificationRepository.java
캘린더 범위 조회, 체크리스트 미완료·카운트 조회, child 조회 보조 메서드, NotificationRepository.findInbox에 childId/childName 필터 추가.
NotificationService 및 푸시 필터링
src/main/java/com/gachi/be/domain/notification/service/NotificationService.java, src/main/java/com/gachi/be/domain/notification/service/NotificationPushDispatcher.java
getNotifications 오버로드에 childId 추가·resolveChildName 구현, createNotification/toResponse에 level·child 필드 매핑, 푸시 필터를 notificationPreference.allows(level)로 변경.
알림 API 및 사용자 설정 관리
src/main/java/com/gachi/be/domain/notification/api/controller/NotificationController.java, src/main/java/com/gachi/be/domain/user/api/controller/UserController.java, src/main/java/com/gachi/be/domain/user/dto/request/ChangeNotificationRequest.java, src/main/java/com/gachi/be/domain/user/dto/response/UserMeResponse.java, src/main/java/com/gachi/be/global/code/SuccessCode.java
NotificationController에 childId 파라미터 추가 및 OpenAPI 문구 간소화. UserController에 getMyInfo에 notificationPreference 포함 및 PATCH /me/notification 엔드포인트 추가. 관련 DTO/SuccessCode 확장.
회원가입 및 Newsletter 통합
src/main/java/com/gachi/be/domain/auth/dto/request/SignupRequest.java, src/main/java/com/gachi/be/domain/auth/service/impl/AuthServiceImpl.java, src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java
SignupRequest에 notificationPreference 추가, AuthServiceImpl에서 기본값 IMPORTANT 처리. NewsletterPipelineService에서 분석 완료 후 알림 생성 로직을 트랜잭션 이후로 스케줄링하고 실패는 경고로 처리.
자동 알림 생성 스케줄러
src/main/java/com/gachi/be/GachiBeApplication.java, src/main/java/com/gachi/be/domain/notification/service/NotificationScheduler.java
NotificationScheduler 추가: 매일/매주 크론으로 마감 D-1, 체크리스트 D-3/D-1, 주간 요약(일요일)을 생성. GachiBeApplication에 @EnableScheduling 추가.

Sequence Diagram

sequenceDiagram
  participant Scheduler as NotificationScheduler
  participant CalendarRepo as CalendarEventRepository
  participant ChecklistRepo as ChecklistRepository
  participant NewsletterRepo as NewsletterRepository
  participant ChildRepo as ChildRepository
  participant NotificationSvc as NotificationService

  Scheduler->>CalendarRepo: findByStartAtGreaterThanEqualAndStartAtLessThan(range)
  Scheduler->>ChecklistRepo: findByTypeAndCompletedFalseAndTargetDate(...)
  CalendarRepo-->>Scheduler: events
  ChecklistRepo-->>Scheduler: checklists
  Scheduler->>NewsletterRepo: findById(...) (for newsletterId)
  Scheduler->>ChildRepo: findFirstByUserIdAndNameAndDeletedAtIsNull(userId,name)
  Scheduler->>NotificationSvc: createNotification(NotificationCreateCommand)
  NotificationSvc-->>NotificationSvc: resolveChildName / build Notification entity
  NotificationSvc-->>Scheduler: confirmation / exception logged
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • GACHI-Project/GACHI-BE#73: NotificationPreference/NotificationLevel 및 NotificationPushDispatcher 관련 변경과 코드 레벨 연계가 있습니다.

Suggested reviewers

  • Hminkyung
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 '알림 단계 설정과 자동 알림 발송 구현'으로 변경사항의 주요 내용을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명은 작업 요약, 브랜치 정보, 체크리스트, 테스트 결과를 포함하며 템플릿 요구사항을 충족하고 있습니다.
Linked Issues check ✅ Passed PR의 모든 주요 변경사항이 #76 이슈의 요구사항을 충족합니다: 알림 수신 단계 enum 추가, 회원가입/설정 API 확장, 알림 모델 확장, 자동 알림 스케줄러 구현, 푸시 발송 필터링 적용, 마이그레이션 추가.
Out of Scope Changes check ✅ Passed 모든 변경사항이 #76 이슈의 범위 내에 있습니다. 알림 단계 설정, 자동 알림 발송, 마이그레이션 등 모두 이슈 요구사항과 직접 관련됩니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#76-notification-settings-auto

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/gachi/be/domain/notification/service/NotificationService.java (1)

160-164: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

알림 level null 허용으로 저장/발송 경로가 깨질 수 있습니다.

createNotification에서 command.level()을 검증하지 않고 그대로 빌더에 주입하고 있습니다. 호출부에서 level을 누락하면 DB 제약 위반 또는 이후 단계 필터링 시 런타임 오류로 이어질 수 있으니, null 방어(기본값 지정 또는 예외)가 필요합니다.

🔧 제안 수정
     if (command == null
         || command.type() == null
+        || command.level() == null
         || !StringUtils.hasText(command.title())
         || !StringUtils.hasText(command.body())) {
       throw new BusinessException(ErrorCode.INVALID_INPUT_VALUE);
     }
@@
             .type(command.type())
-            .level(command.level())
+            .level(command.level())

Also applies to: 178-178

🤖 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/gachi/be/domain/notification/service/NotificationService.java`
around lines 160 - 164, The createNotification path in NotificationService
currently skips validating command.level() and passes it straight into
Notification.builder(), which can cause DB constraint or runtime filter errors
if callers omit level; update the validation in the createNotification method to
check command.level() (or provide a sensible default like
NotificationLevel.DEFAULT/INFO) and throw
BusinessException(ErrorCode.INVALID_INPUT_VALUE) when null (or document/set the
default), and apply the same null-defense to the other affected site noted in
the review (the similar check around the update path at the other reported
location) so both places either validate or default command.level() before
building/persisting the Notification.
🤖 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/gachi/be/domain/auth/service/impl/AuthServiceImpl.java`:
- Around line 141-143: The signup flow in AuthServiceImpl currently forwards
request.notificationPreference() directly to the entity builder (via
.notificationPreference(request.notificationPreference())), relying on the
entity to default missing values; change the signup path to enforce the spec by
mapping a null/absent request.notificationPreference() to the default IMPORTANT
before calling .notificationPreference(...). Locate the builder call around
.languageCode(...)/.notificationPreference(...)/.emailVerifiedAt(now) and
replace the direct use of request.notificationPreference() with a computed value
(e.g., notificationPreference != null ? notificationPreference : IMPORTANT) so
the signup endpoint explicitly guarantees the default.

In
`@src/main/java/com/gachi/be/domain/checklist/repository/ChecklistRepository.java`:
- Line 29: The current repository method countByUserIdAndCompletedFalse
incorrectly includes TODO-type items in its tally; change the query surface to
only count checklist items with ChecklistType.CHECKLIST (e.g., add or replace
with a method such as countByUserIdAndCompletedFalseAndType or
countByUserIdAndCompletedFalseAndTypeEquals checking ChecklistType.CHECKLIST) so
the "incomplete but completable" count excludes ChecklistType.TODO; update
usages of countByUserIdAndCompletedFalse to call the new method.

In
`@src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java`:
- Around line 189-192: The createAnalysisCompletedNotification call must be
isolated from the markCompleted (REQUIRES_NEW) transaction so that failures in
notification do not roll back the completed-state save; modify the block where
n.complete(...), Newsletter saved = newsletterRepository.save(n) and
createAnalysisCompletedNotification(saved) are called to first persist the
completed state (newsletterRepository.save in the method that invokes n.complete
/ markCompleted) and then invoke createAnalysisCompletedNotification(saved) in a
separate try/catch or separate transactional/non-transactional method so any
exception is caught and logged without propagating; apply the same change to the
similar sequence around the code referenced in the 221-239 region so
notification failures are logged/isolated rather than causing the REQUIRES_NEW
transaction to rollback.

In
`@src/main/java/com/gachi/be/domain/notification/repository/NotificationRepository.java`:
- Line 22: 현재 JPQL 조건 "AND (:childId IS NULL OR n.childId = :childId OR
n.childName = :childName)"는 childId가 주어져도 같은 이름의 다른 자녀 알림을 포함하므로, childName 기반
조회는 childId가 비어 있는 레거시 데이터에만 허용되도록 수정하세요: 교체할 조건은 "AND ( ( :childId IS NULL AND
(n.childId IS NULL OR n.childName = :childName) ) OR n.childId = :childId )"처럼
작성해 NotificationRepository의 해당 JPQL/SQL 쿼리(현재 n.childId, n.childName을 사용하는 WHERE
절)를 업데이트하고 동일한 변경을 파일의 다른 두 위치(언급된 28-29의 유사 조건)에도 적용하세요.

In
`@src/main/java/com/gachi/be/domain/notification/service/NotificationScheduler.java`:
- Around line 65-84: The loop in NotificationScheduler that processes each
CalendarEvent (using resolveChildId, payload(), putIfPresent and
notificationService.createNotification) must not let one event's exception stop
the whole batch; wrap the per-event processing (everything inside the for
(CalendarEvent event : events) { ... } block) in a try-catch, catch Exception,
log the error with contextual data (event.getId(), event.getUserId(), targetDate
or childName) and continue to the next event. Apply the same per-item try-catch
pattern to the other similar blocks (the loops that call
notificationService.createNotification at lines referenced) so each failure is
isolated and does not abort the scheduler run.

---

Outside diff comments:
In
`@src/main/java/com/gachi/be/domain/notification/service/NotificationService.java`:
- Around line 160-164: The createNotification path in NotificationService
currently skips validating command.level() and passes it straight into
Notification.builder(), which can cause DB constraint or runtime filter errors
if callers omit level; update the validation in the createNotification method to
check command.level() (or provide a sensible default like
NotificationLevel.DEFAULT/INFO) and throw
BusinessException(ErrorCode.INVALID_INPUT_VALUE) when null (or document/set the
default), and apply the same null-defense to the other affected site noted in
the review (the similar check around the update path at the other reported
location) so both places either validate or default command.level() before
building/persisting the Notification.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9604ca94-b8d7-4042-ab8b-123ccb8b4534

📥 Commits

Reviewing files that changed from the base of the PR and between adc0af0 and faeb201.

📒 Files selected for processing (26)
  • src/main/java/com/gachi/be/GachiBeApplication.java
  • src/main/java/com/gachi/be/domain/auth/dto/request/SignupRequest.java
  • src/main/java/com/gachi/be/domain/auth/service/impl/AuthServiceImpl.java
  • src/main/java/com/gachi/be/domain/calendar/repository/CalendarEventRepository.java
  • src/main/java/com/gachi/be/domain/checklist/repository/ChecklistRepository.java
  • src/main/java/com/gachi/be/domain/child/repository/ChildRepository.java
  • src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java
  • src/main/java/com/gachi/be/domain/newsletter/repository/NewsletterRepository.java
  • src/main/java/com/gachi/be/domain/notification/api/controller/NotificationController.java
  • src/main/java/com/gachi/be/domain/notification/dto/response/NotificationResponse.java
  • src/main/java/com/gachi/be/domain/notification/entity/Notification.java
  • src/main/java/com/gachi/be/domain/notification/entity/enums/NotificationLevel.java
  • src/main/java/com/gachi/be/domain/notification/entity/enums/NotificationType.java
  • src/main/java/com/gachi/be/domain/notification/repository/NotificationRepository.java
  • src/main/java/com/gachi/be/domain/notification/service/NotificationCreateCommand.java
  • src/main/java/com/gachi/be/domain/notification/service/NotificationPushDispatcher.java
  • src/main/java/com/gachi/be/domain/notification/service/NotificationScheduler.java
  • src/main/java/com/gachi/be/domain/notification/service/NotificationService.java
  • src/main/java/com/gachi/be/domain/user/api/controller/UserController.java
  • src/main/java/com/gachi/be/domain/user/dto/request/ChangeNotificationRequest.java
  • src/main/java/com/gachi/be/domain/user/dto/response/UserMeResponse.java
  • src/main/java/com/gachi/be/domain/user/entity/User.java
  • src/main/java/com/gachi/be/domain/user/entity/enums/NotificationPreference.java
  • src/main/java/com/gachi/be/domain/user/repository/UserRepository.java
  • src/main/java/com/gachi/be/global/code/SuccessCode.java
  • src/main/resources/db/migration/V16__notification_preference_and_context.sql

Comment thread src/main/java/com/gachi/be/domain/checklist/repository/ChecklistRepository.java Outdated
@deli-minju
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java (1)

191-199: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

알림 생성 실패 격리가 아직 트랜잭션 레벨에서 불완전합니다.

Line 191-193의 try/catch는 예외 전파만 막고, JPA/트랜잭션 상태가 rollback-only로 표시되는 케이스는 막지 못할 수 있습니다. markCompleted 커밋 이후에 알림을 실행하도록 분리하는 편이 안전합니다.

🔧 제안 수정
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
...
   Newsletter saved = newsletterRepository.save(n);
-  try {
-    createAnalysisCompletedNotification(saved);
-  } catch (Exception ex) {
-    log.warn(
-        "[Pipeline] 분석 완료 알림 생성 실패. newsletterId={}, error={}",
-        saved.getId(),
-        ex.getMessage(),
-        ex);
-  }
+  TransactionSynchronizationManager.registerSynchronization(
+      new TransactionSynchronization() {
+        `@Override`
+        public void afterCommit() {
+          try {
+            createAnalysisCompletedNotification(saved);
+          } catch (Exception ex) {
+            log.warn(
+                "[Pipeline] 분석 완료 알림 생성 실패. newsletterId={}, error={}",
+                saved.getId(),
+                ex.getMessage(),
+                ex);
+          }
+        }
+      });
#!/bin/bash
set -euo pipefail

echo "[1] NotificationService 트랜잭션 경계 확인"
fd -i 'NotificationService*.java' src/main/java
rg -n --type=java -C3 '`@Transactional`|createNotification\s*\(' src/main/java/com/gachi/be/domain/notification

echo "[2] 호출부(NewsletterPipelineService) 경계 확인"
rg -n --type=java -C3 'markCompleted\(|createAnalysisCompletedNotification\(' src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java

예상 결과:

  • createNotification(...)이 기본/REQUIRED 트랜잭션이면, 내부 예외가 rollback-only를 유발할 수 있는지 점검 필요.
  • 위 조건이면 afterCommit(또는 별도 빈의 REQUIRES_NEW)로 완전 분리하는 것이 안전합니다.
🤖 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/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java`
around lines 191 - 199, The current try/catch around
createAnalysisCompletedNotification only prevents exception propagation but
doesn’t guarantee the notification runs after the markCompleted transaction
commits; move the notification out of the transactional commit path so it
executes after commit: after calling markCompleted(saved) (or wherever the
entity is persisted), register a post-commit action (e.g.,
TransactionSynchronizationManager.registerSynchronization with afterCommit) or
invoke a separate NotificationService method annotated with
`@Transactional`(propagation = REQUIRES_NEW) / or publish an event and handle it
in a post-commit listener; ensure you call createAnalysisCompletedNotification
(or the NotificationService.createNotification) from that post-commit context
and remove the in-transaction try/catch in NewsletterPipelineService so failures
in notification won’t mark the main transaction rollback-only.
🤖 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.

Duplicate comments:
In
`@src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java`:
- Around line 191-199: The current try/catch around
createAnalysisCompletedNotification only prevents exception propagation but
doesn’t guarantee the notification runs after the markCompleted transaction
commits; move the notification out of the transactional commit path so it
executes after commit: after calling markCompleted(saved) (or wherever the
entity is persisted), register a post-commit action (e.g.,
TransactionSynchronizationManager.registerSynchronization with afterCommit) or
invoke a separate NotificationService method annotated with
`@Transactional`(propagation = REQUIRES_NEW) / or publish an event and handle it
in a post-commit listener; ensure you call createAnalysisCompletedNotification
(or the NotificationService.createNotification) from that post-commit context
and remove the in-transaction try/catch in NewsletterPipelineService so failures
in notification won’t mark the main transaction rollback-only.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c608c8e3-ea21-4e77-b96e-8f64a5643320

📥 Commits

Reviewing files that changed from the base of the PR and between faeb201 and 7c59db2.

📒 Files selected for processing (5)
  • src/main/java/com/gachi/be/domain/auth/service/impl/AuthServiceImpl.java
  • src/main/java/com/gachi/be/domain/checklist/repository/ChecklistRepository.java
  • src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java
  • src/main/java/com/gachi/be/domain/notification/repository/NotificationRepository.java
  • src/main/java/com/gachi/be/domain/notification/service/NotificationScheduler.java

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java`:
- Around line 193-194: markCompleted() (also markProcessing and
markFailedWithSnapshot) is being called directly from runPipeline() in the same
class so the `@Transactional`(propagation = Propagation.REQUIRES_NEW) boundary is
bypassed and the TransactionSynchronization afterCommit registered in
scheduleAnalysisCompletedNotification (lines ~223-235) fires with the outer
runPipeline transaction instead of a new commit; to fix, extract
markCompleted/markProcessing/markFailedWithSnapshot (and their calls to
scheduleAnalysisCompletedNotification) into a separate `@Service` bean (e.g.,
NewsletterPipelineStatusService), inject that bean into
NewsletterPipelineService and call the methods via the injected proxy so
REQUIRES_NEW takes effect and the afterCommit callbacks trigger on the new
transaction commit.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2bcb4818-0d61-4e79-a005-b3170467b25c

📥 Commits

Reviewing files that changed from the base of the PR and between 7c59db2 and d0d5fd2.

📒 Files selected for processing (1)
  • src/main/java/com/gachi/be/domain/newsletter/pipeline/NewsletterPipelineService.java

@deli-minju deli-minju requested a review from Hminkyung May 27, 2026 06:59
Copy link
Copy Markdown
Collaborator

@Hminkyung Hminkyung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다아ㅏㅏㅏ!! 고생하셨습니당 :)

@deli-minju deli-minju merged commit 6dcc675 into develop May 27, 2026
3 checks passed
@deli-minju deli-minju deleted the feat/#76-notification-settings-auto branch May 27, 2026 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새로운 기능 추가 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 알림 설정 단계/알림함 필터/자동 알림 발송 보강

2 participants