feat : 피드백 상세 조회 수정(이미 실행된 생성계획이 있다면 패스.)

This commit is contained in:
lsh9672 2025-06-17 13:47:49 +09:00
parent 6e1d9b2ff5
commit 5f05f4af51
5 changed files with 47 additions and 5 deletions

View File

@ -115,7 +115,8 @@ public class AnalyticsService implements AnalyticsUseCase {
// 2. AI 피드백이 없으면 새로 생성 // 2. AI 피드백이 없으면 새로 생성
aiFeedback = Optional.of(generateAIFeedback(storeId)); aiFeedback = Optional.of(generateAIFeedback(storeId));
} }
// 3. 응답 생성 // 3. 응답 생성
AiFeedbackDetailResponse response = AiFeedbackDetailResponse.builder() AiFeedbackDetailResponse response = AiFeedbackDetailResponse.builder()
.feedbackId(aiFeedback.get().getId()) .feedbackId(aiFeedback.get().getId())
@ -128,6 +129,11 @@ public class AnalyticsService implements AnalyticsUseCase {
.confidenceScore(aiFeedback.get().getConfidenceScore()) .confidenceScore(aiFeedback.get().getConfidenceScore())
.generatedAt(aiFeedback.get().getGeneratedAt()) .generatedAt(aiFeedback.get().getGeneratedAt())
.build(); .build();
//(추가) 실행계획을 조회해서, 이미 생성된 improvementPoints인지 판단
List<String> actionPlanTitleList = actionPlanPort.findActionPlanTitleByFeedbackId(aiFeedback.get().getId());
log.info("실행계획 확인 => {}", actionPlanTitleList.toString());
response.updateImprovementCheck(actionPlanTitleList); //이미 생성된 실행계획 추가.
log.info("AI 피드백 상세 조회 완료: storeId={}", storeId); log.info("AI 피드백 상세 조회 완료: storeId={}", storeId);
return response; return response;
@ -492,7 +498,7 @@ public class AnalyticsService implements AnalyticsUseCase {
// 3. DB에 실행계획 저장 // 3. DB에 실행계획 저장
saveGeneratedActionPlansToDatabase(feedback, actionPlans); saveGeneratedActionPlansToDatabase(request.getActionPlanSelect(), feedback, actionPlans);
log.info("실행계획 생성 완료: feedbackId={}, planCount={}", feedbackId, actionPlans.size()); log.info("실행계획 생성 완료: feedbackId={}, planCount={}", feedbackId, actionPlans.size());
return actionPlans; return actionPlans;
@ -579,7 +585,7 @@ public class AnalyticsService implements AnalyticsUseCase {
* 생성된 실행계획을 데이터베이스에 저장하는 메서드 * 생성된 실행계획을 데이터베이스에 저장하는 메서드
* AI 피드백 기반으로 생성된 실행계획들을 ActionPlan 테이블에 저장 * AI 피드백 기반으로 생성된 실행계획들을 ActionPlan 테이블에 저장
*/ */
private void saveGeneratedActionPlansToDatabase(AiFeedback feedback, List<String> actionPlans) { private void saveGeneratedActionPlansToDatabase(List<String> actionPlanSelect, AiFeedback feedback, List<String> actionPlans) {
if (actionPlans.isEmpty()) { if (actionPlans.isEmpty()) {
log.info("저장할 실행계획이 없습니다: storeId={}", feedback.getStoreId()); log.info("저장할 실행계획이 없습니다: storeId={}", feedback.getStoreId());
return; return;
@ -596,7 +602,7 @@ public class AnalyticsService implements AnalyticsUseCase {
.storeId(feedback.getStoreId()) .storeId(feedback.getStoreId())
.userId(0L) // AI가 생성한 계획이므로 userId는 0 .userId(0L) // AI가 생성한 계획이므로 userId는 0
.feedbackId(feedback.getId()) .feedbackId(feedback.getId())
.title("AI 추천 실행계획 " + (i + 1)) .title(actionPlanSelect.get(i))
.description(planContent) .description(planContent)
.period("1개월") // 기본 실행 기간 .period("1개월") // 기본 실행 기간
.status(PlanStatus.PLANNED) .status(PlanStatus.PLANNED)

View File

@ -30,4 +30,9 @@ public interface ActionPlanPort {
* 실행 계획 삭제 * 실행 계획 삭제
*/ */
void deleteActionPlan(Long planId); void deleteActionPlan(Long planId);
/**
* 피드백 id로 실행계획 title 조회
*/
List<String> findActionPlanTitleByFeedbackId(Long feedbackId);
} }

View File

@ -7,6 +7,8 @@ import lombok.NoArgsConstructor;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* AI 피드백 상세 응답 DTO * AI 피드백 상세 응답 DTO
@ -22,8 +24,23 @@ public class AiFeedbackDetailResponse {
private String summary; private String summary;
private List<String> positivePoints; private List<String> positivePoints;
private List<String> improvementPoints; private List<String> improvementPoints;
private List<String> existActionPlan; // improvemnetPoints 중에서 처리 된것.
private List<String> recommendations; private List<String> recommendations;
private String sentimentAnalysis; private String sentimentAnalysis;
private Double confidenceScore; private Double confidenceScore;
private LocalDateTime generatedAt; private LocalDateTime generatedAt;
public void updateImprovementCheck(List<String> actionPlanTitle){
Set<String> trimmedTitles = actionPlanTitle.stream()
.map(String::trim)
.collect(Collectors.toSet());
this.existActionPlan =
improvementPoints.stream()
.map(String::trim)
.filter(point -> trimmedTitles.stream()
.anyMatch(title -> title.contains(point)))
.toList();
}
} }

View File

@ -52,7 +52,12 @@ public class ActionPlanRepositoryAdapter implements ActionPlanPort {
public void deleteActionPlan(Long planId) { public void deleteActionPlan(Long planId) {
actionPlanJpaRepository.deleteById(planId); actionPlanJpaRepository.deleteById(planId);
} }
@Override
public List<String> findActionPlanTitleByFeedbackId(Long feedbackId) {
return actionPlanJpaRepository.findActionPlanTitleByFeedbackId(feedbackId);
}
/** /**
* Entity를 Domain으로 변환 * Entity를 Domain으로 변환
*/ */

View File

@ -3,10 +3,13 @@ package com.ktds.hi.analytics.infra.gateway.repository;
import com.ktds.hi.analytics.biz.domain.PlanStatus; import com.ktds.hi.analytics.biz.domain.PlanStatus;
import com.ktds.hi.analytics.infra.gateway.entity.ActionPlanEntity; import com.ktds.hi.analytics.infra.gateway.entity.ActionPlanEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
import io.lettuce.core.dynamic.annotation.Param;
/** /**
* 실행 계획 JPA 리포지토리 인터페이스 * 실행 계획 JPA 리포지토리 인터페이스
* 실행 계획 데이터의 CRUD 작업을 담당 * 실행 계획 데이터의 CRUD 작업을 담당
@ -33,4 +36,10 @@ public interface ActionPlanJpaRepository extends JpaRepository<ActionPlanEntity,
* 매장 ID와 사용자 ID로 실행 계획 목록 조회 * 매장 ID와 사용자 ID로 실행 계획 목록 조회
*/ */
List<ActionPlanEntity> findByStoreIdAndUserIdOrderByCreatedAtDesc(Long storeId, Long userId); List<ActionPlanEntity> findByStoreIdAndUserIdOrderByCreatedAtDesc(Long storeId, Long userId);
/**
* 피드백 id로 실행계획 title 조회
*/
@Query("SELECT a.title FROM ActionPlanEntity a WHERE a.feedbackId = :feedbackId")
List<String> findActionPlanTitleByFeedbackId(@Param("feedbackId")Long feedbackId);
} }