mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 19:26:23 +00:00
- 4개 주요 비즈니스 플로우 외부 시퀀스 다이어그램 작성 * 사용자인증플로우: 회원가입, 로그인, 로그아웃 * 이벤트생성플로우: AI 추천, 이미지 생성, 다중 채널 배포 * 고객참여플로우: 이벤트 참여, 당첨자 추첨 * 성과분석플로우: 실시간 대시보드 조회 - Event-Driven 아키텍처 반영 (Kafka Event Topics + Job Topics) - Resilience 패턴 전면 적용 (Circuit Breaker, Retry, Timeout, Fallback) - Cache-Aside 패턴 적용 (Redis 캐싱) - 논리 아키텍처 및 유저스토리 기반 설계 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
225 lines
7.1 KiB
Plaintext
225 lines
7.1 KiB
Plaintext
@startuml 성과분석플로우_외부시퀀스
|
||
!theme mono
|
||
|
||
title 성과 분석 플로우 - 외부 시퀀스 다이어그램\n(UFR-ANAL-010: 실시간 성과분석 대시보드 조회)
|
||
|
||
actor "소상공인" as User
|
||
participant "Frontend" as FE
|
||
participant "API Gateway" as GW
|
||
participant "Analytics Service" as Analytics
|
||
participant "Redis Cache\n(TTL 5분)" as Redis
|
||
participant "Analytics DB" as AnalyticsDB
|
||
participant "Kafka\n(Event Topics)" as Kafka
|
||
box "외부 시스템" #LightGray
|
||
participant "우리동네TV API" as WooriAPI
|
||
participant "지니TV API" as GenieAPI
|
||
participant "SNS APIs\n(Instagram/Naver/Kakao)" as SNSAPI
|
||
end box
|
||
|
||
== 1. 대시보드 조회 - Cache HIT 시나리오 ==
|
||
|
||
User -> FE: 성과분석 대시보드 접근\n(Bottom Nav "분석" 탭 클릭)
|
||
activate FE
|
||
|
||
FE -> GW: GET /api/events/{id}/analytics\n+ Authorization: Bearer {token}
|
||
activate GW
|
||
|
||
GW -> GW: JWT 토큰 검증
|
||
GW -> Analytics: GET /api/events/{id}/analytics
|
||
activate Analytics
|
||
|
||
Analytics -> Redis: GET analytics:dashboard:{eventId}
|
||
activate Redis
|
||
Redis --> Analytics: **Cache HIT**\n캐시된 대시보드 데이터 반환
|
||
deactivate Redis
|
||
|
||
note right of Analytics
|
||
**Cache-Aside 패턴**
|
||
- TTL: 5분
|
||
- 예상 크기: 5KB
|
||
- 히트율 목표: 95%
|
||
- 응답 시간: 0.5초
|
||
end note
|
||
|
||
Analytics --> GW: 200 OK\n대시보드 데이터 (JSON)
|
||
deactivate Analytics
|
||
|
||
GW --> FE: 200 OK\n대시보드 데이터
|
||
deactivate GW
|
||
|
||
FE -> FE: 대시보드 렌더링\n- 4개 요약 카드\n- 채널별 성과 차트\n- 시간대별 참여 추이
|
||
FE --> User: 실시간 대시보드 표시
|
||
deactivate FE
|
||
|
||
== 2. 대시보드 조회 - Cache MISS 시나리오 ==
|
||
|
||
User -> FE: 대시보드 새로고침\n또는 첫 조회
|
||
activate FE
|
||
|
||
FE -> GW: GET /api/events/{id}/analytics
|
||
activate GW
|
||
|
||
GW -> Analytics: GET /api/events/{id}/analytics
|
||
activate Analytics
|
||
|
||
Analytics -> Redis: GET analytics:dashboard:{eventId}
|
||
activate Redis
|
||
Redis --> Analytics: **Cache MISS**\nnull 반환
|
||
deactivate Redis
|
||
|
||
note right of Analytics
|
||
**데이터 통합 작업 시작**
|
||
- Analytics DB 조회
|
||
- 외부 채널 API 병렬 호출
|
||
- Circuit Breaker 적용
|
||
end note
|
||
|
||
|||
|
||
== 2.1. Analytics DB 조회 (로컬 데이터) ==
|
||
|
||
Analytics -> AnalyticsDB: SELECT event_stats\nWHERE event_id = {id}
|
||
activate AnalyticsDB
|
||
AnalyticsDB --> Analytics: 이벤트 통계\n- 총 참여자 수\n- 예상 ROI\n- 매출 증가율
|
||
deactivate AnalyticsDB
|
||
|
||
|||
|
||
== 2.2. 외부 채널 API 병렬 호출 (Circuit Breaker 적용) ==
|
||
|
||
par 병렬 채널 API 호출
|
||
Analytics -> WooriAPI: GET /stats/{eventId}\n+ API Key\n[Circuit Breaker]
|
||
activate WooriAPI
|
||
|
||
alt Circuit Breaker CLOSED (정상)
|
||
WooriAPI --> Analytics: 200 OK\n- 노출 수: 5,000\n- 조회 수: 1,200
|
||
deactivate WooriAPI
|
||
|
||
note right of Analytics
|
||
**Resilience 패턴**
|
||
- Circuit Breaker: 실패율 50% 초과 시 Open
|
||
- Timeout: 10초
|
||
- Retry: 최대 3회 (지수 백오프)
|
||
- Fallback: 캐시된 이전 데이터 반환
|
||
end note
|
||
|
||
else Circuit Breaker OPEN (장애)
|
||
Analytics -> Analytics: **Fallback 실행**\n캐시된 이전 데이터 사용
|
||
note right of Analytics
|
||
Circuit Breaker OPEN 상태
|
||
- 빠른 실패로 응답 시간 단축
|
||
- 30초 후 Half-Open으로 전환
|
||
end note
|
||
end
|
||
|
||
else
|
||
Analytics -> GenieAPI: GET /campaign/{eventId}/stats\n+ API Key\n[Circuit Breaker]
|
||
activate GenieAPI
|
||
|
||
alt 정상 응답
|
||
GenieAPI --> Analytics: 200 OK\n- 광고 노출 수: 10,000\n- 클릭 수: 500
|
||
deactivate GenieAPI
|
||
else Timeout (10초 초과)
|
||
Analytics -> Analytics: **Timeout 처리**\n기본값 반환 (0)
|
||
note right of Analytics
|
||
Timeout 발생
|
||
- 리소스 점유 방지
|
||
- Fallback으로 기본값 설정
|
||
end note
|
||
end
|
||
|
||
else
|
||
Analytics -> SNSAPI: GET /posts/{eventId}/insights\n+ Access Token\n[Circuit Breaker]
|
||
activate SNSAPI
|
||
|
||
SNSAPI --> Analytics: 200 OK\n- Instagram: 좋아요 300, 댓글 50\n- Naver: 조회 수 2,000\n- Kakao: 공유 수 100
|
||
deactivate SNSAPI
|
||
end
|
||
|
||
|||
|
||
== 2.3. 데이터 통합 및 ROI 계산 ==
|
||
|
||
Analytics -> Analytics: 데이터 통합 및 계산\n- 총 노출 수 = 외부 채널 노출 합계\n- 총 참여자 수 = Analytics DB\n- ROI 계산 = (수익 - 비용) / 비용 × 100\n- 채널별 전환율 계산
|
||
|
||
note right of Analytics
|
||
**ROI 계산 로직**
|
||
총 비용 = 경품 비용 + 플랫폼 비용
|
||
예상 수익 = 매출 증가액 + 신규 고객 LTV
|
||
투자 대비 수익률 = (수익 - 비용) / 비용 × 100
|
||
end note
|
||
|
||
|||
|
||
== 2.4. Redis 캐싱 및 응답 ==
|
||
|
||
Analytics -> Redis: SET analytics:dashboard:{eventId}\nvalue={통합 데이터}\nTTL=300초 (5분)
|
||
activate Redis
|
||
Redis --> Analytics: OK
|
||
deactivate Redis
|
||
|
||
Analytics --> GW: 200 OK\n대시보드 데이터 (JSON)\n{\n 총참여자: 1,234,\n 총노출: 17,200,\n ROI: 250%,\n 채널별성과: [...]\n}
|
||
deactivate Analytics
|
||
|
||
GW --> FE: 200 OK\n대시보드 데이터
|
||
deactivate GW
|
||
|
||
FE -> FE: 대시보드 렌더링\n- 4개 요약 카드 표시\n- 채널별 성과 차트\n- 시간대별 참여 추이\n- 참여자 프로필 분석
|
||
FE --> User: 실시간 대시보드 표시\n(응답 시간: 3초)
|
||
deactivate FE
|
||
|
||
|||
|
||
== 3. 실시간 업데이트 (Background Event 구독) ==
|
||
|
||
note over Analytics, Kafka
|
||
**Analytics Service는 항상 Background에서
|
||
Kafka Event Topics를 구독하여
|
||
실시간으로 통계를 업데이트합니다**
|
||
end note
|
||
|
||
Kafka -> Analytics: **EventCreated** 이벤트\n{eventId, storeId, title, objective}
|
||
activate Analytics
|
||
Analytics -> AnalyticsDB: INSERT INTO event_stats\n이벤트 기본 정보 초기화
|
||
activate AnalyticsDB
|
||
AnalyticsDB --> Analytics: OK
|
||
deactivate AnalyticsDB
|
||
Analytics -> Redis: DEL analytics:dashboard:{eventId}\n캐시 무효화
|
||
activate Redis
|
||
Redis --> Analytics: OK
|
||
deactivate Redis
|
||
deactivate Analytics
|
||
|
||
...참여자 등록 시...
|
||
|
||
Kafka -> Analytics: **ParticipantRegistered** 이벤트\n{participantId, eventId, phoneNumber}
|
||
activate Analytics
|
||
Analytics -> AnalyticsDB: UPDATE event_stats\nSET participant_count = participant_count + 1\nWHERE event_id = {eventId}
|
||
activate AnalyticsDB
|
||
AnalyticsDB --> Analytics: OK
|
||
deactivate AnalyticsDB
|
||
Analytics -> Redis: DEL analytics:dashboard:{eventId}\n캐시 무효화 (다음 조회 시 갱신)
|
||
activate Redis
|
||
Redis --> Analytics: OK
|
||
deactivate Redis
|
||
deactivate Analytics
|
||
|
||
...배포 완료 시...
|
||
|
||
Kafka -> Analytics: **DistributionCompleted** 이벤트\n{eventId, distributedChannels, completedAt}
|
||
activate Analytics
|
||
Analytics -> AnalyticsDB: INSERT INTO channel_stats\n배포 채널 통계 저장
|
||
activate AnalyticsDB
|
||
AnalyticsDB --> Analytics: OK
|
||
deactivate AnalyticsDB
|
||
Analytics -> Redis: DEL analytics:dashboard:{eventId}\n캐시 무효화
|
||
activate Redis
|
||
Redis --> Analytics: OK
|
||
deactivate Redis
|
||
deactivate Analytics
|
||
|
||
note right of Analytics
|
||
**실시간 업데이트 메커니즘**
|
||
- EventCreated: 이벤트 기본 정보 초기화
|
||
- ParticipantRegistered: 참여자 수 실시간 증가
|
||
- DistributionCompleted: 배포 채널 통계 업데이트
|
||
- 캐시 무효화: 다음 조회 시 최신 데이터 갱신
|
||
end note
|
||
|
||
@enduml
|