@startuml event-최종승인및배포
!theme mono

title Event Service - 최종 승인 및 Distribution Service 동기 호출 (UFR-EVENT-050)

actor Client
participant "API Gateway" as Gateway
participant "EventController" as Controller <<API Layer>>
participant "EventService" as Service <<Business Layer>>
participant "EventRepository" as Repo <<Data Layer>>
participant "Redis Cache" as Cache <<E>>
database "Event DB" as DB <<E>>
participant "Distribution Service" as DistSvc <<E>>
participant "Kafka Producer" as Kafka <<E>>

note over Controller, Kafka
**UFR-EVENT-050: 이벤트 최종 승인 및 배포**
- 이벤트 준비 상태 검증
- 이벤트 승인 및 Kafka 이벤트 발행
- Distribution Service 동기 호출 (다중 채널 배포)
- 이벤트 상태를 ACTIVE로 변경
end note

Client -> Gateway: POST /api/events/{eventDraftId}/publish\n{"userId": 123,\n"selectedChannels": [\n  "우리동네TV",\n  "지니TV",\n  "Instagram"\n]}
activate Gateway

Gateway -> Controller: POST /api/events/{eventDraftId}/publish
activate Controller

Controller -> Controller: 요청 검증\n(필수 필드, 채널 유효성)

Controller -> Service: publishEvent(eventDraftId, userId, selectedChannels)
activate Service

== 1단계: 이벤트 초안 조회 및 검증 ==

Service -> Repo: findById(eventDraftId)
activate Repo
Repo -> DB: 이벤트 초안 조회\n(초안ID로 조회)
activate DB
DB --> Repo: EventDraft 엔티티\n{목적, 추천안, 콘텐츠, 상태}
deactivate DB
Repo --> Service: EventDraft entity
deactivate Repo

Service -> Service: validateOwnership(userId, eventDraft)
note right
소유권 검증:
- 사용자ID와 초안 소유자 일치 확인
- 권한 없으면 403 Forbidden
end note

Service -> Service: validatePublishReady()
note right
발행 준비 검증:
- 목적 선택 완료
- AI 추천 선택 완료
- 콘텐츠 선택 완료
- 배포 채널 최소 1개 선택
end note

== 2단계: 이벤트 승인 ==

Service -> Repo: updateStatus(eventDraftId, APPROVED)
activate Repo
Repo -> DB: 이벤트 초안 상태 업데이트\n(상태를 APPROVED로,\n승인일시를 현재 시각으로 저장)
activate DB
DB --> Repo: 업데이트 완료
deactivate DB
Repo --> Service: EventDraft entity
deactivate Repo

== 3단계: Kafka 이벤트 발행 ==

Service -> Kafka: 이벤트 발행\nTopic: event-topic\nPayload: {eventId, userId, title,\nobjective, createdAt}
activate Kafka
note right
Kafka Event Topic:
- Topic: event-topic
- Consumer: Analytics Service
- Event Type: EventCreated
end note
Kafka --> Service: ACK (발행 확인)
deactivate Kafka

== 4단계: Distribution Service 동기 호출 ==

Service -> DistSvc: POST /api/distribution/distribute\n{"eventId": 123,\n"channels": [...],\n"content": {...}}
activate DistSvc
note right
동기 호출 (Circuit Breaker 적용):
- Timeout: 70초
- 다중 채널 병렬 배포
- Failure Rate: 50% 초과 시 OPEN
end note

DistSvc -> DistSvc: distributeToChannels(eventId, channels)
note right
다중 채널 병렬 배포:
- 우리동네TV
- 링고비즈 (음성 안내)
- 지니TV
- Instagram
- Naver Blog
- Kakao Channel
end note

DistSvc --> Service: DistributionResponse\n{"distributionId": "dist-123",\n"channelResults": [\n  {"channel": "우리동네TV", "status": "SUCCESS"},\n  {"channel": "지니TV", "status": "SUCCESS"},\n  {"channel": "Instagram", "status": "SUCCESS"}\n]}
deactivate DistSvc

== 5단계: 이벤트 활성화 ==

Service -> Repo: updateStatus(eventDraftId, ACTIVE)
activate Repo
Repo -> DB: 이벤트 상태 업데이트\n(상태를 ACTIVE로,\n배포일시를 현재 시각으로 저장)
activate DB
DB --> Repo: 업데이트 완료
deactivate DB
Repo --> Service: Event entity
deactivate Repo

== 6단계: 캐시 무효화 ==

Service -> Cache: 캐시 삭제\nKey: draft:event:{eventDraftId}
activate Cache
note right
Redis 캐시 무효화:
- 이벤트 초안 캐시 삭제
- 활성화 완료 후 불필요
end note
Cache --> Service: 삭제 완료
deactivate Cache

== 7단계: 응답 반환 ==

Service --> Controller: PublishResponse\n{eventId, status: ACTIVE,\ndistributionResults}
deactivate Service

Controller --> Gateway: 200 OK\n{"eventId": 123,\n"status": "ACTIVE",\n"distributionResults": [...]}
deactivate Controller

Gateway --> Client: 200 OK\n이벤트 배포 완료
deactivate Gateway

note over Client, Kafka
**배포 완료 후 처리**
- Distribution Service는 배포 완료 후 Kafka에\n  DistributionCompleted 이벤트 발행
- Analytics Service가 구독하여 초기 통계 생성
- 이벤트 상태: ACTIVE (참여자 접수 시작)

**성능 목표**
- 응답 시간: 60초 이내 (Distribution Service 포함)
- Distribution Service 타임아웃: 70초
- 채널별 배포: 병렬 처리로 최적화
end note

@enduml
