hgzero/design/backend/sequence/inner/notification-알림발송.puml
ondal 715add4dbc 외부/내부 시퀀스 설계 일관성 개선 및 표준화
주요 변경사항:

[Critical]
- API 엔드포인트 통일: POST /api/minutes/{minutesId}/finalize
- 이벤트 이름 표준화: MinutesFinalized

[Warning]
- API Gateway 라우팅 규칙 문서화 (외부 시퀀스 7개 파일)
- 대시보드 API 경로 통일: GET /api/dashboard
- AI 제안 병합 프로세스 상세 문서화
- 회의록 확정 검증 로직 5단계 상세화

[Minor]
- Redis 캐시 TTL 명시 (7개 파일, TTL 정책 표준화)
- 대시보드 페이지네이션 파라미터 추가
- 에러 응답 포맷 표준화 (14개 에러 응답)

총 31개 파일 수정, 34건의 개선 사항 적용

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 09:48:06 +09:00

169 lines
4.7 KiB
Plaintext

@startuml
!theme mono
title 알림 발송 내부 시퀀스 (Event-Driven)
queue "Event Hub<<E>>" as EventHub
participant "NotificationListener" as Listener
participant "NotificationService" as Service
participant "NotificationRouter" as Router
participant "EmailNotifier" as EmailNotifier
participant "Email Service<<E>>" as Email
participant "NotificationRepository" as Repository
database "PostgreSQL<<E>>" as DB
EventHub -> Listener: consume(NotificationEvent)
activate Listener
note right
Event 종류:
- MeetingCreatedEvent
- TodoAssignedEvent
- MeetingReminderEvent
- SummaryCompletedEvent
end note
Listener -> Service: processNotification(event)
activate Service
Service -> Repository: checkDuplicateNotification(eventId)
activate Repository
Repository -> DB: 알림 중복 확인 조회\n(이벤트ID 기준)
note right
중복 발송 방지:
- Event ID 기반
- Idempotency 보장
end note
alt 중복 이벤트
DB --> Repository: notification exists
Repository --> Service: duplicate
Service --> Listener: skip (already processed)
deactivate Service
Listener --> EventHub: ACK
deactivate Listener
else 신규 이벤트
DB --> Repository: not found
Repository --> Service: proceed
deactivate Repository
Service -> Service: parseEventPayload(event)
note right
이벤트 파싱:
- userId
- notificationType
- templateId
- templateData
end note
Service -> Repository: getUserPreferences(userId)
activate Repository
Repository -> DB: 사용자 알림 설정 조회\n(사용자ID 기준)
note right
사용자 설정 확인:
- 알림 채널 (email/sms)
- 알림 활성화 여부
- 수신 시간대
end note
DB --> Repository: preferences
Repository --> Service: NotificationPreference
deactivate Repository
alt 알림 비활성화
Service --> Listener: skip (user preference)
deactivate Service
Listener --> EventHub: ACK
deactivate Listener
else 알림 활성화
Service -> Router: routeNotification(event, preferences)
activate Router
Router -> Router: determineChannel(preferences)
note right
채널 선택:
- 이메일 우선
- SMS 백업
end note
alt 이메일 알림
Router -> EmailNotifier: sendEmail(notification)
activate EmailNotifier
EmailNotifier -> EmailNotifier: loadTemplate(templateId)
note right
템플릿 로드:
- 회의 초대
- 할일 배정
- 회의 알림
- 요약 완료
end note
EmailNotifier -> EmailNotifier: renderTemplate(templateData)
note right
템플릿 렌더링:
- 제목 생성
- 본문 생성
- 다이나믹 데이터 삽입
end note
EmailNotifier -> Email: send(to, subject, body)
note right
이메일 발송:
- SMTP 프로토콜
- 재시도 로직
- Timeout: 10s
end note
alt 발송 성공
Email --> EmailNotifier: success
EmailNotifier --> Router: sent
deactivate EmailNotifier
else 발송 실패
Email --> EmailNotifier: failure
EmailNotifier -> EmailNotifier: scheduleRetry()
note right
재시도 전략:
- Max retry: 3
- Backoff: exponential
- 1m, 5m, 15m
end note
EmailNotifier --> Router: retry scheduled
deactivate EmailNotifier
end
end
Router --> Service: notification result
deactivate Router
Service -> Repository: saveNotificationLog(notification)
activate Repository
Repository -> DB: 알림 이력 저장\n(이벤트ID, 사용자ID, 유형, 채널, 상태, 발송일시)
note right
알림 로그 저장:
- 발송 이력
- 채널 정보
- 성공/실패 상태
end note
DB --> Repository: saved
Repository --> Service: saved
deactivate Repository
Service -> Repository: updateUserActivity(userId, "NOTIFICATION_SENT")
activate Repository
Repository -> DB: 사용자 활동 이력 저장\n(사용자ID, 활동유형, 상세내용)
DB --> Repository: saved
Repository --> Service: updated
deactivate Repository
Service --> Listener: processed
deactivate Service
Listener --> EventHub: ACK
deactivate Listener
end
end
@enduml