# 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
