mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 06:46:25 +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>
224 lines
5.5 KiB
Plaintext
224 lines
5.5 KiB
Plaintext
@startuml
|
|
!theme mono
|
|
|
|
title Content Service - ERD (Entity Relationship Diagram)
|
|
|
|
' ============================================
|
|
' PostgreSQL 테이블
|
|
' ============================================
|
|
|
|
entity "content" as content {
|
|
* id : BIGSERIAL <<PK>>
|
|
--
|
|
* event_id : VARCHAR(100) <<UK>>
|
|
* event_title : VARCHAR(200)
|
|
event_description : TEXT
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
}
|
|
|
|
entity "generated_image" as generated_image {
|
|
* id : BIGSERIAL <<PK>>
|
|
--
|
|
* event_id : VARCHAR(100) <<FK>>
|
|
* style : VARCHAR(20) <<CHECK>>
|
|
* platform : VARCHAR(30) <<CHECK>>
|
|
* cdn_url : VARCHAR(500)
|
|
* prompt : TEXT
|
|
* selected : BOOLEAN
|
|
* width : INT
|
|
* height : INT
|
|
file_size : BIGINT
|
|
* content_type : VARCHAR(50)
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
--
|
|
<<INDEX>> (event_id)
|
|
<<INDEX>> (event_id, style, platform)
|
|
<<INDEX>> (created_at)
|
|
}
|
|
|
|
entity "job" as job {
|
|
* id : VARCHAR(100) <<PK>>
|
|
--
|
|
* event_id : VARCHAR(100)
|
|
* job_type : VARCHAR(50) <<CHECK>>
|
|
* status : VARCHAR(20) <<CHECK>>
|
|
* progress : INT
|
|
result_message : TEXT
|
|
error_message : TEXT
|
|
* created_at : TIMESTAMP
|
|
* updated_at : TIMESTAMP
|
|
completed_at : TIMESTAMP
|
|
--
|
|
<<INDEX>> (event_id)
|
|
<<INDEX>> (status, created_at)
|
|
}
|
|
|
|
' ============================================
|
|
' Redis 캐시 구조 (개념적 표현)
|
|
' ============================================
|
|
|
|
entity "RedisJobData\n(Cache)" as redis_job {
|
|
* key : job:{jobId}
|
|
--
|
|
id : STRING
|
|
eventId : STRING
|
|
jobType : STRING
|
|
status : STRING
|
|
progress : INT
|
|
resultMessage : STRING
|
|
errorMessage : STRING
|
|
createdAt : TIMESTAMP
|
|
updatedAt : TIMESTAMP
|
|
--
|
|
<<TTL>> 1 hour
|
|
}
|
|
|
|
entity "RedisImageData\n(Cache)" as redis_image {
|
|
* key : image:{eventId}:{style}:{platform}
|
|
--
|
|
eventId : STRING
|
|
style : STRING
|
|
platform : STRING
|
|
imageUrl : STRING
|
|
prompt : STRING
|
|
createdAt : TIMESTAMP
|
|
--
|
|
<<TTL>> 7 days
|
|
}
|
|
|
|
entity "RedisAIEventData\n(Cache)" as redis_ai {
|
|
* key : ai:event:{eventId}
|
|
--
|
|
eventId : STRING
|
|
recommendedStyles : LIST
|
|
recommendedKeywords : LIST
|
|
cachedAt : TIMESTAMP
|
|
--
|
|
<<TTL>> 1 hour
|
|
}
|
|
|
|
' ============================================
|
|
' 관계 정의
|
|
' ============================================
|
|
|
|
content ||--o{ generated_image : "has many"
|
|
content ||--o{ job : "tracks"
|
|
|
|
' ============================================
|
|
' 캐시 관계 (점선: 논리적 연관)
|
|
' ============================================
|
|
|
|
job ..> redis_job : "cached in"
|
|
generated_image ..> redis_image : "cached in"
|
|
|
|
' ============================================
|
|
' 노트 및 설명
|
|
' ============================================
|
|
|
|
note right of content
|
|
**콘텐츠 집합**
|
|
• 이벤트당 하나의 콘텐츠 집합
|
|
• event_id로 이미지 그룹핑
|
|
• 생성/수정 시각 추적
|
|
end note
|
|
|
|
note right of generated_image
|
|
**생성된 이미지 메타데이터**
|
|
• CDN URL만 저장 (Azure Blob)
|
|
• 스타일: FANCY, SIMPLE, TRENDY
|
|
• 플랫폼: INSTAGRAM, FACEBOOK, KAKAO, BLOG
|
|
• 플랫폼별 해상도:
|
|
- INSTAGRAM: 1080x1080
|
|
- FACEBOOK: 1200x628
|
|
- KAKAO: 800x800
|
|
- BLOG: 800x600
|
|
• selected = true: 최종 선택 이미지
|
|
end note
|
|
|
|
note right of job
|
|
**비동기 작업 추적**
|
|
• Job ID: "job-img-{uuid}"
|
|
• 상태: PENDING → PROCESSING → COMPLETED/FAILED
|
|
• progress: 0-100
|
|
• Kafka 기반 비동기 처리
|
|
end note
|
|
|
|
note bottom of redis_job
|
|
**Job 상태 캐싱**
|
|
• 폴링 조회 성능 최적화
|
|
• TTL 1시간 후 자동 삭제
|
|
• PostgreSQL과 동기화
|
|
end note
|
|
|
|
note bottom of redis_image
|
|
**이미지 캐싱**
|
|
• 동일 이벤트 재요청 시 즉시 반환
|
|
• TTL 7일 후 자동 삭제
|
|
• Key: event_id + style + platform
|
|
end note
|
|
|
|
note bottom of redis_ai
|
|
**AI 추천 데이터 캐싱**
|
|
• AI Service 이벤트 분석 결과
|
|
• 추천 스타일 및 키워드
|
|
• TTL 1시간 후 자동 삭제
|
|
end note
|
|
|
|
' ============================================
|
|
' 제약 조건 표시
|
|
' ============================================
|
|
|
|
note top of content
|
|
**제약 조건**
|
|
• PK: id (BIGSERIAL)
|
|
• UK: event_id (이벤트당 하나)
|
|
• INDEX: created_at
|
|
end note
|
|
|
|
note top of generated_image
|
|
**제약 조건**
|
|
• PK: id (BIGSERIAL)
|
|
• INDEX: (event_id, style, platform)
|
|
• INDEX: event_id
|
|
• INDEX: created_at
|
|
• CHECK: style IN ('FANCY', 'SIMPLE', 'TRENDY')
|
|
• CHECK: platform IN ('INSTAGRAM', 'FACEBOOK', 'KAKAO', 'BLOG')
|
|
• CHECK: width > 0 AND height > 0
|
|
end note
|
|
|
|
note top of job
|
|
**제약 조건**
|
|
• PK: id (VARCHAR)
|
|
• INDEX: event_id
|
|
• INDEX: (status, created_at)
|
|
• CHECK: status IN ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED')
|
|
• CHECK: job_type IN ('IMAGE_GENERATION', 'IMAGE_REGENERATION')
|
|
• CHECK: progress >= 0 AND progress <= 100
|
|
end note
|
|
|
|
' ============================================
|
|
' 데이터 흐름 및 외부 연동 설명
|
|
' ============================================
|
|
|
|
note as external_integration
|
|
**외부 시스템 연동**
|
|
• Azure Blob Storage (CDN): 이미지 파일 저장
|
|
• Stable Diffusion API: 이미지 생성
|
|
• DALL-E API: Fallback 이미지 생성
|
|
• Kafka Topic (image-generation-job): Job 트리거
|
|
|
|
**데이터 흐름**
|
|
1. Kafka에서 이미지 생성 Job 수신
|
|
2. Job 상태 PENDING → PostgreSQL + Redis 저장
|
|
3. AI 추천 데이터 Redis에서 조회
|
|
4. 외부 API 호출 (Stable Diffusion)
|
|
5. 생성된 이미지 CDN 업로드
|
|
6. generated_image 테이블 저장 (CDN URL)
|
|
7. Job 상태 COMPLETED → Redis 업데이트
|
|
8. 클라이언트 폴링 조회 → Redis 캐시 반환
|
|
end note
|
|
|
|
@enduml
|