@startuml !theme mono title Notification Service - 초대알림발송 내부 시퀀스 participant "NotificationController" as Controller participant "NotificationService" as Service participant "EmailTemplateService" as TemplateService participant "NotificationRepository" as Repository participant "EmailClient" as EmailClient database "Notification DB" as DB queue "Azure Event Hubs<>" as EventHub participant "Email Service<>" as EmailService == MeetingCreated 이벤트 수신 == EventHub -> Controller: MeetingCreated 이벤트 수신 activate Controller note right 이벤트 데이터: - meetingId - 제목 - 일시 - 장소 - 참석자 목록 (이메일) - 생성자 정보 end note Controller -> Service: sendMeetingInvitation(meetingId, meetingData) activate Service == 알림 기록 생성 == Service -> Repository: createNotification(meetingId, "INVITATION", participants) activate Repository Repository -> DB: INSERT INTO notifications\n(notification_id, meeting_id,\ntype='INVITATION',\nstatus='PENDING',\nrecipients,\ncreated_at) activate DB DB --> Repository: notificationId 반환 deactivate DB Repository --> Service: NotificationEntity 반환 deactivate Repository == 이메일 템플릿 생성 == Service -> TemplateService: generateInvitationEmail(meetingData) activate TemplateService TemplateService -> TemplateService: 템플릿 로드 note right 템플릿 정보: - 제목: "[회의 초대] {회의 제목}" - 내용: 회의 정보 + 참여 링크 - CTA 버튼: "회의 참석하기" end note TemplateService -> TemplateService: 데이터 바인딩 note right 바인딩 데이터: - 회의 제목 - 날짜/시간 - 장소 - 생성자 이름 - 회의 참여 링크 - 캘린더 추가 링크 end note TemplateService --> Service: EmailContent 반환\n(subject, htmlBody, plainTextBody) deactivate TemplateService == 참석자별 이메일 발송 (병렬 처리) == loop 각 참석자별 Service -> EmailClient: sendEmail(recipient, emailContent) activate EmailClient EmailClient -> EmailService: SMTP 이메일 발송 activate EmailService EmailService --> EmailClient: 발송 결과 deactivate EmailService alt 발송 성공 EmailClient --> Service: SUCCESS Service -> Repository: updateRecipientStatus(notificationId, recipient, "SENT") activate Repository Repository -> DB: UPDATE notification_recipients\nSET status='SENT', sent_at=NOW()\nWHERE notification_id='{notificationId}'\nAND recipient='{email}' activate DB DB --> Repository: 업데이트 완료 deactivate DB Repository --> Service: 완료 deactivate Repository else 발송 실패 EmailClient --> Service: FAILED (errorMessage) Service -> Repository: updateRecipientStatus(notificationId, recipient, "FAILED") activate Repository Repository -> DB: UPDATE notification_recipients\nSET status='FAILED',\nerror_message='{errorMessage}'\nWHERE notification_id='{notificationId}'\nAND recipient='{email}' activate DB DB --> Repository: 업데이트 완료 deactivate DB Repository --> Service: 완료 deactivate Repository Service -> Service: 재시도 큐에 추가\n(최대 3회 재시도) end deactivate EmailClient end == 전체 알림 상태 업데이트 == Service -> Repository: updateNotificationStatus(notificationId, finalStatus) activate Repository Repository -> DB: UPDATE notifications\nSET status='{finalStatus}',\ncompleted_at=NOW(),\nsent_count={sentCount},\nfailed_count={failedCount}\nWHERE notification_id='{notificationId}' activate DB DB --> Repository: 업데이트 완료 deactivate DB Repository --> Service: 완료 deactivate Repository Service --> Controller: NotificationResponse\n(notificationId, status, sentCount, failedCount) deactivate Service Controller --> EventHub: InvitationSent 이벤트 발행\n(meetingId, notificationId, status) deactivate Controller note over Controller, EmailService 처리 시간: - 알림 기록 생성: ~100ms - 템플릿 생성: ~200ms - 이메일 발송 (per recipient): ~500ms - 총 처리 시간: 참석자 수에 비례 (병렬 처리) 재시도 정책: - 최대 3회 재시도 - 재시도 간격: 5분, 15분, 30분 end note @enduml