[Feat] 신규 프로젝트 신청·승인·거절·생성시 알림 전송 #112

🔗 관련 이슈

#112 (closed)

💡 작업 내용

Bug Report

https://git.ajou.ac.kr/aolda/cloud-console-backend/-/issues?show=eyJpaWQiOiIxMjkiLCJmdWxsX3BhdGgiOiJhb2xkYS9jbG91ZC1jb25zb2xlLWJhY2tlbmQiLCJpZCI6MTUzOX0%3D

해당 issue와 같이 프로젝트 신청시 email이 null이 되는 문제가 있어 테스트는 email을 하드코딩하여 진행했습니다.

작업 내용

신규 프로젝트 신청·승인·거절·생성 시 discord, email 알림을 전송합니다.

  • 아올다 클라우드 사용자가 cloud 리소스를 사용하기 위해, 프로젝트를 신청하고, 이를 승인/거절 시에 비지니스 로직에 이어서 Discord, Email 알림이 전송됩니다.
    1. 신규 프로젝트 신청
    2. 프로젝트 신청 승인
    3. 프로젝트 신청 거절
    4. 실제 프로젝트 생성

Transactional Outbox Pattern 적용

  • 이때, 트랜잭션과 외부 알림이 원자적으로 처리되지 않기 때문에 데이터 불일치 문제가 발생할 수 있습니다.
  • 또한, 서로 다른 비즈니스 로직 간의 강한 결합으로 알림이 추가되면 복잡도와 의존성이 커지는 구조를 개선합니다.
  • 이러한 상황에서 Transaction Outbox 패턴을 통한 이벤트 기반 알림 전송 로직을 작성을 통해 다음과 같은 이점을 얻습니다.
    • 알림 전송과 무관하게 프로젝트 생성 성공
    • 빠른 API 응답 (알림을 기다리지 않음)
    • 알림 전송 실패 시 자동 재시도
    • 외부 서비스(Email/Discord) 장애가 프로젝트 생성에 영향을 주지 않음
    • ShedLock을 통해 중복 처리 방지
  • 메시지 유실을 방지하며, 중복 전송은 허용하는 “At-Least-Once” 전달을 보장합니다.

처리 flow

  1. 프로젝트 요청/승인/거부/생성 시 이벤트 발행
  2. EventListener가 비즈니스 로직과 별개의 트랜잭션 내에서 알림 메시지를 Outbox 테이블에 저장
  3. 트랜잭션 커밋 이후 별도의 스케줄러(Polling Publisher)가 Outbox를 읽어 알림 발행
  4. 메시지가 정상 발행된 기록을 flagging
  5. 하루 주기로 Batch 삭제

Event 기반 구조로 의존성 완화

  • Spring의 ApplicationEventPublisher 와 @TransactionalEventListener 사용
  • ProjectServiceAdapter 는 단순히 도메인 이벤트만 발행

📚 참고 자료

블로깅

Transaction Outbox 패턴을 통한 이벤트 기반 알림 전송

API 테스트

discord email email email email
image image image image image

Merge request reports

Loading