mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 22:46:24 +00:00
170 lines
6.5 KiB
Plaintext
170 lines
6.5 KiB
Plaintext
@startuml distribution-배포상태조회
|
|
!theme mono
|
|
|
|
title Distribution Service - 배포 상태 조회 (UFR-DIST-020)
|
|
|
|
actor "소상공인" as User
|
|
participant "Frontend" as FE
|
|
participant "API Gateway" as Gateway
|
|
participant "Distribution\nREST API" as API
|
|
participant "Distribution\nController" as Controller
|
|
participant "Distribution\nService" as Service
|
|
participant "Redis Cache" as Cache
|
|
database "Event DB" as DB
|
|
participant "Circuit Breaker\nManager" as CB
|
|
|
|
== 배포 상태 조회 요청 ==
|
|
User -> FE: 이벤트 상세 화면\n배포 상태 섹션 확인
|
|
activate FE
|
|
|
|
FE -> Gateway: GET /api/distribution/{eventId}/status
|
|
activate Gateway
|
|
|
|
Gateway -> Gateway: JWT 토큰 검증
|
|
Gateway -> API: GET /distribution/{eventId}/status
|
|
activate API
|
|
|
|
API -> Controller: getDistributionStatus(eventId)
|
|
activate Controller
|
|
|
|
Controller -> Service: fetchDistributionStatus(eventId)
|
|
activate Service
|
|
|
|
== Cache-Aside 패턴 적용 ==
|
|
Service -> Cache: 캐시 조회\nkey: distribution:{eventId}
|
|
activate Cache
|
|
|
|
alt 캐시 HIT
|
|
Cache --> Service: 캐시된 배포 상태\n{status, results[], cachedAt}
|
|
deactivate Cache
|
|
|
|
note over Service: 캐시 TTL: 1시간\n빠른 응답 (0.1초)
|
|
|
|
Service --> Controller: DistributionStatus\n{eventId, status, channelResults[]}
|
|
deactivate Service
|
|
|
|
else 캐시 MISS
|
|
Cache --> Service: null (캐시 없음)
|
|
deactivate Cache
|
|
|
|
== 데이터베이스에서 배포 이력 조회 ==
|
|
Service -> DB: SELECT * FROM distribution_logs\nWHERE event_id = :eventId\nORDER BY created_at DESC\nLIMIT 1
|
|
activate DB
|
|
|
|
alt 배포 이력 존재
|
|
DB --> Service: DistributionLog\n{id, eventId, status, createdAt, completedAt}
|
|
deactivate DB
|
|
|
|
Service -> DB: SELECT * FROM distribution_channel_logs\nWHERE distribution_log_id = :logId
|
|
activate DB
|
|
DB --> Service: List<ChannelLog>\n{channel, status, distributionId, postUrl, retries, error}
|
|
deactivate DB
|
|
|
|
== 실시간 채널 상태 확인 (선택적) ==
|
|
note over Service: 진행중(IN_PROGRESS) 상태일 때만\n외부 API로 실시간 상태 확인
|
|
|
|
alt 배포 진행중 (IN_PROGRESS)
|
|
loop 각 채널별 상태 확인
|
|
Service -> CB: checkCircuitBreaker(channel)
|
|
alt Circuit Breaker CLOSED
|
|
CB --> Service: 요청 허용
|
|
|
|
alt 우리동네TV
|
|
Service -> DB: SELECT distribution_id FROM distribution_channel_logs\nWHERE channel = 'WooridongneTV'
|
|
DB --> Service: distributionId
|
|
|
|
note over Service: Timeout: 5초\nCircuit Breaker 적용
|
|
Service -> "외부 APIs": GET /api/status/{distributionId}
|
|
activate "외부 APIs"
|
|
|
|
alt 성공
|
|
"외부 APIs" --> Service: 200 OK\n{status: COMPLETED, views: 1500}
|
|
deactivate "외부 APIs"
|
|
Service -> DB: UPDATE distribution_channel_logs\nSET status = 'COMPLETED', views = 1500
|
|
else 실패 (Timeout/Error)
|
|
"외부 APIs" --> Service: 500 Error or Timeout
|
|
deactivate "외부 APIs"
|
|
Service -> CB: recordFailure(channel)
|
|
note over Service: Circuit Breaker 실패율 증가\n50% 초과 시 Circuit Open
|
|
end
|
|
end
|
|
|
|
note over Service: 다른 채널(링고비즈, 지니TV, SNS)도\n동일한 패턴으로 상태 확인
|
|
|
|
else Circuit Breaker OPEN
|
|
CB --> Service: 서킷 오픈 상태\n(외부 API 호출 스킵)
|
|
note over Service: Fallback: DB 저장 상태 사용\n30초 후 Half-Open 전환
|
|
end
|
|
end
|
|
|
|
== 배포 완료 여부 판단 ==
|
|
Service -> Service: 모든 채널 상태 확인\n완료/실패 여부 판단
|
|
|
|
alt 모든 채널 완료
|
|
Service -> DB: UPDATE distribution_logs\nSET status = 'COMPLETED', completed_at = NOW()
|
|
else 일부 실패
|
|
Service -> DB: UPDATE distribution_logs\nSET status = 'PARTIAL_FAILURE'
|
|
end
|
|
end
|
|
|
|
== 배포 상태 응답 준비 ==
|
|
Service -> Service: 채널별 상태 집계\n{channel, status, distributionId, postUrl, views, error}
|
|
|
|
Service -> Cache: 배포 상태 캐싱\nkey: distribution:{eventId}\nvalue: {status, results[]}\nTTL: 1시간
|
|
|
|
Service --> Controller: DistributionStatus\n{eventId, status, channelResults[]}
|
|
deactivate Service
|
|
|
|
else 배포 이력 없음
|
|
DB --> Service: null
|
|
deactivate DB
|
|
|
|
Service --> Controller: DistributionStatus\n{eventId, status: NOT_FOUND}
|
|
deactivate Service
|
|
end
|
|
end
|
|
|
|
== 응답 반환 ==
|
|
Controller --> API: DistributionStatusResponse\n{eventId, status, channelResults[]}
|
|
deactivate Controller
|
|
|
|
API --> Gateway: 200 OK\n{eventId, overallStatus, channels[]}
|
|
deactivate API
|
|
|
|
Gateway --> FE: 배포 상태 응답\n{overallStatus, channels[]}
|
|
deactivate Gateway
|
|
|
|
== 프론트엔드 화면 표시 ==
|
|
FE -> FE: 채널별 상태 표시\n- 대기중: 회색\n- 진행중: 파란색\n- 완료: 초록색\n- 실패: 빨간색
|
|
FE --> User: 배포 상태 시각화\n채널별 세부 정보 표시
|
|
deactivate FE
|
|
|
|
note over User: 배포 상태 정보\n- 우리동네TV: 완료 (배포ID, 조회수)\n- 링고비즈: 완료 (업데이트 시각)\n- 지니TV: 완료 (광고ID, 스케줄)\n- SNS: 완료 (포스팅 URL)
|
|
|
|
== 재시도 기능 (실패한 채널) ==
|
|
alt 실패한 채널 존재
|
|
User -> FE: "재시도" 버튼 클릭
|
|
FE -> Gateway: POST /api/distribution/{eventId}/retry\n{channels: [failed_channel_list]}
|
|
Gateway -> API: 재시도 요청
|
|
API -> Controller: retryDistribution(eventId, channels)
|
|
Controller -> Service: retryFailedChannels(eventId, channels)
|
|
activate Service
|
|
|
|
note over Service: 실패한 채널만\n다시 배포 시도\n(동일한 Circuit Breaker/Retry 적용)
|
|
|
|
Service -> DB: 새로운 배포 시도 로그 생성
|
|
Service -> Cache: 캐시 무효화
|
|
Service --> Controller: 재시도 완료\n{retryStatus}
|
|
deactivate Service
|
|
|
|
Controller --> API: RetryResponse
|
|
API --> Gateway: 200 OK
|
|
Gateway --> FE: 재시도 결과
|
|
FE --> User: "재시도가 완료되었습니다"
|
|
end
|
|
|
|
== 실시간 업데이트 (선택적) ==
|
|
note over FE: Frontend는 5초마다\nPolling 또는 WebSocket으로\n배포 상태 자동 갱신\n(Phase 2에서 WebSocket 적용 가능)
|
|
|
|
@enduml
|