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 5-minute TTL
    - 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: []
