@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<<E>>" as EventHub
participant "Email Service<<E>>" 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: 초대 알림 생성\n(알림ID, 회의ID, 유형, 상태, 수신자, 생성일시)
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: 수신자별 알림 상태 업데이트\n(상태='발송완료', 발송일시=현재시각)
        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: 수신자별 알림 상태 업데이트\n(상태='발송실패', 오류메시지=에러내용)
        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: 알림 최종 상태 업데이트\n(상태, 완료일시, 발송건수, 실패건수)
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
