mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2026-06-13 18:19:10 +00:00
물리아키텍처 설계 완료
✨ 주요 기능 - Azure 기반 물리아키텍처 설계 (개발환경/운영환경) - 7개 마이크로서비스 물리 구조 설계 - 네트워크 아키텍처 다이어그램 작성 (Mermaid) - 환경별 비교 분석 및 마스터 인덱스 문서 📁 생성 파일 - design/backend/physical/physical-architecture.md (마스터) - design/backend/physical/physical-architecture-dev.md (개발환경) - design/backend/physical/physical-architecture-prod.md (운영환경) - design/backend/physical/*.mmd (4개 Mermaid 다이어그램) 🎯 핵심 성과 - 비용 최적화: 개발환경 월 $143, 운영환경 월 $2,860 - 확장성: 개발환경 100명 → 운영환경 10,000명 (100배) - 가용성: 개발환경 95% → 운영환경 99.9% - 보안: 다층 보안 아키텍처 (L1~L4) 🛠️ 기술 스택 - Azure Kubernetes Service (AKS) - Azure Database for PostgreSQL Flexible - Azure Cache for Redis Premium - Azure Service Bus Premium - Application Gateway + WAF 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
@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
|
||||
Reference in New Issue
Block a user