kt-event-marketing/design/backend/api/analytics-service-api.yaml
2025-10-28 13:33:00 +09:00

1082 lines
29 KiB
YAML

openapi: 3.0.3
info:
title: Analytics Service API
description: |
실시간 효과 측정 및 통합 대시보드를 제공하는 Analytics Service API
**주요 기능:**
- 이벤트 성과 대시보드 실시간 조회
- 채널별 성과 분석 및 비교
- 시간대별 참여 추이 분석
- 투자 대비 수익률(ROI) 상세 분석
**Kafka Event Subscriptions:**
- EventCreated: 이벤트 통계 초기화
- ParticipantRegistered: 실시간 참여자 수 업데이트
- DistributionCompleted: 배포 통계 업데이트
**External API Integration:**
- 우리동네TV API (조회수)
- 지니TV API (광고 노출 수)
- 링고비즈 API (통화 수, 완료 수, 평균 통화 시간)
- SNS APIs (좋아요, 댓글, 공유 수)
- Circuit Breaker with fallback to cached data
**Caching Strategy:**
- Redis cache with 1-hour TTL (3600 seconds)
- Cache-Aside pattern for dashboard data
- Real-time updates via Kafka event subscription
version: 1.0.0
contact:
name: Digital Garage Team
email: support@kt-event-marketing.com
servers:
- url: http://localhost:8086
description: Local Development Server
- url: https://dev-api.kt-event-marketing.com/analytics/v1
description: Development Server
- url: https://api.kt-event-marketing.com/analytics/v1
description: Production Server
tags:
- name: Analytics
description: 이벤트 성과 분석 및 대시보드 API
- name: Channels
description: 채널별 성과 분석 API
- name: Timeline
description: 시간대별 분석 API
- name: ROI
description: 투자 대비 수익률 분석 API
paths:
/events/{eventId}/analytics:
get:
tags:
- Analytics
summary: 성과 대시보드 조회
description: |
이벤트의 전체 성과를 통합하여 조회합니다.
- 실시간 참여자 수
- 총 도달 수 (조회수, 노출 수)
- 참여율, 전환율
- 투자 대비 수익률 (ROI)
- 채널별 성과 요약
operationId: getEventAnalytics
x-user-story: UFR-ANAL-010
x-controller: AnalyticsDashboardController
parameters:
- name: eventId
in: path
required: true
description: 이벤트 ID
schema:
type: string
example: "evt_2025012301"
- name: startDate
in: query
required: false
description: 조회 시작 날짜 (ISO 8601 format)
schema:
type: string
format: date-time
example: "2025-01-01T00:00:00Z"
- name: endDate
in: query
required: false
description: 조회 종료 날짜 (ISO 8601 format)
schema:
type: string
format: date-time
example: "2025-01-31T23:59:59Z"
- name: refresh
in: query
required: false
description: 캐시 갱신 여부 (true인 경우 외부 API 호출)
schema:
type: boolean
default: false
responses:
'200':
description: 성과 대시보드 조회 성공
content:
application/json:
schema:
$ref: '#/components/schemas/AnalyticsDashboard'
'404':
description: 이벤트를 찾을 수 없음
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: 서버 오류
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/events/{eventId}/analytics/channels:
get:
tags:
- Channels
summary: 채널별 성과 분석
description: |
각 배포 채널별 성과를 상세하게 분석합니다.
- 우리동네TV 조회수
- 지니TV 광고 노출 수
- 링고비즈 통화 수 및 완료율
- SNS 반응 수 (좋아요, 댓글, 공유)
- 채널별 참여율 및 전환율
- 채널별 ROI
operationId: getChannelAnalytics
x-user-story: UFR-ANAL-010
x-controller: ChannelAnalyticsController
parameters:
- name: eventId
in: path
required: true
description: 이벤트 ID
schema:
type: string
example: "evt_2025012301"
- name: channels
in: query
required: false
description: 조회할 채널 목록 (쉼표로 구분, 미지정 시 전체)
schema:
type: string
example: "우리동네TV,지니TV,SNS"
- name: sortBy
in: query
required: false
description: 정렬 기준
schema:
type: string
enum:
- views
- participants
- engagement_rate
- conversion_rate
- roi
default: roi
- name: order
in: query
required: false
description: 정렬 순서
schema:
type: string
enum:
- asc
- desc
default: desc
responses:
'200':
description: 채널별 성과 분석 조회 성공
content:
application/json:
schema:
$ref: '#/components/schemas/ChannelAnalyticsResponse'
'404':
description: 이벤트를 찾을 수 없음
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: 서버 오류
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/events/{eventId}/analytics/timeline:
get:
tags:
- Timeline
summary: 시간대별 참여 추이
description: |
이벤트 기간 동안의 시간대별 참여 추이를 분석합니다.
- 시간대별 참여자 수
- 시간대별 조회수
- 피크 타임 분석
- 추세 분석 (증가/감소)
operationId: getTimelineAnalytics
x-user-story: UFR-ANAL-010
x-controller: TimelineAnalyticsController
parameters:
- name: eventId
in: path
required: true
description: 이벤트 ID
schema:
type: string
example: "evt_2025012301"
- name: interval
in: query
required: false
description: 시간 간격 단위
schema:
type: string
enum:
- hourly
- daily
- weekly
default: daily
- name: startDate
in: query
required: false
description: 조회 시작 날짜 (ISO 8601 format)
schema:
type: string
format: date-time
example: "2025-01-01T00:00:00Z"
- name: endDate
in: query
required: false
description: 조회 종료 날짜 (ISO 8601 format)
schema:
type: string
format: date-time
example: "2025-01-31T23:59:59Z"
- name: metrics
in: query
required: false
description: 조회할 지표 목록 (쉼표로 구분)
schema:
type: string
example: "participants,views,engagement"
responses:
'200':
description: 시간대별 참여 추이 조회 성공
content:
application/json:
schema:
$ref: '#/components/schemas/TimelineAnalyticsResponse'
'404':
description: 이벤트를 찾을 수 없음
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: 서버 오류
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/events/{eventId}/analytics/roi:
get:
tags:
- ROI
summary: 투자 대비 수익률 상세
description: |
이벤트의 투자 대비 수익률을 상세하게 분석합니다.
- 총 투자 비용 (제작비, 배포비, 운영비)
- 예상 매출 증대
- ROI 계산
- 비용 대비 참여자 수 (CPA)
- 비용 대비 전환 수 (CPC)
operationId: getRoiAnalytics
x-user-story: UFR-ANAL-010
x-controller: RoiAnalyticsController
parameters:
- name: eventId
in: path
required: true
description: 이벤트 ID
schema:
type: string
example: "evt_2025012301"
- name: includeProjection
in: query
required: false
description: 예상 수익 포함 여부
schema:
type: boolean
default: true
responses:
'200':
description: ROI 상세 분석 조회 성공
content:
application/json:
schema:
$ref: '#/components/schemas/RoiAnalyticsResponse'
'404':
description: 이벤트를 찾을 수 없음
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: 서버 오류
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
AnalyticsDashboard:
type: object
description: 이벤트 성과 대시보드
properties:
eventId:
type: string
description: 이벤트 ID
example: "evt_2025012301"
eventTitle:
type: string
description: 이벤트 제목
example: "신년맞이 20% 할인 이벤트"
period:
$ref: '#/components/schemas/PeriodInfo'
summary:
$ref: '#/components/schemas/AnalyticsSummary'
channelPerformance:
type: array
description: 채널별 성과 요약
items:
$ref: '#/components/schemas/ChannelSummary'
roi:
$ref: '#/components/schemas/RoiSummary'
lastUpdatedAt:
type: string
format: date-time
description: 마지막 업데이트 시간
example: "2025-01-23T10:30:00Z"
dataSource:
type: string
description: 데이터 출처
enum:
- real-time
- cached
- fallback
example: "cached"
required:
- eventId
- eventTitle
- period
- summary
- lastUpdatedAt
PeriodInfo:
type: object
description: 조회 기간 정보
properties:
startDate:
type: string
format: date-time
example: "2025-01-01T00:00:00Z"
endDate:
type: string
format: date-time
example: "2025-01-31T23:59:59Z"
durationDays:
type: integer
description: 기간 (일)
example: 30
required:
- startDate
- endDate
AnalyticsSummary:
type: object
description: 성과 요약
properties:
totalParticipants:
type: integer
description: 총 참여자 수
example: 15420
totalViews:
type: integer
description: 총 조회수
example: 125300
totalReach:
type: integer
description: 총 도달 수
example: 98500
engagementRate:
type: number
format: double
description: 참여율 (%)
example: 12.3
conversionRate:
type: number
format: double
description: 전환율 (%)
example: 3.8
averageEngagementTime:
type: integer
description: 평균 참여 시간 (초)
example: 145
socialInteractions:
$ref: '#/components/schemas/SocialInteractionStats'
required:
- totalParticipants
- totalViews
- totalReach
- engagementRate
- conversionRate
SocialInteractionStats:
type: object
description: SNS 반응 통계
properties:
likes:
type: integer
description: 좋아요 수
example: 3450
comments:
type: integer
description: 댓글 수
example: 890
shares:
type: integer
description: 공유 수
example: 1250
required:
- likes
- comments
- shares
VoiceCallStats:
type: object
description: 링고비즈 음성 통화 통계
properties:
totalCalls:
type: integer
description: 총 통화 수
example: 3000
completedCalls:
type: integer
description: 완료된 통화 수
example: 2500
averageDuration:
type: integer
description: 평균 통화 시간 (초)
example: 45
completionRate:
type: number
format: double
description: 통화 완료율 (%)
example: 83.3
required:
- totalCalls
- completedCalls
- averageDuration
ChannelSummary:
type: object
description: 채널별 성과 요약
properties:
channelName:
type: string
description: 채널명
example: "우리동네TV"
views:
type: integer
description: 조회수
example: 45000
participants:
type: integer
description: 참여자 수
example: 5500
engagementRate:
type: number
format: double
description: 참여율 (%)
example: 12.2
conversionRate:
type: number
format: double
description: 전환율 (%)
example: 4.1
roi:
type: number
format: double
description: ROI (%)
example: 280.5
required:
- channelName
- views
- participants
RoiSummary:
type: object
description: ROI 요약
properties:
totalInvestment:
type: number
format: double
description: 총 투자 비용 (원)
example: 5000000
expectedRevenue:
type: number
format: double
description: 예상 매출 증대 (원)
example: 19025000
netProfit:
type: number
format: double
description: 순이익 (원)
example: 14025000
roi:
type: number
format: double
description: ROI (%)
example: 280.5
costPerAcquisition:
type: number
format: double
description: 고객 획득 비용 (CPA, 원)
example: 324.35
required:
- totalInvestment
- expectedRevenue
- roi
ChannelAnalyticsResponse:
type: object
description: 채널별 성과 분석 응답
properties:
eventId:
type: string
description: 이벤트 ID
example: "evt_2025012301"
channels:
type: array
description: 채널별 상세 분석
items:
$ref: '#/components/schemas/ChannelAnalytics'
comparison:
$ref: '#/components/schemas/ChannelComparison'
lastUpdatedAt:
type: string
format: date-time
description: 마지막 업데이트 시간
example: "2025-01-23T10:30:00Z"
required:
- eventId
- channels
- lastUpdatedAt
ChannelAnalytics:
type: object
description: 채널별 상세 분석
properties:
channelName:
type: string
description: 채널명
example: "우리동네TV"
channelType:
type: string
description: 채널 유형
enum:
- LOCAL_TV
- CABLE_TV
- VOICE_CALL
- SNS
- MOBILE_APP
example: "LOCAL_TV"
metrics:
$ref: '#/components/schemas/ChannelMetrics'
performance:
$ref: '#/components/schemas/ChannelPerformance'
costs:
$ref: '#/components/schemas/ChannelCosts'
externalApiStatus:
type: string
description: 외부 API 연동 상태
enum:
- success
- fallback
- failed
example: "success"
required:
- channelName
- channelType
- metrics
- performance
ChannelMetrics:
type: object
description: 채널 지표
properties:
impressions:
type: integer
description: 노출 수
example: 120000
views:
type: integer
description: 조회수
example: 45000
clicks:
type: integer
description: 클릭 수
example: 8900
participants:
type: integer
description: 참여자 수
example: 5500
conversions:
type: integer
description: 전환 수
example: 1850
socialInteractions:
$ref: '#/components/schemas/SocialInteractionStats'
voiceCallStats:
$ref: '#/components/schemas/VoiceCallStats'
required:
- views
- participants
ChannelPerformance:
type: object
description: 채널 성과 지표
properties:
clickThroughRate:
type: number
format: double
description: 클릭률 (CTR, %)
example: 7.4
engagementRate:
type: number
format: double
description: 참여율 (%)
example: 12.2
conversionRate:
type: number
format: double
description: 전환율 (%)
example: 4.1
averageEngagementTime:
type: integer
description: 평균 참여 시간 (초)
example: 165
bounceRate:
type: number
format: double
description: 이탈율 (%)
example: 35.8
required:
- engagementRate
- conversionRate
ChannelCosts:
type: object
description: 채널별 비용
properties:
distributionCost:
type: number
format: double
description: 배포 비용 (원)
example: 1500000
costPerView:
type: number
format: double
description: 조회당 비용 (CPV, 원)
example: 33.33
costPerClick:
type: number
format: double
description: 클릭당 비용 (CPC, 원)
example: 168.54
costPerAcquisition:
type: number
format: double
description: 고객 획득 비용 (CPA, 원)
example: 272.73
roi:
type: number
format: double
description: ROI (%)
example: 295.3
required:
- distributionCost
- roi
ChannelComparison:
type: object
description: 채널 간 비교 분석
properties:
bestPerforming:
type: object
description: 최고 성과 채널
properties:
byViews:
type: string
example: "우리동네TV"
byEngagement:
type: string
example: "지니TV"
byRoi:
type: string
example: "SNS"
averageMetrics:
type: object
description: 전체 채널 평균 지표
properties:
engagementRate:
type: number
format: double
example: 11.5
conversionRate:
type: number
format: double
example: 3.9
roi:
type: number
format: double
example: 275.8
TimelineAnalyticsResponse:
type: object
description: 시간대별 참여 추이 응답
properties:
eventId:
type: string
description: 이벤트 ID
example: "evt_2025012301"
interval:
type: string
description: 시간 간격
enum:
- hourly
- daily
- weekly
example: "daily"
dataPoints:
type: array
description: 시간대별 데이터
items:
$ref: '#/components/schemas/TimelineDataPoint'
trends:
$ref: '#/components/schemas/TrendAnalysis'
peakTimes:
type: array
description: 피크 타임 정보
items:
$ref: '#/components/schemas/PeakTimeInfo'
lastUpdatedAt:
type: string
format: date-time
description: 마지막 업데이트 시간
example: "2025-01-23T10:30:00Z"
required:
- eventId
- interval
- dataPoints
- lastUpdatedAt
TimelineDataPoint:
type: object
description: 시간대별 데이터 포인트
properties:
timestamp:
type: string
format: date-time
description: 시간
example: "2025-01-15T00:00:00Z"
participants:
type: integer
description: 참여자 수
example: 450
views:
type: integer
description: 조회수
example: 3500
engagement:
type: integer
description: 참여 행동 수
example: 280
conversions:
type: integer
description: 전환 수
example: 45
cumulativeParticipants:
type: integer
description: 누적 참여자 수
example: 5450
required:
- timestamp
- participants
- views
TrendAnalysis:
type: object
description: 추세 분석
properties:
overallTrend:
type: string
description: 전체 추세
enum:
- increasing
- stable
- decreasing
example: "increasing"
growthRate:
type: number
format: double
description: 증가율 (%)
example: 15.3
projectedParticipants:
type: integer
description: 예상 참여자 수 (기간 종료 시점)
example: 18500
peakPeriod:
type: string
description: 피크 기간
example: "2025-01-15 ~ 2025-01-18"
required:
- overallTrend
PeakTimeInfo:
type: object
description: 피크 타임 정보
properties:
timestamp:
type: string
format: date-time
description: 피크 시간
example: "2025-01-15T14:00:00Z"
metric:
type: string
description: 피크 지표
enum:
- participants
- views
- engagement
- conversions
example: "participants"
value:
type: integer
description: 피크 값
example: 1250
description:
type: string
description: 피크 설명
example: "주말 오후 최대 참여"
RoiAnalyticsResponse:
type: object
description: ROI 상세 분석 응답
properties:
eventId:
type: string
description: 이벤트 ID
example: "evt_2025012301"
investment:
$ref: '#/components/schemas/InvestmentDetails'
revenue:
$ref: '#/components/schemas/RevenueDetails'
roi:
$ref: '#/components/schemas/RoiCalculation'
costEfficiency:
$ref: '#/components/schemas/CostEfficiency'
projection:
$ref: '#/components/schemas/RevenueProjection'
lastUpdatedAt:
type: string
format: date-time
description: 마지막 업데이트 시간
example: "2025-01-23T10:30:00Z"
required:
- eventId
- investment
- revenue
- roi
- lastUpdatedAt
InvestmentDetails:
type: object
description: 투자 비용 상세
properties:
contentCreation:
type: number
format: double
description: 콘텐츠 제작비 (원)
example: 2000000
distribution:
type: number
format: double
description: 배포 비용 (원)
example: 2500000
operation:
type: number
format: double
description: 운영 비용 (원)
example: 500000
total:
type: number
format: double
description: 총 투자 비용 (원)
example: 5000000
breakdown:
type: array
description: 채널별 비용 상세
items:
type: object
properties:
channelName:
type: string
example: "우리동네TV"
cost:
type: number
format: double
example: 1500000
required:
- total
RevenueDetails:
type: object
description: 수익 상세
properties:
directSales:
type: number
format: double
description: 직접 매출 (원)
example: 12500000
expectedSales:
type: number
format: double
description: 예상 추가 매출 (원)
example: 6525000
brandValue:
type: number
format: double
description: 브랜드 가치 향상 추정액 (원)
example: 3000000
total:
type: number
format: double
description: 총 수익 (원)
example: 19025000
required:
- total
RoiCalculation:
type: object
description: ROI 계산
properties:
netProfit:
type: number
format: double
description: 순이익 (원)
example: 14025000
roiPercentage:
type: number
format: double
description: ROI (%)
example: 280.5
breakEvenPoint:
type: string
format: date-time
description: 손익분기점 도달 시점
example: "2025-01-10T15:30:00Z"
paybackPeriod:
type: integer
description: 투자 회수 기간 (일)
example: 9
required:
- netProfit
- roiPercentage
CostEfficiency:
type: object
description: 비용 효율성
properties:
costPerParticipant:
type: number
format: double
description: 참여자당 비용 (원)
example: 324.35
costPerConversion:
type: number
format: double
description: 전환당 비용 (원)
example: 850.34
costPerView:
type: number
format: double
description: 조회당 비용 (원)
example: 39.90
revenuePerParticipant:
type: number
format: double
description: 참여자당 수익 (원)
example: 1234.25
required:
- costPerParticipant
RevenueProjection:
type: object
description: 수익 예측
properties:
currentRevenue:
type: number
format: double
description: 현재 누적 수익 (원)
example: 12500000
projectedFinalRevenue:
type: number
format: double
description: 예상 최종 수익 (원)
example: 21000000
confidenceLevel:
type: number
format: double
description: 예측 신뢰도 (%)
example: 85.5
basedOn:
type: string
description: 예측 기반
example: "현재 추세 및 과거 유사 이벤트 데이터"
ErrorResponse:
type: object
description: 오류 응답
properties:
timestamp:
type: string
format: date-time
description: 오류 발생 시간
example: "2025-01-23T10:30:00Z"
status:
type: integer
description: HTTP 상태 코드
example: 404
error:
type: string
description: 오류 유형
example: "Not Found"
message:
type: string
description: 오류 메시지
example: "이벤트를 찾을 수 없습니다."
path:
type: string
description: 요청 경로
example: "/api/events/evt_2025012301/analytics"
errorCode:
type: string
description: 내부 오류 코드
example: "ANAL_001"
required:
- timestamp
- status
- error
- message
- path
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT 토큰 기반 인증
security:
- bearerAuth: []