feat : 고객용 분석을 위해 긍정 요약 내용 저장

This commit is contained in:
lsh9672 2025-06-18 17:37:16 +09:00
parent c2903fdb04
commit 9128e62356
11 changed files with 89 additions and 2 deletions

View File

@ -29,6 +29,9 @@ public class AiFeedback {
private List<String> recommendations; private List<String> recommendations;
private String sentimentAnalysis; private String sentimentAnalysis;
private Double confidenceScore; private Double confidenceScore;
private String positiveSummary;
private LocalDateTime generatedAt; private LocalDateTime generatedAt;
private LocalDateTime createdAt; private LocalDateTime createdAt;
private LocalDateTime updatedAt; private LocalDateTime updatedAt;

View File

@ -537,6 +537,7 @@ public class AnalyticsService implements AnalyticsUseCase {
.recommendations(aiFeedback.getRecommendations()) .recommendations(aiFeedback.getRecommendations())
.sentimentAnalysis(aiFeedback.getSentimentAnalysis()) .sentimentAnalysis(aiFeedback.getSentimentAnalysis())
.confidenceScore(aiFeedback.getConfidenceScore()) .confidenceScore(aiFeedback.getConfidenceScore())
.positiveSummary(aiFeedback.getPositiveSummary())
.totalReviewsAnalyzed(getTotalReviewsCount(storeId, request.getDays())) .totalReviewsAnalyzed(getTotalReviewsCount(storeId, request.getDays()))
.actionPlans(actionPlans) //TODO : 사용하는 값은 아니지만 의존성을 위해 그대로 , 추후에 변경 필요. .actionPlans(actionPlans) //TODO : 사용하는 값은 아니지만 의존성을 위해 그대로 , 추후에 변경 필요.
.analyzedAt(aiFeedback.getGeneratedAt()) .analyzedAt(aiFeedback.getGeneratedAt())
@ -581,6 +582,11 @@ public class AnalyticsService implements AnalyticsUseCase {
} }
} }
@Override
public CustomerPositiveReviewResponse getCustomerPositiveReview(Long storeId) {
return null;
}
/** /**
* 실제 AI를 호출하는 개선된 피드백 생성 메서드 * 실제 AI를 호출하는 개선된 피드백 생성 메서드
* 기존 generateAIFeedback() 하드코딩 부분을 실제 AI 호출로 수정 * 기존 generateAIFeedback() 하드코딩 부분을 실제 AI 호출로 수정
@ -613,6 +619,7 @@ public class AnalyticsService implements AnalyticsUseCase {
.recommendations(aiFeedback.getRecommendations()) .recommendations(aiFeedback.getRecommendations())
.sentimentAnalysis(aiFeedback.getSentimentAnalysis()) .sentimentAnalysis(aiFeedback.getSentimentAnalysis())
.confidenceScore(aiFeedback.getConfidenceScore()) .confidenceScore(aiFeedback.getConfidenceScore())
.positiveSummary(aiFeedback.getPositiveSummary())
.generatedAt(LocalDateTime.now()) .generatedAt(LocalDateTime.now())
.createdAt(LocalDateTime.now()) .createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now()) .updatedAt(LocalDateTime.now())

View File

@ -46,4 +46,8 @@ public interface AnalyticsUseCase {
*/ */
List<String> generateActionPlansFromFeedback(ActionPlanCreateRequest request,Long feedbackId); List<String> generateActionPlansFromFeedback(ActionPlanCreateRequest request,Long feedbackId);
// 🔥 고객용 긍정 리뷰 조회 API 추가
CustomerPositiveReviewResponse getCustomerPositiveReview(Long storeId);
} }

View File

@ -35,4 +35,12 @@ public interface AIServicePort {
* 실행 계획 생성 * 실행 계획 생성
*/ */
List<String> generateActionPlan(List<String> actionPlanSelect, AiFeedback feedback); List<String> generateActionPlan(List<String> actionPlanSelect, AiFeedback feedback);
// 🔥 고객용 긍정 리뷰 요약 생성 메서드 추가
/**
* 긍정적인 리뷰만을 분석하여 고객용 요약 생성
* @param positiveReviews 긍정적인 리뷰 목록
* @return 고객에게 보여줄 긍정적인 요약
*/
String generateCustomerPositiveSummary(List<String> positiveReviews);
} }

View File

@ -18,6 +18,14 @@ public interface ExternalReviewPort {
*/ */
List<String> getRecentReviews(Long storeId, Integer days); List<String> getRecentReviews(Long storeId, Integer days);
// 🔥 긍정적인 리뷰만 조회하는 메서드 추가
/**
* 긍정적인 리뷰만 조회 (평점 4점 이상)
* @param storeId 매장 ID
* @param days 조회 기간 ()
* @return 긍정적인 리뷰 목록
*/
List<String> getPositiveReviews(Long storeId, Integer days);
/** /**
* 리뷰 개수 조회 * 리뷰 개수 조회

View File

@ -43,6 +43,9 @@ public class AiAnalysisResponse {
@Schema(description = "감정 분석 결과") @Schema(description = "감정 분석 결과")
private String sentimentAnalysis; private String sentimentAnalysis;
@Schema(description = "긍정 분석 요약")
private String positiveSummary;
@Schema(description = "신뢰도 점수") @Schema(description = "신뢰도 점수")
private Double confidenceScore; private Double confidenceScore;

View File

@ -0,0 +1,35 @@
package com.ktds.hi.analytics.infra.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
/**
* 고객용 긍정 리뷰 응답 DTO
*/
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "고객용 긍정 리뷰 응답")
public class CustomerPositiveReviewResponse {
@Schema(description = "매장 ID")
private Long storeId;
@Schema(description = "긍정적인 리뷰 요약")
private String positiveSummary;
@Schema(description = "분석된 총 리뷰 수")
private Integer totalReviewsAnalyzed;
@Schema(description = "분석 일시")
private LocalDateTime analyzedAt;
}

View File

@ -275,6 +275,11 @@ public class AIServiceAdapter implements AIServicePort {
} }
} }
@Override
public String generateCustomerPositiveSummary(List<String> positiveReviews) {
return "";
}
/** /**
* OpenAI API를 호출하여 전체 리뷰 분석 수행 * OpenAI API를 호출하여 전체 리뷰 분석 수행
*/ */
@ -286,13 +291,14 @@ public class AIServiceAdapter implements AIServicePort {
다음은 매장의 고객 리뷰들입니다. 이를 분석하여 다음 JSON 형식으로 답변해주세요: 다음은 매장의 고객 리뷰들입니다. 이를 분석하여 다음 JSON 형식으로 답변해주세요:
{ {
"summary": "전체적인 분석 요약(2-3문장)", "summary": "전체적인 분석 요약(1-2문장)",
"positivePoints": ["긍정적 요소1", "긍정적 요소2", "긍정적 요소3"], "positivePoints": ["긍정적 요소1", "긍정적 요소2", "긍정적 요소3"],
"negativePoints": ["부정적 요소1", "부정적 요소2", "부정적 요소3"], "negativePoints": ["부정적 요소1", "부정적 요소2", "부정적 요소3"],
"improvementPoints": ["개선점1", "개선점2", "개선점3"], "improvementPoints": ["개선점1", "개선점2", "개선점3"],
"recommendations": ["추천사항1", "추천사항2", "추천사항3"], "recommendations": ["추천사항1", "추천사항2", "추천사항3"],
"sentimentAnalysis": "전체적인 감정 분석 결과", "sentimentAnalysis": "전체적인 감정 분석 결과",
"confidenceScore": 0.85 "confidenceScore": 0.85
"positiveSummary": "리뷰중에 긍정적인 내용만 분석 요약(1~2문장)"
} }
리뷰 목록: 리뷰 목록:
@ -306,6 +312,7 @@ public class AIServiceAdapter implements AIServicePort {
4. 신뢰도 점수는 0.0-1.0 사이의 값으로 리뷰정보를 보고 적절히 판단. 4. 신뢰도 점수는 0.0-1.0 사이의 값으로 리뷰정보를 보고 적절히 판단.
5. summary에는 전체적인 리뷰 분석에 대한 요약이 담기게 작성하고 **같은 강조하는 문자 없이 텍스트로만 나타내주세요 5. summary에는 전체적인 리뷰 분석에 대한 요약이 담기게 작성하고 **같은 강조하는 문자 없이 텍스트로만 나타내주세요
6. 분석한 내용에 `(백틱) 들어가지 않도록 해주세요. 6. 분석한 내용에 `(백틱) 들어가지 않도록 해주세요.
7. positiveSummary에는 긍정적인 내용만 있어야 합니다, summary에 있는 내용에서 긍정적인 부분만 작성해주세요.
""", """,
reviewsText reviewsText
); );
@ -402,6 +409,7 @@ public class AIServiceAdapter implements AIServicePort {
.improvementPoints((List<String>) result.get("improvementPoints")) .improvementPoints((List<String>) result.get("improvementPoints"))
.recommendations((List<String>) result.get("recommendations")) .recommendations((List<String>) result.get("recommendations"))
.sentimentAnalysis((String) result.get("sentimentAnalysis")) .sentimentAnalysis((String) result.get("sentimentAnalysis"))
.positiveSummary((String) result.get("positiveSummary"))
.confidenceScore(((Number) result.get("confidenceScore")).doubleValue()) .confidenceScore(((Number) result.get("confidenceScore")).doubleValue())
.generatedAt(LocalDateTime.now()) .generatedAt(LocalDateTime.now())
.build(); .build();

View File

@ -109,6 +109,7 @@ public class AnalyticsRepositoryAdapter implements AnalyticsPort {
.improvementPoints(parseJsonToList(entity.getImprovementPointsJson())) .improvementPoints(parseJsonToList(entity.getImprovementPointsJson()))
.recommendations(parseJsonToList(entity.getRecommendationsJson())) .recommendations(parseJsonToList(entity.getRecommendationsJson()))
.sentimentAnalysis(entity.getSentimentAnalysis()) .sentimentAnalysis(entity.getSentimentAnalysis())
.positiveSummary(entity.getPositiveSummary())
.confidenceScore(entity.getConfidenceScore()) .confidenceScore(entity.getConfidenceScore())
.generatedAt(entity.getGeneratedAt()) .generatedAt(entity.getGeneratedAt())
.createdAt(entity.getCreatedAt()) .createdAt(entity.getCreatedAt())
@ -128,6 +129,7 @@ public class AnalyticsRepositoryAdapter implements AnalyticsPort {
.negativePointsJson(parseListToJson(domain.getNegativePoints())) .negativePointsJson(parseListToJson(domain.getNegativePoints()))
.improvementPointsJson(parseListToJson(domain.getImprovementPoints())) .improvementPointsJson(parseListToJson(domain.getImprovementPoints()))
.recommendationsJson(parseListToJson(domain.getRecommendations())) .recommendationsJson(parseListToJson(domain.getRecommendations()))
.positiveSummary(domain.getPositiveSummary())
.sentimentAnalysis(domain.getSentimentAnalysis()) .sentimentAnalysis(domain.getSentimentAnalysis())
.confidenceScore(domain.getConfidenceScore()) .confidenceScore(domain.getConfidenceScore())
.generatedAt(domain.getGeneratedAt()) .generatedAt(domain.getGeneratedAt())

View File

@ -153,6 +153,11 @@ public class ExternalReviewAdapter implements ExternalReviewPort {
} }
} }
@Override
public List<String> getPositiveReviews(Long storeId, Integer days) {
return List.of();
}
@Override @Override
public Integer getReviewCount(Long storeId) { public Integer getReviewCount(Long storeId) {
log.info("리뷰 개수 조회: storeId={}", storeId); log.info("리뷰 개수 조회: storeId={}", storeId);

View File

@ -58,6 +58,10 @@ public class AiFeedbackEntity {
@Column(name = "confidence_score") @Column(name = "confidence_score")
private Double confidenceScore; private Double confidenceScore;
// 🔥 고객용 긍정 리뷰 요약 컬럼 추가
@Column(name = "customer_positive_summary", columnDefinition = "TEXT")
private String positiveSummary;
@Column(name = "generated_at") @Column(name = "generated_at")
private LocalDateTime generatedAt; private LocalDateTime generatedAt;