mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2026-06-13 11:39:11 +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,538 @@
|
||||
# Event Service 클래스 설계서
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
Event Service의 Clean Architecture 기반 클래스 설계를 정의합니다.
|
||||
|
||||
### 1.2 설계 원칙
|
||||
- **아키텍처 패턴**: Clean Architecture
|
||||
- **패키지 그룹**: com.kt.event
|
||||
- **의존성 방향**: Presentation → Application → Domain ← Infrastructure
|
||||
|
||||
### 1.3 핵심 특징
|
||||
- 복잡한 이벤트 생명주기 관리 (DRAFT → PUBLISHED → ENDED)
|
||||
- 상태 머신 패턴 적용
|
||||
- AI 서비스 비동기 연동 (Kafka)
|
||||
- Content Service 동기 연동 (Feign)
|
||||
- Redis 캐시 활용
|
||||
|
||||
---
|
||||
|
||||
## 2. 계층별 구조
|
||||
|
||||
### 2.1 Domain Layer (핵심 비즈니스 로직)
|
||||
|
||||
#### 2.1.1 Entity
|
||||
**Event (이벤트 집합 루트)**
|
||||
```java
|
||||
- 책임: 이벤트 전체 생명주기 관리
|
||||
- 상태: DRAFT, PUBLISHED, ENDED
|
||||
- 비즈니스 규칙:
|
||||
* DRAFT 상태에서만 수정 가능
|
||||
* 배포 시 필수 데이터 검증 (이벤트명, 기간, 이미지, 채널)
|
||||
* 상태 전이 제약 (DRAFT → PUBLISHED → ENDED)
|
||||
- 관계:
|
||||
* 1:N GeneratedImage (생성된 이미지)
|
||||
* 1:N AiRecommendation (AI 추천안)
|
||||
```
|
||||
|
||||
**AiRecommendation (AI 추천 엔티티)**
|
||||
```java
|
||||
- 책임: AI가 생성한 이벤트 기획안 관리
|
||||
- 속성: 이벤트명, 설명, 프로모션 유형, 타겟 고객
|
||||
- 선택 상태: isSelected (단일 선택)
|
||||
```
|
||||
|
||||
**GeneratedImage (생성 이미지 엔티티)**
|
||||
```java
|
||||
- 책임: 이벤트별 생성된 이미지 관리
|
||||
- 속성: 이미지 URL, 스타일, 플랫폼
|
||||
- 선택 상태: isSelected (단일 선택)
|
||||
```
|
||||
|
||||
**Job (비동기 작업 엔티티)**
|
||||
```java
|
||||
- 책임: AI 추천, 이미지 생성 등 비동기 작업 상태 관리
|
||||
- 상태: PENDING, PROCESSING, COMPLETED, FAILED
|
||||
- 진행률: 0~100 (progress)
|
||||
- 결과: Redis 키 (resultKey) 또는 에러 메시지
|
||||
```
|
||||
|
||||
#### 2.1.2 Enums
|
||||
- **EventStatus**: DRAFT, PUBLISHED, ENDED
|
||||
- **JobStatus**: PENDING, PROCESSING, COMPLETED, FAILED
|
||||
- **JobType**: AI_RECOMMENDATION, IMAGE_GENERATION
|
||||
|
||||
#### 2.1.3 Repository Interfaces
|
||||
- **EventRepository**: 이벤트 조회, 필터링, 페이징
|
||||
- **AiRecommendationRepository**: AI 추천 관리
|
||||
- **GeneratedImageRepository**: 이미지 관리
|
||||
- **JobRepository**: 작업 상태 관리
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Application Layer (유스케이스)
|
||||
|
||||
#### 2.2.1 Services
|
||||
|
||||
**EventService (핵심 오케스트레이터)**
|
||||
```java
|
||||
책임:
|
||||
- 이벤트 전체 생명주기 조율
|
||||
- AI 서비스 연동 (Kafka 비동기)
|
||||
- Content 서비스 연동 (Feign 동기)
|
||||
- 트랜잭션 경계 관리
|
||||
|
||||
주요 유스케이스:
|
||||
1. createEvent(): 이벤트 생성 (Step 1: 목적 선택)
|
||||
2. requestAiRecommendations(): AI 추천 요청 (Step 2)
|
||||
3. selectRecommendation(): AI 추천 선택
|
||||
4. requestImageGeneration(): 이미지 생성 요청 (Step 3)
|
||||
5. selectImage(): 이미지 선택
|
||||
6. selectChannels(): 배포 채널 선택 (Step 4)
|
||||
7. publishEvent(): 이벤트 배포 (Step 5)
|
||||
8. endEvent(): 이벤트 종료
|
||||
```
|
||||
|
||||
**JobService (작업 관리)**
|
||||
```java
|
||||
책임:
|
||||
- 비동기 작업 상태 조회
|
||||
- 작업 진행률 업데이트
|
||||
- 작업 완료/실패 처리
|
||||
|
||||
주요 유스케이스:
|
||||
1. createJob(): 작업 생성
|
||||
2. getJobStatus(): 작업 상태 조회
|
||||
3. updateJobProgress(): 진행률 업데이트
|
||||
4. completeJob(): 작업 완료 처리
|
||||
5. failJob(): 작업 실패 처리
|
||||
```
|
||||
|
||||
#### 2.2.2 DTOs
|
||||
|
||||
**Request DTOs**
|
||||
- SelectObjectiveRequest: 목적 선택
|
||||
- AiRecommendationRequest: AI 추천 요청 (매장 정보 포함)
|
||||
- SelectRecommendationRequest: AI 추천 선택 + 커스터마이징
|
||||
- ImageGenerationRequest: 이미지 생성 요청 (스타일, 플랫폼)
|
||||
- SelectImageRequest: 이미지 선택
|
||||
- ImageEditRequest: 이미지 편집
|
||||
- SelectChannelsRequest: 배포 채널 선택
|
||||
- UpdateEventRequest: 이벤트 수정
|
||||
|
||||
**Response DTOs**
|
||||
- EventCreatedResponse: 이벤트 생성 응답
|
||||
- EventDetailResponse: 이벤트 상세 (이미지, 추천 포함)
|
||||
- JobAcceptedResponse: 작업 접수 응답
|
||||
- JobStatusResponse: 작업 상태 응답
|
||||
- ImageGenerationResponse: 이미지 생성 응답
|
||||
|
||||
**Kafka Message DTOs**
|
||||
- AIEventGenerationJobMessage: AI 작업 메시지
|
||||
- ImageGenerationJobMessage: 이미지 생성 작업 메시지
|
||||
- EventCreatedMessage: 이벤트 생성 이벤트
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Infrastructure Layer (기술 구현)
|
||||
|
||||
#### 2.3.1 Kafka (비동기 메시징)
|
||||
|
||||
**AIJobKafkaProducer**
|
||||
```java
|
||||
책임: AI 추천 생성 작업 발행
|
||||
토픽: ai-event-generation-job
|
||||
메시지: AIEventGenerationJobMessage
|
||||
```
|
||||
|
||||
**AIJobKafkaConsumer**
|
||||
```java
|
||||
책임: AI 작업 결과 수신 및 처리
|
||||
처리: COMPLETED, FAILED, PROCESSING 상태별 분기
|
||||
수동 커밋: Acknowledgment 사용
|
||||
```
|
||||
|
||||
**ImageJobKafkaConsumer**
|
||||
```java
|
||||
책임: 이미지 생성 작업 결과 수신
|
||||
처리: 생성된 이미지 DB 저장
|
||||
```
|
||||
|
||||
**EventKafkaProducer**
|
||||
```java
|
||||
책임: 이벤트 생성 이벤트 발행
|
||||
토픽: event-created
|
||||
용도: Distribution Service 연동
|
||||
```
|
||||
|
||||
#### 2.3.2 Client (외부 서비스 연동)
|
||||
|
||||
**ContentServiceClient (Feign)**
|
||||
```java
|
||||
대상: Content Service (포트 8082)
|
||||
API: POST /api/v1/content/images/generate
|
||||
요청: ContentImageGenerationRequest
|
||||
응답: ContentJobResponse (Job ID 반환)
|
||||
```
|
||||
|
||||
#### 2.3.3 Config
|
||||
|
||||
**RedisConfig**
|
||||
```java
|
||||
책임: Redis 연결 설정
|
||||
용도:
|
||||
- AI 추천 결과 임시 저장
|
||||
- 이미지 생성 결과 임시 저장
|
||||
- Job 결과 캐싱
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Presentation Layer (API)
|
||||
|
||||
#### 2.4.1 Controllers
|
||||
|
||||
**EventController**
|
||||
```java
|
||||
Base Path: /api/v1/events
|
||||
|
||||
주요 엔드포인트:
|
||||
1. POST /objectives - 이벤트 목적 선택 (생성)
|
||||
2. GET /events - 이벤트 목록 조회 (페이징, 필터링)
|
||||
3. GET /events/{id} - 이벤트 상세 조회
|
||||
4. DELETE /events/{id} - 이벤트 삭제
|
||||
5. POST /events/{id}/publish - 이벤트 배포
|
||||
6. POST /events/{id}/end - 이벤트 종료
|
||||
7. POST /events/{id}/ai-recommendations - AI 추천 요청
|
||||
8. PUT /events/{id}/recommendations - AI 추천 선택
|
||||
9. POST /events/{id}/images - 이미지 생성 요청
|
||||
10. PUT /events/{id}/images/{imageId}/select - 이미지 선택
|
||||
11. PUT /events/{id}/images/{imageId}/edit - 이미지 편집
|
||||
12. PUT /events/{id}/channels - 배포 채널 선택
|
||||
13. PUT /events/{id} - 이벤트 수정
|
||||
```
|
||||
|
||||
**JobController**
|
||||
```java
|
||||
Base Path: /api/v1/jobs
|
||||
|
||||
엔드포인트:
|
||||
1. GET /jobs/{id} - 작업 상태 조회
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 핵심 플로우
|
||||
|
||||
### 3.1 이벤트 생성 플로우
|
||||
|
||||
```
|
||||
1. 목적 선택 (POST /objectives)
|
||||
→ Event 생성 (DRAFT 상태)
|
||||
|
||||
2. AI 추천 요청 (POST /events/{id}/ai-recommendations)
|
||||
→ Job 생성 (AI_RECOMMENDATION)
|
||||
→ Kafka 메시지 발행 (ai-event-generation-job)
|
||||
→ AI Service 처리
|
||||
→ Kafka 메시지 수신 (결과)
|
||||
→ Redis 캐시 저장
|
||||
→ Job 완료 처리
|
||||
|
||||
3. AI 추천 선택 (PUT /events/{id}/recommendations)
|
||||
→ Redis에서 추천 목록 조회
|
||||
→ 선택 + 커스터마이징 적용
|
||||
→ Event 업데이트 (eventName, description, period)
|
||||
|
||||
4. 이미지 생성 요청 (POST /events/{id}/images)
|
||||
→ Content Service 호출 (Feign)
|
||||
→ Job ID 반환
|
||||
→ 폴링으로 상태 확인
|
||||
|
||||
5. 이미지 선택 (PUT /events/{id}/images/{imageId}/select)
|
||||
→ Event.selectedImageId 업데이트
|
||||
→ GeneratedImage.isSelected = true
|
||||
|
||||
6. 배포 채널 선택 (PUT /events/{id}/channels)
|
||||
→ Event.channels 업데이트
|
||||
|
||||
7. 이벤트 배포 (POST /events/{id}/publish)
|
||||
→ 필수 데이터 검증
|
||||
→ 상태 변경 (DRAFT → PUBLISHED)
|
||||
→ Kafka 메시지 발행 (event-created)
|
||||
```
|
||||
|
||||
### 3.2 상태 머신 다이어그램
|
||||
|
||||
```
|
||||
DRAFT → publish() → PUBLISHED → end() → ENDED
|
||||
↑ |
|
||||
| ↓
|
||||
└─────── (수정 불가) ─────┘
|
||||
```
|
||||
|
||||
**상태별 제약:**
|
||||
- DRAFT: 모든 수정 가능, 삭제 가능
|
||||
- PUBLISHED: 수정 불가, 삭제 불가, 종료만 가능
|
||||
- ENDED: 모든 변경 불가 (읽기 전용)
|
||||
|
||||
---
|
||||
|
||||
## 4. 비동기 작업 처리
|
||||
|
||||
### 4.1 Job 생명주기
|
||||
|
||||
```
|
||||
PENDING → start() → PROCESSING → complete() → COMPLETED
|
||||
↓
|
||||
fail() → FAILED
|
||||
```
|
||||
|
||||
### 4.2 작업 유형별 처리
|
||||
|
||||
**AI_RECOMMENDATION (AI 추천 생성)**
|
||||
- 발행: AIJobKafkaProducer
|
||||
- 수신: AIJobKafkaConsumer
|
||||
- 결과: Redis 캐시 (추천 목록)
|
||||
- 시간: 10~30초
|
||||
|
||||
**IMAGE_GENERATION (이미지 생성)**
|
||||
- 발행: EventService → ContentServiceClient
|
||||
- 수신: ImageJobKafkaConsumer (Content Service에서 발행)
|
||||
- 결과: GeneratedImage 엔티티 (DB 저장)
|
||||
- 시간: 30~60초
|
||||
|
||||
---
|
||||
|
||||
## 5. 패키지 구조
|
||||
|
||||
```
|
||||
com.kt.event.eventservice
|
||||
├── domain/
|
||||
│ ├── entity/
|
||||
│ │ ├── Event.java
|
||||
│ │ ├── AiRecommendation.java
|
||||
│ │ ├── GeneratedImage.java
|
||||
│ │ └── Job.java
|
||||
│ ├── enums/
|
||||
│ │ ├── EventStatus.java
|
||||
│ │ ├── JobStatus.java
|
||||
│ │ └── JobType.java
|
||||
│ └── repository/
|
||||
│ ├── EventRepository.java
|
||||
│ ├── AiRecommendationRepository.java
|
||||
│ ├── GeneratedImageRepository.java
|
||||
│ └── JobRepository.java
|
||||
├── application/
|
||||
│ ├── service/
|
||||
│ │ ├── EventService.java
|
||||
│ │ └── JobService.java
|
||||
│ └── dto/
|
||||
│ ├── request/
|
||||
│ │ ├── SelectObjectiveRequest.java
|
||||
│ │ ├── AiRecommendationRequest.java
|
||||
│ │ ├── SelectRecommendationRequest.java
|
||||
│ │ ├── ImageGenerationRequest.java
|
||||
│ │ ├── SelectImageRequest.java
|
||||
│ │ ├── ImageEditRequest.java
|
||||
│ │ ├── SelectChannelsRequest.java
|
||||
│ │ └── UpdateEventRequest.java
|
||||
│ ├── response/
|
||||
│ │ ├── EventCreatedResponse.java
|
||||
│ │ ├── EventDetailResponse.java
|
||||
│ │ ├── JobAcceptedResponse.java
|
||||
│ │ ├── JobStatusResponse.java
|
||||
│ │ ├── ImageGenerationResponse.java
|
||||
│ │ └── ImageEditResponse.java
|
||||
│ └── kafka/
|
||||
│ ├── AIEventGenerationJobMessage.java
|
||||
│ ├── ImageGenerationJobMessage.java
|
||||
│ └── EventCreatedMessage.java
|
||||
├── infrastructure/
|
||||
│ ├── kafka/
|
||||
│ │ ├── AIJobKafkaProducer.java
|
||||
│ │ ├── AIJobKafkaConsumer.java
|
||||
│ │ ├── ImageJobKafkaConsumer.java
|
||||
│ │ └── EventKafkaProducer.java
|
||||
│ ├── client/
|
||||
│ │ └── ContentServiceClient.java (Feign)
|
||||
│ ├── client.dto/
|
||||
│ │ ├── ContentImageGenerationRequest.java
|
||||
│ │ └── ContentJobResponse.java
|
||||
│ └── config/
|
||||
│ └── RedisConfig.java
|
||||
├── presentation/
|
||||
│ └── controller/
|
||||
│ ├── EventController.java
|
||||
│ └── JobController.java
|
||||
└── config/
|
||||
├── SecurityConfig.java
|
||||
├── KafkaConfig.java
|
||||
└── DevAuthenticationFilter.java
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 의존성 방향
|
||||
|
||||
### 6.1 Clean Architecture 계층
|
||||
|
||||
```
|
||||
Presentation Layer (EventController)
|
||||
↓ depends on
|
||||
Application Layer (EventService)
|
||||
↓ depends on
|
||||
Domain Layer (Event, EventRepository)
|
||||
↑ implements
|
||||
Infrastructure Layer (EventRepositoryImpl, Kafka, Feign)
|
||||
```
|
||||
|
||||
### 6.2 핵심 원칙
|
||||
1. **Domain Layer는 외부 의존성 없음** (순수 비즈니스 로직)
|
||||
2. **Application Layer는 Domain을 조율** (유스케이스)
|
||||
3. **Infrastructure Layer는 Domain 인터페이스 구현** (기술 세부사항)
|
||||
4. **Presentation Layer는 Application 호출** (API 엔드포인트)
|
||||
|
||||
---
|
||||
|
||||
## 7. 주요 설계 패턴
|
||||
|
||||
### 7.1 Domain 패턴
|
||||
- **Aggregate Root**: Event (경계 내 일관성 보장)
|
||||
- **State Machine**: EventStatus, JobStatus (상태 전이 제약)
|
||||
- **Value Object**: StoreInfo, Customizations (불변 값)
|
||||
|
||||
### 7.2 Application 패턴
|
||||
- **Service Layer**: EventService, JobService (유스케이스 조율)
|
||||
- **DTO Pattern**: Request/Response 분리 (계층 간 데이터 전송)
|
||||
- **Repository Pattern**: EventRepository (영속성 추상화)
|
||||
|
||||
### 7.3 Infrastructure 패턴
|
||||
- **Adapter Pattern**: ContentServiceClient (외부 서비스 연동)
|
||||
- **Producer/Consumer**: Kafka 메시징 (비동기 통신)
|
||||
- **Cache-Aside**: Redis 캐싱 (성능 최적화)
|
||||
|
||||
---
|
||||
|
||||
## 8. 트랜잭션 경계
|
||||
|
||||
### 8.1 @Transactional 적용 위치
|
||||
```java
|
||||
EventService:
|
||||
- createEvent() - 쓰기
|
||||
- deleteEvent() - 쓰기
|
||||
- publishEvent() - 쓰기
|
||||
- endEvent() - 쓰기
|
||||
- updateEvent() - 쓰기
|
||||
- requestAiRecommendations() - 쓰기 (Job 생성)
|
||||
- selectRecommendation() - 쓰기
|
||||
- selectImage() - 쓰기
|
||||
- selectChannels() - 쓰기
|
||||
|
||||
JobService:
|
||||
- createJob() - 쓰기
|
||||
- updateJobProgress() - 쓰기
|
||||
- completeJob() - 쓰기
|
||||
- failJob() - 쓰기
|
||||
```
|
||||
|
||||
### 8.2 읽기 전용 트랜잭션
|
||||
```java
|
||||
@Transactional(readOnly = true):
|
||||
- getEvent()
|
||||
- getEvents()
|
||||
- getJobStatus()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 보안 및 인증
|
||||
|
||||
### 9.1 인증 방식
|
||||
- **개발 환경**: DevAuthenticationFilter (Header 기반)
|
||||
- **운영 환경**: JWT 인증 (JwtAuthenticationFilter)
|
||||
|
||||
### 9.2 인가 처리
|
||||
```java
|
||||
@AuthenticationPrincipal UserPrincipal
|
||||
- userId: 요청자 ID
|
||||
- storeId: 매장 ID
|
||||
|
||||
검증:
|
||||
- Event는 userId로 소유권 확인
|
||||
- EventRepository.findByEventIdAndUserId() 사용
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 에러 처리
|
||||
|
||||
### 10.1 공통 에러 코드
|
||||
```java
|
||||
ErrorCode:
|
||||
- EVENT_001: 이벤트를 찾을 수 없음
|
||||
- EVENT_002: 이벤트 수정/삭제 불가 (상태 제약)
|
||||
- EVENT_003: 선택한 리소스를 찾을 수 없음
|
||||
- JOB_001: 작업을 찾을 수 없음
|
||||
- JOB_002: 작업 상태 변경 불가
|
||||
```
|
||||
|
||||
### 10.2 예외 처리
|
||||
```java
|
||||
Domain Layer:
|
||||
- IllegalStateException (상태 전이 제약 위반)
|
||||
- IllegalArgumentException (비즈니스 규칙 위반)
|
||||
|
||||
Application Layer:
|
||||
- BusinessException (비즈니스 로직 에러)
|
||||
|
||||
Infrastructure Layer:
|
||||
- InfraException (외부 시스템 에러)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 테스트 전략
|
||||
|
||||
### 11.1 단위 테스트
|
||||
```java
|
||||
Domain Layer:
|
||||
- Event 상태 전이 로직
|
||||
- 비즈니스 규칙 검증
|
||||
|
||||
Application Layer:
|
||||
- EventService 유스케이스
|
||||
- DTO 변환 로직
|
||||
```
|
||||
|
||||
### 11.2 통합 테스트
|
||||
```java
|
||||
Infrastructure Layer:
|
||||
- Kafka Producer/Consumer
|
||||
- Feign Client
|
||||
- Redis 캐싱
|
||||
|
||||
Presentation Layer:
|
||||
- REST API 엔드포인트
|
||||
- 인증/인가
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 파일 정보
|
||||
|
||||
### 12.1 다이어그램 파일
|
||||
- **상세 다이어그램**: `design/backend/class/event-service.puml`
|
||||
- **요약 다이어그램**: `design/backend/class/event-service-simple.puml`
|
||||
|
||||
### 12.2 참조 문서
|
||||
- 공통 컴포넌트: `design/backend/class/common-base.puml`
|
||||
- API 설계서: `design/backend/api/spec/event-service-api.yaml`
|
||||
- 데이터 설계서: `design/backend/database/event-service-schema.sql`
|
||||
|
||||
---
|
||||
|
||||
**작성일**: 2025-10-29
|
||||
**작성자**: Backend Architect (Claude Code)
|
||||
**버전**: 1.0.0
|
||||
Reference in New Issue
Block a user