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 (광고 노출 수) - SNS APIs (좋아요, 댓글, 공유 수) - Circuit Breaker with fallback to cached data **Caching Strategy:** - Redis cache with 5-minute TTL - Cache-Aside pattern for dashboard data - Real-time updates via Kafka event subscription version: 1.0.0 contact: name: Analytics Service Team email: analytics@kt-event.com servers: - url: http://localhost:8086 description: Local Development Server - url: https://api-dev.kt-event.com/analytics description: Development Server - url: https://api.kt-event.com/analytics description: Production Server tags: - name: Analytics description: 이벤트 성과 분석 및 대시보드 API - name: Channels description: 채널별 성과 분석 API - name: Timeline description: 시간대별 분석 API - name: ROI description: 투자 대비 수익률 분석 API paths: /api/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' /api/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' /api/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' /api/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 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 - 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' 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: []