# KT Event Marketing - Clean Architecture Package Structure

## 프로젝트 구조 개요

```
kt-event-marketing/
├── common/                          # 공통 모듈
├── user-service/                    # 사용자 서비스
├── event-service/                   # 이벤트 서비스
├── ai-service/                      # AI 서비스
├── content-service/                 # 콘텐츠 서비스
├── distribution-service/            # 배포 서비스
├── participation-service/           # 참여 서비스
├── analytics-service/               # 분석 서비스
├── settings.gradle
└── build.gradle
```

---

## Common 모듈 패키지 구조

```
common/
└── src/main/java/com/kt/event/common/
    ├── dto/
    │   ├── ApiResponse.java              # 공통 API 응답 래퍼
    │   ├── PageResponse.java             # 페이지네이션 응답
    │   └── ErrorResponse.java            # 에러 응답
    ├── exception/
    │   ├── ErrorCode.java                # 에러 코드 enum
    │   ├── BusinessException.java        # 비즈니스 예외
    │   ├── InfraException.java           # 인프라 예외
    │   └── GlobalExceptionHandler.java   # 전역 예외 핸들러
    ├── util/
    │   ├── DateTimeUtil.java             # 날짜/시간 유틸
    │   ├── StringUtil.java               # 문자열 유틸
    │   ├── ValidationUtil.java           # 유효성 검증 유틸
    │   └── EncryptionUtil.java           # 암호화 유틸
    ├── security/
    │   ├── UserPrincipal.java            # 인증된 사용자 정보
    │   ├── JwtTokenProvider.java         # JWT 토큰 제공자
    │   └── JwtAuthenticationFilter.java  # JWT 인증 필터
    └── entity/
        └── BaseTimeEntity.java           # 생성/수정 시간 base entity
```

---

## User Service 패키지 구조 (Clean Architecture)

```
user-service/
└── src/main/java/com/kt/event/user/
    ├── biz/                              # Business Layer
    │   ├── domain/                       # 도메인 모델
    │   │   ├── User.java
    │   │   ├── Store.java
    │   │   └── BusinessVerification.java
    │   ├── usecase/                      # Use Case 인터페이스
    │   │   ├── in/                       # Inbound Port (비즈니스 로직 진입점)
    │   │   │   ├── RegisterUserUseCase.java
    │   │   │   ├── LoginUserUseCase.java
    │   │   │   ├── LogoutUserUseCase.java
    │   │   │   ├── GetUserProfileUseCase.java
    │   │   │   ├── UpdateUserProfileUseCase.java
    │   │   │   ├── ChangePasswordUseCase.java
    │   │   │   └── GetStoreInfoUseCase.java
    │   │   └── out/                      # Outbound Port (외부 의존성 인터페이스)
    │   │       ├── UserReader.java
    │   │       ├── UserWriter.java
    │   │       ├── StoreReader.java
    │   │       ├── StoreWriter.java
    │   │       ├── RedisSessionWriter.java
    │   │       └── BusinessVerifier.java
    │   ├── service/                      # Use Case 구현체
    │   │   ├── UserService.java
    │   │   ├── AuthenticationService.java
    │   │   └── ProfileService.java
    │   └── dto/                          # 비즈니스 DTO
    │       ├── UserCommand.java
    │       ├── UserInfo.java
    │       └── StoreInfo.java
    └── infra/                            # Infrastructure Layer
        ├── UserApplication.java          # Spring Boot Main
        ├── controller/                   # REST API Controller (Inbound Adapter)
        │   ├── UserController.java
        │   └── AuthController.java
        ├── dto/                          # API Request/Response DTO
        │   ├── request/
        │   │   ├── UserRegisterRequest.java
        │   │   ├── UserLoginRequest.java
        │   │   ├── UserProfileUpdateRequest.java
        │   │   └── ChangePasswordRequest.java
        │   └── response/
        │       ├── UserProfileResponse.java
        │       ├── StoreInfoResponse.java
        │       └── LoginResponse.java
        ├── gateway/                      # Outbound Adapter
        │   ├── entity/                   # JPA Entity
        │   │   ├── UserEntity.java
        │   │   └── StoreEntity.java
        │   ├── repository/               # JPA Repository
        │   │   ├── UserJpaRepository.java
        │   │   └── StoreJpaRepository.java
        │   ├── UserGateway.java          # User Reader/Writer 구현
        │   ├── StoreGateway.java         # Store Reader/Writer 구현
        │   ├── RedisSessionGateway.java  # Redis Session 구현
        │   └── BusinessVerifierGateway.java # 사업자번호 검증 구현
        └── config/                       # 설정
            ├── SecurityConfig.java
            ├── RedisConfig.java
            ├── SwaggerConfig.java
            └── DataLoader.java
```

---

## Event Service 패키지 구조 (Clean Architecture)

```
event-service/
└── src/main/java/com/kt/event/event/
    ├── biz/
    │   ├── domain/
    │   │   ├── Event.java
    │   │   ├── EventObjective.java
    │   │   ├── EventStatus.java
    │   │   ├── AIRecommendation.java
    │   │   ├── Image.java
    │   │   ├── DistributionChannel.java
    │   │   └── Job.java
    │   ├── usecase/
    │   │   ├── in/
    │   │   │   ├── CreateEventObjectiveUseCase.java
    │   │   │   ├── RequestAIRecommendationUseCase.java
    │   │   │   ├── SelectAIRecommendationUseCase.java
    │   │   │   ├── RequestImageGenerationUseCase.java
    │   │   │   ├── SelectImageUseCase.java
    │   │   │   ├── EditImageUseCase.java
    │   │   │   ├── SelectDistributionChannelsUseCase.java
    │   │   │   ├── PublishEventUseCase.java
    │   │   │   ├── GetEventListUseCase.java
    │   │   │   ├── GetEventDetailUseCase.java
    │   │   │   ├── UpdateEventUseCase.java
    │   │   │   ├── DeleteEventUseCase.java
    │   │   │   ├── EndEventUseCase.java
    │   │   │   └── GetJobStatusUseCase.java
    │   │   └── out/
    │   │       ├── EventReader.java
    │   │       ├── EventWriter.java
    │   │       ├── JobReader.java
    │   │       ├── JobWriter.java
    │   │       ├── KafkaJobPublisher.java
    │   │       ├── KafkaEventPublisher.java
    │   │       ├── RedisAIDataReader.java
    │   │       ├── RedisImageDataReader.java
    │   │       └── DistributionServiceCaller.java
    │   ├── service/
    │   │   ├── EventCreationService.java
    │   │   ├── EventManagementService.java
    │   │   ├── AIRecommendationService.java
    │   │   ├── ImageGenerationService.java
    │   │   ├── DistributionService.java
    │   │   └── JobStatusService.java
    │   └── dto/
    │       ├── EventCommand.java
    │       ├── EventInfo.java
    │       ├── AIRecommendationInfo.java
    │       ├── ImageInfo.java
    │       ├── ChannelInfo.java
    │       └── JobInfo.java
    └── infra/
        ├── EventApplication.java
        ├── controller/
        │   ├── EventController.java
        │   ├── EventCreationController.java
        │   └── JobController.java
        ├── dto/
        │   ├── request/
        │   │   ├── EventObjectiveRequest.java
        │   │   ├── AIRecommendationSelectionRequest.java
        │   │   ├── ImageSelectionRequest.java
        │   │   ├── ImageEditRequest.java
        │   │   ├── ChannelSelectionRequest.java
        │   │   └── EventUpdateRequest.java
        │   └── response/
        │       ├── EventResponse.java
        │       ├── EventListResponse.java
        │       ├── JobStatusResponse.java
        │       └── PublishResponse.java
        ├── gateway/
        │   ├── entity/
        │   │   ├── EventEntity.java
        │   │   ├── AIRecommendationEntity.java
        │   │   ├── ImageEntity.java
        │   │   ├── DistributionChannelEntity.java
        │   │   └── JobEntity.java
        │   ├── repository/
        │   │   ├── EventJpaRepository.java
        │   │   ├── AIRecommendationJpaRepository.java
        │   │   ├── ImageJpaRepository.java
        │   │   ├── DistributionChannelJpaRepository.java
        │   │   └── JobJpaRepository.java
        │   ├── EventGateway.java
        │   ├── JobGateway.java
        │   ├── KafkaProducerGateway.java
        │   ├── RedisGateway.java
        │   └── DistributionServiceGateway.java
        └── config/
            ├── SecurityConfig.java
            ├── KafkaProducerConfig.java
            ├── RedisConfig.java
            ├── SwaggerConfig.java
            └── FeignConfig.java
```

---

## AI Service 패키지 구조 (Clean Architecture)

```
ai-service/
└── src/main/java/com/kt/event/ai/
    ├── biz/
    │   ├── domain/
    │   │   ├── AIRecommendation.java
    │   │   ├── TrendAnalysis.java
    │   │   ├── EventRecommendation.java
    │   │   └── Job.java
    │   ├── usecase/
    │   │   ├── in/
    │   │   │   ├── GenerateAIRecommendationUseCase.java
    │   │   │   ├── GetJobStatusUseCase.java
    │   │   │   └── GetRecommendationResultUseCase.java
    │   │   └── out/
    │   │       ├── JobReader.java
    │   │       ├── JobWriter.java
    │   │       ├── RedisResultWriter.java
    │   │       ├── RedisResultReader.java
    │   │       ├── TrendAnalyzer.java
    │   │       └── AIModelCaller.java
    │   ├── service/
    │   │   ├── AIRecommendationService.java
    │   │   ├── TrendAnalysisService.java
    │   │   └── JobManagementService.java
    │   └── dto/
    │       ├── AICommand.java
    │       ├── AIResult.java
    │       ├── TrendInfo.java
    │       └── JobInfo.java
    └── infra/
        ├── AIApplication.java
        ├── controller/
        │   └── InternalAIController.java
        ├── dto/
        │   ├── request/
        │   │   └── AIRequestDto.java
        │   └── response/
        │       ├── AIRecommendationResponse.java
        │       ├── JobStatusResponse.java
        │       └── TrendAnalysisResponse.java
        ├── gateway/
        │   ├── entity/
        │   │   └── JobEntity.java
        │   ├── repository/
        │   │   └── JobJpaRepository.java
        │   ├── JobGateway.java
        │   ├── RedisGateway.java
        │   ├── TrendAnalyzerGateway.java
        │   └── ClaudeAPIGateway.java
        ├── consumer/
        │   └── AIJobConsumer.java
        └── config/
            ├── SecurityConfig.java
            ├── KafkaConsumerConfig.java
            ├── RedisConfig.java
            ├── SwaggerConfig.java
            └── ClaudeAPIConfig.java
```

---

## Content Service 패키지 구조 (Clean Architecture)

```
content-service/
└── src/main/java/com/kt/event/content/
    ├── biz/
    │   ├── domain/
    │   │   ├── Content.java
    │   │   ├── GeneratedImage.java
    │   │   ├── ImageStyle.java
    │   │   ├── Platform.java
    │   │   └── Job.java
    │   ├── usecase/
    │   │   ├── in/
    │   │   │   ├── GenerateImagesUseCase.java
    │   │   │   ├── GetJobStatusUseCase.java
    │   │   │   ├── GetEventContentUseCase.java
    │   │   │   ├── GetImageListUseCase.java
    │   │   │   ├── GetImageDetailUseCase.java
    │   │   │   └── RegenerateImageUseCase.java
    │   │   └── out/
    │   │       ├── ContentReader.java
    │   │       ├── ContentWriter.java
    │   │       ├── JobReader.java
    │   │       ├── JobWriter.java
    │   │       ├── RedisAIDataReader.java
    │   │       ├── RedisImageWriter.java
    │   │       ├── ImageGeneratorCaller.java
    │   │       └── CDNUploader.java
    │   ├── service/
    │   │   ├── ImageGenerationService.java
    │   │   ├── ContentManagementService.java
    │   │   └── JobManagementService.java
    │   └── dto/
    │       ├── ContentCommand.java
    │       ├── ContentInfo.java
    │       ├── ImageInfo.java
    │       └── JobInfo.java
    └── infra/
        ├── ContentApplication.java
        ├── controller/
        │   └── ContentController.java
        ├── dto/
        │   ├── request/
        │   │   ├── ImageGenerationRequest.java
        │   │   └── RegenerateRequest.java
        │   └── response/
        │       ├── ContentResponse.java
        │       ├── ImageResponse.java
        │       └── JobStatusResponse.java
        ├── gateway/
        │   ├── entity/
        │   │   ├── ContentEntity.java
        │   │   ├── GeneratedImageEntity.java
        │   │   └── JobEntity.java
        │   ├── repository/
        │   │   ├── ContentJpaRepository.java
        │   │   ├── GeneratedImageJpaRepository.java
        │   │   └── JobJpaRepository.java
        │   ├── ContentGateway.java
        │   ├── JobGateway.java
        │   ├── RedisGateway.java
        │   ├── StableDiffusionGateway.java
        │   └── AzureBlobStorageGateway.java
        ├── consumer/
        │   └── ImageGenerationJobConsumer.java
        └── config/
            ├── SecurityConfig.java
            ├── KafkaConsumerConfig.java
            ├── RedisConfig.java
            ├── SwaggerConfig.java
            └── AzureStorageConfig.java
```

---

## Distribution Service 패키지 구조 (Clean Architecture)

```
distribution-service/
└── src/main/java/com/kt/event/distribution/
    ├── biz/
    │   ├── domain/
    │   │   ├── Distribution.java
    │   │   ├── DistributionChannel.java
    │   │   ├── ChannelResult.java
    │   │   └── DistributionStatus.java
    │   ├── usecase/
    │   │   ├── in/
    │   │   │   ├── DistributeToChannelsUseCase.java
    │   │   │   └── GetDistributionStatusUseCase.java
    │   │   └── out/
    │   │       ├── DistributionReader.java
    │   │       ├── DistributionWriter.java
    │   │       ├── ChannelDistributor.java
    │   │       └── KafkaEventPublisher.java
    │   ├── service/
    │   │   ├── DistributionService.java
    │   │   └── ChannelService.java
    │   └── dto/
    │       ├── DistributionCommand.java
    │       ├── DistributionInfo.java
    │       └── ChannelInfo.java
    └── infra/
        ├── DistributionApplication.java
        ├── controller/
        │   └── DistributionController.java
        ├── dto/
        │   ├── request/
        │   │   └── DistributionRequest.java
        │   └── response/
        │       ├── DistributionResponse.java
        │       └── DistributionStatusResponse.java
        ├── gateway/
        │   ├── entity/
        │   │   ├── DistributionEntity.java
        │   │   └── ChannelResultEntity.java
        │   ├── repository/
        │   │   ├── DistributionJpaRepository.java
        │   │   └── ChannelResultJpaRepository.java
        │   ├── DistributionGateway.java
        │   ├── KafkaProducerGateway.java
        │   └── channel/
        │       ├── UriDongneTVGateway.java
        │       ├── RingoBizGateway.java
        │       ├── GenieTVGateway.java
        │       ├── InstagramGateway.java
        │       ├── NaverBlogGateway.java
        │       └── KakaoChannelGateway.java
        └── config/
            ├── SecurityConfig.java
            ├── KafkaProducerConfig.java
            ├── SwaggerConfig.java
            ├── ResilienceConfig.java
            └── FeignConfig.java
```

---

## Participation Service 패키지 구조 (Clean Architecture)

```
participation-service/
└── src/main/java/com/kt/event/participation/
    ├── biz/
    │   ├── domain/
    │   │   ├── Participant.java
    │   │   ├── Winner.java
    │   │   ├── DrawResult.java
    │   │   └── Consent.java
    │   ├── usecase/
    │   │   ├── in/
    │   │   │   ├── ParticipateEventUseCase.java
    │   │   │   ├── GetParticipantListUseCase.java
    │   │   │   ├── GetParticipantDetailUseCase.java
    │   │   │   ├── DrawWinnersUseCase.java
    │   │   │   └── GetWinnerListUseCase.java
    │   │   └── out/
    │   │       ├── ParticipantReader.java
    │   │       ├── ParticipantWriter.java
    │   │       ├── WinnerReader.java
    │   │       ├── WinnerWriter.java
    │   │       ├── DrawExecutor.java
    │   │       └── KafkaEventPublisher.java
    │   ├── service/
    │   │   ├── ParticipationService.java
    │   │   └── WinnerDrawService.java
    │   └── dto/
    │       ├── ParticipationCommand.java
    │       ├── ParticipantInfo.java
    │       ├── WinnerInfo.java
    │       └── DrawCommand.java
    └── infra/
        ├── ParticipationApplication.java
        ├── controller/
        │   └── ParticipationController.java
        ├── dto/
        │   ├── request/
        │   │   ├── ParticipationRequest.java
        │   │   └── WinnerDrawRequest.java
        │   └── response/
        │       ├── ParticipationResponse.java
        │       ├── ParticipantListResponse.java
        │       └── WinnerResponse.java
        ├── gateway/
        │   ├── entity/
        │   │   ├── ParticipantEntity.java
        │   │   └── WinnerEntity.java
        │   ├── repository/
        │   │   ├── ParticipantJpaRepository.java
        │   │   └── WinnerJpaRepository.java
        │   ├── ParticipantGateway.java
        │   ├── WinnerGateway.java
        │   ├── DrawExecutorGateway.java
        │   └── KafkaProducerGateway.java
        └── config/
            ├── SecurityConfig.java
            ├── KafkaProducerConfig.java
            └── SwaggerConfig.java
```

---

## Analytics Service 패키지 구조 (Clean Architecture)

```
analytics-service/
└── src/main/java/com/kt/event/analytics/
    ├── biz/
    │   ├── domain/
    │   │   ├── EventAnalytics.java
    │   │   ├── ChannelPerformance.java
    │   │   ├── TimelineData.java
    │   │   ├── RoiDetail.java
    │   │   └── ParticipantProfile.java
    │   ├── usecase/
    │   │   ├── in/
    │   │   │   ├── GetAnalyticsDashboardUseCase.java
    │   │   │   ├── GetChannelPerformanceUseCase.java
    │   │   │   ├── GetTimelineDataUseCase.java
    │   │   │   └── GetRoiDetailUseCase.java
    │   │   └── out/
    │   │       ├── AnalyticsReader.java
    │   │       ├── AnalyticsWriter.java
    │   │       ├── ExternalAPIDataCollector.java
    │   │       └── RedisAnalyticsCache.java
    │   ├── service/
    │   │   ├── AnalyticsDashboardService.java
    │   │   ├── PerformanceAnalysisService.java
    │   │   └── RoiCalculationService.java
    │   └── dto/
    │       ├── AnalyticsCommand.java
    │       ├── AnalyticsInfo.java
    │       ├── PerformanceInfo.java
    │       └── RoiInfo.java
    └── infra/
        ├── AnalyticsApplication.java
        ├── controller/
        │   └── AnalyticsController.java
        ├── dto/
        │   └── response/
        │       ├── AnalyticsDashboardResponse.java
        │       ├── ChannelPerformanceResponse.java
        │       ├── TimelineDataResponse.java
        │       └── RoiDetailResponse.java
        ├── gateway/
        │   ├── entity/
        │   │   ├── EventAnalyticsEntity.java
        │   │   ├── ChannelPerformanceEntity.java
        │   │   └── TimelineDataEntity.java
        │   ├── repository/
        │   │   ├── EventAnalyticsJpaRepository.java
        │   │   ├── ChannelPerformanceJpaRepository.java
        │   │   └── TimelineDataJpaRepository.java
        │   ├── AnalyticsGateway.java
        │   ├── RedisGateway.java
        │   └── external/
        │       ├── UriDongneTVAPIGateway.java
        │       ├── GenieTVAPIGateway.java
        │       ├── InstagramAPIGateway.java
        │       ├── NaverAPIGateway.java
        │       └── KakaoAPIGateway.java
        ├── consumer/
        │   └── AnalyticsEventConsumer.java
        └── config/
            ├── SecurityConfig.java
            ├── KafkaConsumerConfig.java
            ├── RedisConfig.java
            ├── SwaggerConfig.java
            ├── ResilienceConfig.java
            └── FeignConfig.java
```

---

## 아키텍처 설명

### Clean Architecture 레이어 구조

1. **biz (Business Layer)** - 비즈니스 로직
   - `domain/`: 핵심 도메인 모델 (순수 Java 객체, 외부 의존성 없음)
   - `usecase/in/`: Inbound Port (비즈니스 로직 진입점 인터페이스)
   - `usecase/out/`: Outbound Port (외부 의존성 인터페이스)
   - `service/`: Use Case 구현체 (비즈니스 로직 실행)
   - `dto/`: 비즈니스 레이어 내부 DTO

2. **infra (Infrastructure Layer)** - 외부 세계와의 통신
   - `controller/`: REST API Controller (Inbound Adapter)
   - `dto/request/`, `dto/response/`: API 계약 DTO
   - `gateway/`: Outbound Adapter (DB, 외부 API, Kafka, Redis 등)
   - `gateway/entity/`: JPA Entity
   - `gateway/repository/`: JPA Repository
   - `consumer/`: Kafka Consumer
   - `config/`: 설정 클래스

### 의존성 규칙

- **biz → infra**: ❌ 불가능 (비즈니스 로직은 인프라에 의존하지 않음)
- **infra → biz**: ✅ 가능 (인프라는 비즈니스 인터페이스를 구현)
- **domain → 외부**: ❌ 불가능 (순수 비즈니스 로직만 포함)

### 네이밍 규칙

- **UseCase 인터페이스**: `{동작}{대상}UseCase` (예: `RegisterUserUseCase`)
- **Service 구현체**: `{대상}Service` (예: `UserService`)
- **Gateway 구현체**: `{대상}Gateway` (예: `UserGateway`)
- **Port 인터페이스**: `{대상}{동작}` (예: `UserReader`, `UserWriter`)

---

## 기술 스택 정리

| 레이어 | 기술 |
|--------|------|
| Framework | Spring Boot 3.3.0, Java 21 |
| Database | PostgreSQL (각 서비스별 독립 DB) |
| Cache | Redis (공통) |
| Message Queue | Kafka (비동기 Job 처리, Event 발행) |
| Security | JWT, Spring Security |
| API Documentation | Swagger UI (SpringDoc OpenAPI) |
| Persistence | Spring Data JPA |
| Build Tool | Gradle 8.x |

---

**작성일**: 2025-10-23
**작성자**: Backend Developer (리액트킹)
