commit
262a5fea33
@ -10,7 +10,9 @@ import com.kt.event.eventservice.domain.entity.*;
|
||||
import com.kt.event.eventservice.domain.enums.EventStatus;
|
||||
import com.kt.event.eventservice.domain.repository.EventRepository;
|
||||
import com.kt.event.eventservice.domain.repository.JobRepository;
|
||||
import com.kt.event.eventservice.infrastructure.client.AIServiceClient;
|
||||
import com.kt.event.eventservice.infrastructure.client.ContentServiceClient;
|
||||
import com.kt.event.eventservice.infrastructure.client.dto.AIRecommendationResponse;
|
||||
import com.kt.event.eventservice.infrastructure.client.dto.ContentImageGenerationRequest;
|
||||
import com.kt.event.eventservice.infrastructure.client.dto.ContentJobResponse;
|
||||
import com.kt.event.eventservice.infrastructure.kafka.AIJobKafkaProducer;
|
||||
@ -43,6 +45,7 @@ public class EventService {
|
||||
|
||||
private final EventRepository eventRepository;
|
||||
private final JobRepository jobRepository;
|
||||
private final AIServiceClient aiServiceClient;
|
||||
private final ContentServiceClient contentServiceClient;
|
||||
private final AIJobKafkaProducer aiJobKafkaProducer;
|
||||
private final ImageJobKafkaProducer imageJobKafkaProducer;
|
||||
@ -611,4 +614,30 @@ public class EventService {
|
||||
.updatedAt(event.getUpdatedAt())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* AI 추천안 조회 (AI Service에서 직접 조회)
|
||||
*
|
||||
* @param userId 사용자 ID
|
||||
* @param eventId 이벤트 ID
|
||||
* @return AI 추천 결과
|
||||
*/
|
||||
public AIRecommendationResponse getAiRecommendations(String userId, String eventId) {
|
||||
log.info("AI 추천안 조회 - userId: {}, eventId: {}", userId, eventId);
|
||||
|
||||
// 이벤트 권한 확인
|
||||
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.EVENT_001));
|
||||
|
||||
// AI Service에서 추천안 조회
|
||||
try {
|
||||
AIRecommendationResponse response = aiServiceClient.getRecommendation(eventId);
|
||||
log.info("AI 추천안 조회 성공 - eventId: {}, 추천안 수: {}",
|
||||
eventId, response.getRecommendations() != null ? response.getRecommendations().size() : 0);
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("AI 추천안 조회 실패 - eventId: {}", eventId, e);
|
||||
throw new BusinessException(ErrorCode.AI_004);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.kt.event.eventservice.infrastructure.client;
|
||||
|
||||
import com.kt.event.eventservice.infrastructure.client.dto.AIRecommendationResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
/**
|
||||
* AI Service Feign Client
|
||||
*
|
||||
* AI Service의 추천안 조회 API를 호출합니다.
|
||||
*
|
||||
* @author Event Service Team
|
||||
* @version 1.0.0
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@FeignClient(
|
||||
name = "ai-service",
|
||||
url = "${feign.ai-service.url:http://localhost:8083}"
|
||||
)
|
||||
public interface AIServiceClient {
|
||||
|
||||
/**
|
||||
* AI 추천 결과 조회
|
||||
*
|
||||
* @param eventId 이벤트 ID
|
||||
* @return AI 추천 결과
|
||||
*/
|
||||
@GetMapping("/recommendations/{eventId}")
|
||||
AIRecommendationResponse getRecommendation(@PathVariable("eventId") String eventId);
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package com.kt.event.eventservice.infrastructure.client.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* AI Service 추천안 응답 DTO
|
||||
*
|
||||
* @author Event Service Team
|
||||
* @version 1.0.0
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AIRecommendationResponse {
|
||||
|
||||
private String eventId;
|
||||
private TrendAnalysis trendAnalysis;
|
||||
private List<EventRecommendation> recommendations;
|
||||
private LocalDateTime generatedAt;
|
||||
private LocalDateTime expiresAt;
|
||||
private String aiProvider;
|
||||
|
||||
/**
|
||||
* 트렌드 분석
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class TrendAnalysis {
|
||||
private List<TrendKeyword> industryTrends;
|
||||
private List<TrendKeyword> regionalTrends;
|
||||
private List<TrendKeyword> seasonalTrends;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class TrendKeyword {
|
||||
private String keyword;
|
||||
private Double relevance;
|
||||
private String description;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 이벤트 추천안
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class EventRecommendation {
|
||||
private Integer optionNumber;
|
||||
private String concept;
|
||||
private String title;
|
||||
private String description;
|
||||
private String targetAudience;
|
||||
private Duration duration;
|
||||
private Mechanics mechanics;
|
||||
private List<String> promotionChannels;
|
||||
private EstimatedCost estimatedCost;
|
||||
private ExpectedMetrics expectedMetrics;
|
||||
private String differentiator;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Duration {
|
||||
private Integer recommendedDays;
|
||||
private String recommendedPeriod;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Mechanics {
|
||||
private String type;
|
||||
private String details;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class EstimatedCost {
|
||||
private Integer min;
|
||||
private Integer max;
|
||||
private Map<String, Integer> breakdown;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class ExpectedMetrics {
|
||||
private Range newCustomers;
|
||||
private Range revenueIncrease;
|
||||
private Range roi;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Range {
|
||||
private Double min;
|
||||
private Double max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import com.kt.event.common.security.UserPrincipal;
|
||||
import com.kt.event.eventservice.application.dto.request.*;
|
||||
import com.kt.event.eventservice.application.dto.response.*;
|
||||
import com.kt.event.eventservice.application.service.EventService;
|
||||
import com.kt.event.eventservice.infrastructure.client.dto.AIRecommendationResponse;
|
||||
import com.kt.event.eventservice.domain.enums.EventStatus;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -287,6 +288,30 @@ public class EventController {
|
||||
.body(ApiResponse.success(response));
|
||||
}
|
||||
|
||||
/**
|
||||
* AI 추천안 조회 (Step 2-1)
|
||||
*
|
||||
* @param eventId 이벤트 ID
|
||||
* @param userPrincipal 인증된 사용자 정보
|
||||
* @return AI 추천 결과
|
||||
*/
|
||||
@GetMapping("/{eventId}/ai-recommendations")
|
||||
@Operation(summary = "AI 추천안 조회", description = "AI Service에서 생성된 추천안을 조회합니다.")
|
||||
public ResponseEntity<ApiResponse<AIRecommendationResponse>> getAiRecommendations(
|
||||
@PathVariable String eventId,
|
||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||
|
||||
log.info("AI 추천안 조회 API 호출 - userId: {}, eventId: {}",
|
||||
userPrincipal.getUserId(), eventId);
|
||||
|
||||
AIRecommendationResponse response = eventService.getAiRecommendations(
|
||||
userPrincipal.getUserId(),
|
||||
eventId
|
||||
);
|
||||
|
||||
return ResponseEntity.ok(ApiResponse.success(response));
|
||||
}
|
||||
|
||||
/**
|
||||
* AI 추천 선택 (Step 2-2)
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user