@startuml
!theme mono

title Notification Service - 리마인더발송 내부 시퀀스

participant "SchedulerJob" as Scheduler
participant "ReminderService" as Service
participant "EmailTemplateService" as TemplateService
participant "NotificationRepository" as Repository
participant "EmailClient" as EmailClient
database "Notification DB" as DB
participant "Email Service<<E>>" as EmailService

== 스케줄링된 작업 실행 (회의 시작 30분 전) ==

Scheduler -> Scheduler: 30분 전 알림 대상 회의 조회
activate Scheduler
note right
  조회 조건:
  - 회의 시작 시간 - 30분 = NOW
  - 회의 상태 = 예약됨
  - 리마인더 미발송
end note

Scheduler -> Service: sendMeetingReminders(meetingList)
activate Service

loop 각 회의별
    Service -> Repository: checkReminderSent(meetingId)
    activate Repository

    Repository -> DB: 리마인더 알림 조회\n(회의ID, 유형='REMINDER')
    activate DB
    DB --> Repository: 조회 결과
    deactivate DB

    Repository --> Service: 발송 여부 확인
    deactivate Repository

    alt 이미 발송됨
        Service -> Service: 스킵
    else 미발송

        == 리마인더 알림 생성 ==

        Service -> Repository: createNotification(meetingId, "REMINDER", participants)
        activate Repository

        Repository -> DB: 리마인더 알림 생성\n(알림ID, 회의ID, 유형, 상태, 수신자, 생성일시)
        activate DB
        DB --> Repository: notificationId 반환
        deactivate DB

        Repository --> Service: NotificationEntity 반환
        deactivate Repository

        == 이메일 템플릿 생성 ==

        Service -> TemplateService: generateReminderEmail(meetingData)
        activate TemplateService

        TemplateService -> TemplateService: 템플릿 로드
        note right
          템플릿 정보:
          - 제목: "[리마인더] {회의 제목} - 30분 후 시작"
          - 내용: 회의 정보 + 참여 링크
          - 긴급도: 높음
        end note

        TemplateService -> TemplateService: 데이터 바인딩
        note right
          바인딩 데이터:
          - 회의 제목
          - 시작 시간 (30분 후)
          - 장소
          - 회의 참여 링크
          - 준비 사항 (있는 경우)
        end note

        TemplateService --> Service: EmailContent 반환
        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

                Service -> Repository: updateRecipientStatus(notificationId, recipient, "FAILED")
                activate Repository
                Repository -> DB: 수신자별 알림 상태 업데이트\n(상태='발송실패')
                activate DB
                DB --> Repository: 업데이트 완료
                deactivate DB
                Repository --> Service: 완료
                deactivate Repository

                Service -> Service: 재시도 큐에 추가
            end

            deactivate EmailClient
        end

        == 알림 상태 업데이트 ==

        Service -> Repository: updateNotificationStatus(notificationId, finalStatus)
        activate Repository

        Repository -> DB: 알림 최종 상태 업데이트\n(상태, 완료일시, 발송건수, 실패건수)
        activate DB
        DB --> Repository: 업데이트 완료
        deactivate DB

        Repository --> Service: 완료
        deactivate Repository
    end
end

Service --> Scheduler: 전체 리마인더 발송 완료\n(총 발송 건수, 성공/실패 통계)
deactivate Service

Scheduler -> Scheduler: 다음 스케줄 대기
deactivate Scheduler

note over Scheduler, EmailService
스케줄링 정책:
- 실행 주기: 1분마다
- 대상: 30분 후 시작 회의
- 중복 발송 방지: DB 체크

처리 시간:
- 대상 회의 조회: ~200ms
- 이메일 발송 (per recipient): ~500ms
- 총 처리 시간: 회의 및 참석자 수에 비례
end note

@enduml
