Skip to content

Comments

[FEAT] FCM 푸시 알림 및 이메일 알림 기본 설계 구현#340

Merged
1000hyehyang merged 6 commits intodevfrom
feat/215-notification
Feb 9, 2026
Merged

[FEAT] FCM 푸시 알림 및 이메일 알림 기본 설계 구현#340
1000hyehyang merged 6 commits intodevfrom
feat/215-notification

Conversation

@1000hyehyang
Copy link
Member

Summary

비즈니스 이벤트 기반 알림 시스템을 구현했습니다. 제안 수신, 캠페인 매칭 등 이벤트 발생 시 웹 푸시(FCM) 및 이메일 알림을 발송하고, 알림 페이지 API를 제공합니다. Outbox 패턴을 사용하여 비즈니스 트랜잭션과 완전히 분리되었으며, 재시도 정책과 장애 격리 메커니즘이 포함되어 있습니다.

Changes

도메인 레이어

  • Notification 엔티티: 알림 원장 (읽음 처리, 소프트 삭제 지원)
  • NotificationDelivery 엔티티: 채널별 발송 추적 (PENDING/IN_PROGRESS/SENT/FAILED 상태, 재시도 관리)
  • FcmToken 엔티티: FCM 디바이스 토큰 저장소 (다중 기기 지원, 토큰 재할당)
  • NotificationKind enum: 알림 종류 정의 (PROPOSAL_RECEIVED, CAMPAIGN_MATCHED 등)
  • DeliveryStatus enum: 발송 상태 정의 (PENDING, IN_PROGRESS, SENT, FAILED)

애플리케이션 레이어

  • NotificationService: 알림 생성 및 읽음 처리
  • NotificationQueryService: 알림 목록 조회 (필터링, 날짜별 그룹핑, 페이징)
  • NotificationDeliveryProcessor: 개별 발송 처리 (장애 격리, REQUIRES_NEW 트랜잭션)
  • FcmTokenService: FCM 토큰 등록/삭제 관리
  • NotificationChannelResolver: 알림 종류별 채널 결정 (PUSH/EMAIL)
  • NotificationMessageTemplateService: 알림 메시지 템플릿 생성

인프라스트럭처 레이어

  • NotificationEventListener: 비즈니스 이벤트 구독 및 알림 생성 (@TransactionalEventListener(AFTER_COMMIT))
  • NotificationDeliveryWorker: 비동기 발송 워커 (@Scheduled, 30초마다 실행)
  • FcmNotificationSender: FCM 웹 푸시 발송 (Firebase Admin SDK)
  • EmailNotificationSender: 이메일 발송 (Spring Mail, HTML 템플릿)
  • FirebaseConfig: Firebase Admin SDK 초기화 (선택적, 파일 없어도 동작)

프레젠테이션 레이어

  • NotificationController: 알림 목록 조회, 읽음 처리 API
  • FcmTokenController: FCM 토큰 등록/삭제 API
  • NotificationSwagger: API 문서화 인터페이스
  • FcmTokenSwagger: FCM 토큰 API 문서화 인터페이스

이벤트 정의 (데모데이 이후용)

  • CampaignCompletedEvent: 캠페인 완료 이벤트 (리스너만 정의, 발행은 추후)
  • SettlementReadyEvent: 정산 준비 이벤트 (리스너만 정의, 발행은 추후)
  • AutoConfirmedEvent: 자동 확정 이벤트 (리스너만 정의, 발행은 추후)

설정 파일

  • application.yml: 로컬 개발용 기본값 설정 (FCM, SMTP)
  • application-dev.yml: dev 환경 설정 (환경변수 참조)
  • application-prod.yml: prod 환경 설정 (환경변수 참조)
  • .gitignore: Firebase 키 파일 제외 설정

Type of Change

  • Bug fix (기존 기능에 영향을 주지 않는 버그 수정)
  • New feature (기존 기능에 영향을 주지 않는 새로운 기능 추가)
  • Breaking change (기존 기능에 영향을 주는 수정)
  • Refactoring (기능 변경 없는 코드 개선)
  • Documentation (문서 수정)
  • Chore (빌드, 설정 등 기타 변경)
  • Release (develop → main 배포)

Related Issues

Closes #218
Closes #219

참고 사항

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @1000hyehyang, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 RealMatch 플랫폼에 포괄적인 알림 시스템을 도입합니다. 제안 수신, 캠페인 매칭과 같은 다양한 비즈니스 이벤트에 대해 사용자에게 웹 푸시(FCM) 및 이메일 알림을 보낼 수 있는 기능을 제공합니다. 시스템은 Outbox 패턴을 활용하여 핵심 비즈니스 로직과 알림 발송을 분리하고, 실패 시 재시도 메커니즘과 개별 발송 건에 대한 장애 격리를 통해 높은 신뢰성을 보장하도록 설계되었습니다. 또한, 사용자별 FCM 토큰 관리 API와 알림 목록 조회 API를 포함하여 알림 기능의 완전한 생명주기를 지원합니다.

Highlights

  • FCM 및 이메일 알림 시스템 도입: 비즈니스 이벤트 기반으로 웹 푸시(FCM) 및 이메일 알림을 발송하는 시스템을 구현했습니다.
  • Outbox 패턴 적용: 알림 발송 로직을 비즈니스 트랜잭션과 완전히 분리하여 데이터 일관성을 보장합니다.
  • 견고한 발송 메커니즘: 재시도 정책(exponential backoff)과 장애 격리(REQUIRES_NEW 트랜잭션)를 통해 안정적인 알림 전달을 목표로 합니다.
  • FCM 토큰 관리 API: 사용자별 다중 디바이스 FCM 토큰 등록 및 삭제 기능을 제공합니다.
  • 알림 페이지 API 제공: 사용자 알림 목록 조회 및 읽음 처리 기능을 위한 API를 추가했습니다.
  • 확장 가능한 이벤트 리스너: CampaignCompletedEvent, SettlementReadyEvent, AutoConfirmedEvent 등 향후 비즈니스 이벤트에 대한 알림 리스너를 미리 정의했습니다.
Changelog
  • .gitignore
    • Firebase 서비스 계정 키 파일(firebase-service-account.json)을 Git 추적에서 제외하도록 추가했습니다.
  • build.gradle
    • Spring Mail 및 Firebase Admin SDK 의존성을 추가하여 이메일 발송과 FCM 푸시 알림 기능을 활성화했습니다.
  • docker-compose.yaml
    • Docker 컨테이너 내에서 Firebase 서비스 계정 키 파일을 사용할 수 있도록 볼륨 마운트 설정을 추가했습니다.
  • src/main/java/com/example/RealMatch/business/application/event/AutoConfirmedEvent.java
    • 캠페인 자동 확정 이벤트를 나타내는 레코드 클래스를 추가했습니다.
  • src/main/java/com/example/RealMatch/business/application/event/CampaignCompletedEvent.java
    • 캠페인 완료 이벤트를 나타내는 레코드 클래스를 추가했습니다.
  • src/main/java/com/example/RealMatch/business/application/event/SettlementReadyEvent.java
    • 정산 준비 이벤트를 나타내는 레코드 클래스를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/application/event/NotificationEventListener.java
    • CampaignCompletedEvent, SettlementReadyEvent, AutoConfirmedEvent에 대한 알림 생성 리스너를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/application/service/FcmTokenService.java
    • FCM 토큰을 등록, 삭제, 재할당하는 비즈니스 로직을 처리하는 서비스를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/application/service/NotificationDeliveryProcessor.java
    • 개별 알림 발송 건을 독립적인 트랜잭션으로 처리하고 장애를 격리하는 프로세서 서비스를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/entity/FcmToken.java
    • 사용자별 FCM 디바이스 토큰 정보를 저장하는 엔티티를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/entity/NotificationDelivery.java
    • 알림 발송 상태 추적 엔티티에 재시도 횟수, 다음 재시도 시간(nextRetryAt) 필드를 추가하고, 발송 성공/실패 및 재시도 로직을 업데이트했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/repository/FcmTokenRepository.java
    • FcmToken 엔티티를 위한 JPA 리포지토리를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/domain/repository/NotificationDeliveryRepository.java
    • 재시도 가능한 알림 발송 건을 조회하고, 지연된(stuck) 발송 건을 복구하는 쿼리 메서드를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/exception/NotificationErrorCode.java
    • FCM 토큰, 이메일 발송, 알림 배달 처리 실패와 관련된 새로운 에러 코드를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/config/FirebaseConfig.java
    • Firebase Admin SDK를 초기화하고 FCM 기능을 활성화/비활성화하는 설정을 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/sender/EmailNotificationSender.java
    • Spring Mail을 사용하여 이메일 알림을 발송하는 구현체를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/sender/FcmNotificationSender.java
    • Firebase Admin SDK를 사용하여 FCM 푸시 알림을 발송하는 구현체를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/sender/NotificationChannelSender.java
    • 다양한 알림 채널(FCM, Email)에 대한 발송 로직을 추상화하는 인터페이스를 정의했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/sender/PermanentSendFailureException.java
    • 재시도 불가능한 영구 발송 실패를 나타내는 커스텀 예외를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/infrastructure/worker/NotificationDeliveryWorker.java
    • 주기적으로 대기 중인 알림 발송 건을 처리하고, 실패한 건에 대해 재시도 및 지연된 건 복구 로직을 수행하는 스케줄러 워커를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/presentation/controller/FcmTokenController.java
    • FCM 토큰 등록 및 삭제를 위한 REST API 엔드포인트를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/presentation/dto/request/FcmTokenRegisterRequest.java
    • FCM 토큰 등록 요청을 위한 DTO를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/presentation/dto/request/FcmTokenRemoveRequest.java
    • FCM 토큰 삭제 요청을 위한 DTO를 추가했습니다.
  • src/main/java/com/example/RealMatch/notification/presentation/swagger/FcmTokenSwagger.java
    • FCM 토큰 관련 API의 Swagger 문서화를 위한 인터페이스를 추가했습니다.
  • src/main/resources/application-dev.yml
    • 개발 환경에서 이메일(SMTP) 및 FCM(Firebase) 설정을 위한 속성을 추가했습니다.
  • src/main/resources/application-prod.yml
    • 운영 환경에서 이메일(SMTP) 및 FCM(Firebase) 설정을 위한 속성을 추가했습니다.
Activity
  • 이 PR은 새로운 기능 구현을 위해 초기 설계 및 개발이 진행되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이 PR은 이벤트 기반 알림 시스템의 기본 설계를 훌륭하게 구현했습니다. Outbox 패턴, 재시도 정책, 장애 격리 등 안정적인 시스템을 위한 주요 요소들이 잘 고려되었습니다. 특히 NotificationDeliveryProcessorNotificationDeliveryWorker의 설계는 매우 견고해 보입니다. 잠재적 버그 수정과 관련하여 한 가지 개선점을 제안드렸으며, 코드 중복 제거에 대한 리팩토링 제안은 향후 과제로 고려해 볼 수 있습니다.

@1000hyehyang
Copy link
Member Author

/gemini review @gemini-code-assist 잼민아 코드리뷰 해줘. 심각한 장애나 기능 구현에 문제가 생길만한 지점을 짚어줘.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이 PR은 비즈니스 이벤트에 기반한 알림 시스템의 기본 설계를 구현하며, Outbox 패턴을 사용하여 비즈니스 로직과 알림 발송을 분리하고 FCM 웹 푸시와 이메일 두 가지 채널을 지원합니다. 재시도 정책, 장애 격리, 비정상 종료된 워커 복구 로직 등 시스템 안정성을 높이기 위한 고민이 돋보이며, 확장 가능하고 견고한 알림 시스템의 좋은 기반을 마련한 것으로 보입니다. 하지만, 이메일 발신자에서 출력 이스케이프 부족으로 인한 HTML Injection 취약점이 발견되었습니다. 잠재적인 피싱/추적을 방지하기 위해 이 문제를 해결해야 합니다. 또한, 코드 중복 개선 및 가독성 향상에 대한 몇 가지 제안이 있으며, 이 중 일부는 향후 리팩토링 과제로 고려될 수 있습니다.

@1000hyehyang 1000hyehyang merged commit 36dfa92 into dev Feb 9, 2026
1 check passed
@1000hyehyang 1000hyehyang deleted the feat/215-notification branch February 9, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 이메일 알림 [FEAT] 푸시 알림 (FCM Web)

1 participant