@startuml
!theme mono

title Analytics Service ERD (Entity Relationship Diagram)

' ============================================================
' Entity Definitions
' ============================================================

entity "event_stats" as event_stats {
  * id : BIGSERIAL <<PK>>
  --
  * event_id : VARCHAR(36) <<UK>>
  * event_title : VARCHAR(255)
  * user_id : VARCHAR(36)
  * total_participants : INTEGER
  * total_views : INTEGER
  * estimated_roi : DECIMAL(10,2)
  * target_roi : DECIMAL(10,2)
  * sales_growth_rate : DECIMAL(10,2)
  * total_investment : DECIMAL(15,2)
  * expected_revenue : DECIMAL(15,2)
  * status : VARCHAR(20)
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

entity "channel_stats" as channel_stats {
  * id : BIGSERIAL <<PK>>
  --
  * event_id : VARCHAR(36) <<FK>>
  * channel_name : VARCHAR(50)
  * channel_type : VARCHAR(20)
  * impressions : INTEGER
  * views : INTEGER
  * clicks : INTEGER
  * participants : INTEGER
  * conversions : INTEGER
  * distribution_cost : DECIMAL(15,2)
  * likes : INTEGER
  * comments : INTEGER
  * shares : INTEGER
  * total_calls : INTEGER
  * completed_calls : INTEGER
  * average_duration : INTEGER
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

entity "timeline_data" as timeline_data {
  * id : BIGSERIAL <<PK>>
  --
  * event_id : VARCHAR(36) <<FK>>
  * timestamp : TIMESTAMP
  * participants : INTEGER
  * views : INTEGER
  * engagement : INTEGER
  * conversions : INTEGER
  * cumulative_participants : INTEGER
  * created_at : TIMESTAMP
  * updated_at : TIMESTAMP
}

' ============================================================
' Relationships
' ============================================================

event_stats ||--o{ channel_stats : "1:N (event_id)"
event_stats ||--o{ timeline_data : "1:N (event_id)"

' ============================================================
' Notes
' ============================================================

note top of event_stats
  **이벤트별 통계 집계**
  - Kafka EventCreatedEvent로 생성
  - ParticipantRegisteredEvent로 증분 업데이트
  - Redis 캐싱 (1시간 TTL)
  - UK: event_id (이벤트당 1개 레코드)
  - INDEX: user_id, status, created_at
end note

note top of channel_stats
  **채널별 성과 데이터**
  - Kafka DistributionCompletedEvent로 생성
  - 외부 API 연동 (Circuit Breaker)
  - UK: (event_id, channel_name)
  - INDEX: event_id, channel_type, participants
  - 채널 타입: TV, SNS, VOICE
end note

note top of timeline_data
  **시계열 분석 데이터**
  - ParticipantRegisteredEvent 발생 시 업데이트
  - 시간별 참여 추이 기록
  - INDEX: (event_id, timestamp) - 시계열 조회 최적화
  - BRIN INDEX: timestamp - 대용량 시계열 데이터
  - 월별 파티셔닝 권장
end note

note bottom of event_stats
  **데이터독립성 원칙**
  - Analytics Service 독립 스키마
  - event_id: Event Service의 이벤트 참조 (캐시)
  - user_id: User Service의 사용자 참조 (캐시)
  - FK 없음 (서비스 간 DB 조인 금지)
end note

note as redis_cache
  **Redis 캐시 구조**
  --
  analytics:dashboard:{eventId}
  analytics:channel:{eventId}:{channelName}
  analytics:roi:{eventId}
  analytics:timeline:{eventId}:{granularity}
  analytics:user:{userId}
  analytics:processed:{messageId} (Set, 24h TTL)
  --
  TTL: 3600초 (1시간)
  패턴: Cache-Aside
end note

' ============================================================
' Legend
' ============================================================

legend bottom right
  **범례**
  --
  PK: Primary Key
  FK: Foreign Key (논리적 관계만, 물리 FK 없음)
  UK: Unique Key
  INDEX: B-Tree 인덱스
  BRIN: Block Range Index (시계열 최적화)
  --
  **제약 조건**
  - total_participants >= 0
  - total_investment >= 0
  - estimated_roi >= 0
  - status IN ('ACTIVE', 'ENDED', 'ARCHIVED')
  - channel_type IN ('TV', 'SNS', 'VOICE')
  - completed_calls <= total_calls
end legend

@enduml
