mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 16:06:24 +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>
165 lines
4.1 KiB
Plaintext
165 lines
4.1 KiB
Plaintext
@startuml
|
|
!theme mono
|
|
|
|
title Event Service ERD (Entity Relationship Diagram)
|
|
|
|
' ==============================
|
|
' 엔티티 정의
|
|
' ==============================
|
|
|
|
entity "events" as events {
|
|
* event_id : UUID <<PK>>
|
|
--
|
|
* user_id : UUID <<INDEX>>
|
|
* store_id : UUID <<INDEX>>
|
|
event_name : VARCHAR(200)
|
|
description : TEXT
|
|
* objective : VARCHAR(100)
|
|
start_date : DATE
|
|
end_date : DATE
|
|
* status : VARCHAR(20) <<DEFAULT 'DRAFT'>>
|
|
selected_image_id : UUID
|
|
selected_image_url : VARCHAR(500)
|
|
channels : TEXT
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
}
|
|
|
|
entity "ai_recommendations" as ai_recommendations {
|
|
* recommendation_id : UUID <<PK>>
|
|
--
|
|
* event_id : UUID <<FK>>
|
|
* event_name : VARCHAR(200)
|
|
* description : TEXT
|
|
* promotion_type : VARCHAR(50)
|
|
* target_audience : VARCHAR(100)
|
|
* is_selected : BOOLEAN <<DEFAULT FALSE>>
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
}
|
|
|
|
entity "generated_images" as generated_images {
|
|
* image_id : UUID <<PK>>
|
|
--
|
|
* event_id : UUID <<FK>>
|
|
* image_url : VARCHAR(500)
|
|
* style : VARCHAR(50)
|
|
* platform : VARCHAR(50)
|
|
* is_selected : BOOLEAN <<DEFAULT FALSE>>
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
}
|
|
|
|
entity "jobs" as jobs {
|
|
* job_id : UUID <<PK>>
|
|
--
|
|
* event_id : UUID
|
|
* job_type : VARCHAR(50)
|
|
* status : VARCHAR(20) <<DEFAULT 'PENDING'>>
|
|
* progress : INT <<DEFAULT 0>>
|
|
result_key : VARCHAR(200)
|
|
error_message : TEXT
|
|
completed_at : TIMESTAMP
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
}
|
|
|
|
' ==============================
|
|
' 관계 정의
|
|
' ==============================
|
|
|
|
events ||--o{ ai_recommendations : "has many"
|
|
events ||--o{ generated_images : "has many"
|
|
events ||--o{ jobs : "tracks"
|
|
|
|
' ==============================
|
|
' 제약조건 노트
|
|
' ==============================
|
|
|
|
note right of events
|
|
**핵심 도메인 엔티티**
|
|
- 상태 머신: DRAFT → PUBLISHED → ENDED
|
|
- DRAFT에서만 수정 가능
|
|
- PUBLISHED에서 END만 가능
|
|
- channels: JSON 배열 (["SMS", "EMAIL"])
|
|
|
|
**인덱스**:
|
|
- IDX_events_user_id (user_id)
|
|
- IDX_events_store_id (store_id)
|
|
- IDX_events_status (status)
|
|
- IDX_events_user_status (user_id, status)
|
|
|
|
**체크 제약조건**:
|
|
- status IN ('DRAFT', 'PUBLISHED', 'ENDED')
|
|
- start_date <= end_date
|
|
end note
|
|
|
|
note right of ai_recommendations
|
|
**AI 추천 결과**
|
|
- 이벤트당 최대 3개 생성
|
|
- is_selected=true는 이벤트당 1개만
|
|
|
|
**인덱스**:
|
|
- IDX_recommendations_event_id (event_id)
|
|
- IDX_recommendations_selected (event_id, is_selected)
|
|
|
|
**외래 키**:
|
|
- FK_recommendations_event (event_id)
|
|
→ events(event_id) ON DELETE CASCADE
|
|
end note
|
|
|
|
note right of generated_images
|
|
**생성 이미지 정보**
|
|
- 여러 스타일/플랫폼 조합 가능
|
|
- is_selected=true는 이벤트당 1개만
|
|
|
|
**인덱스**:
|
|
- IDX_images_event_id (event_id)
|
|
- IDX_images_selected (event_id, is_selected)
|
|
|
|
**외래 키**:
|
|
- FK_images_event (event_id)
|
|
→ events(event_id) ON DELETE CASCADE
|
|
end note
|
|
|
|
note right of jobs
|
|
**비동기 작업 추적**
|
|
- job_type: AI_RECOMMENDATION, IMAGE_GENERATION
|
|
- status: PENDING → PROCESSING → COMPLETED/FAILED
|
|
- progress: 0-100
|
|
|
|
**인덱스**:
|
|
- IDX_jobs_event_id (event_id)
|
|
- IDX_jobs_type_status (job_type, status)
|
|
- IDX_jobs_status (status)
|
|
|
|
**체크 제약조건**:
|
|
- status IN ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED')
|
|
- job_type IN ('AI_RECOMMENDATION', 'IMAGE_GENERATION')
|
|
- progress BETWEEN 0 AND 100
|
|
|
|
**외래 키 없음**: 이벤트 삭제 후에도 작업 이력 보존
|
|
end note
|
|
|
|
' ==============================
|
|
' Redis 캐시 노트
|
|
' ==============================
|
|
|
|
note top of events
|
|
**Redis 캐시 전략**
|
|
|
|
1. event:session:{userId} (TTL: 3600s)
|
|
- 이벤트 생성 세션 정보
|
|
- Hash: eventId, objective, storeId, createdAt
|
|
|
|
2. event:draft:{eventId} (TTL: 1800s)
|
|
- DRAFT 상태 이벤트 캐시
|
|
- Hash: eventName, description, objective, status, userId, storeId
|
|
|
|
3. job:status:{jobId} (TTL: 600s)
|
|
- 작업 상태 실시간 조회
|
|
- Hash: jobType, status, progress, eventId
|
|
end note
|
|
|
|
@enduml
|