Skip to content

[LLM] 추천 결과 및 상세 페이지 추가#39

Merged
usn757 merged 15 commits into
PETTY-HUB:mainfrom
s0ooo0k:feat/regionSearch3
May 25, 2025
Merged

[LLM] 추천 결과 및 상세 페이지 추가#39
usn757 merged 15 commits into
PETTY-HUB:mainfrom
s0ooo0k:feat/regionSearch3

Conversation

@s0ooo0k
Copy link
Copy Markdown
Member

@s0ooo0k s0ooo0k commented May 24, 2025

📜 PR 내용 요약

  • 추천 결과 페이지 카드 형태 출력
  • 각 카드 클릭 시 상세 페이지 연결
    image
    image

⚒️ 작업 및 변경 내용(상세하게)

  • vision - report - recommend 로 연결 과정을 통합하였습니다
  • GeminiRerankingService - Gemini Rerank 서비스를 도입하여 추천의 정확도를 높였습니다
    • 프롬프팅을 통해 사용자의 요구 사항에 맞지 않는 장소는 제외
    • 추후 카테고리 관련하여 논의 후 프롬프트 보충 예정
  • 추천 결과를 카드 형태로 출력되게 하였습니다. (디자인 통일)
  • contentId를 이용하여 각 카드 클릭 시 장소 상세보기 페이지로 이동하는 기능 추가
    • 상세 페이지 시 뒤로가기 기능 추가
  • UnifiedFlowController 의 세션 제거 파트 리팩토링
    • 기존 추천 결과 페이지에서 세션에 저장된 정보 삭제 기능을, 새로운 분석 시작 시에 삭제되도록 변경
    • GET /analyze 메서드 변경 참고

📚 기타 참고 사항

  • 유사도 검색과 Gemini Rerank 관련하여 카테고리 파트를 추가해야 될지 테스트 부탁드립니다.
  • 카드 리스트 및 상세 페이지로 넘어가는 파트에서 이슈가 없는지 확인 부탁드립니다.

@s0ooo0k
Copy link
Copy Markdown
Member Author

s0ooo0k commented May 24, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2025

Summary by CodeRabbit

  • 신규 기능

    • 여행지 상세 정보를 보여주는 추천 상세 페이지가 추가되었습니다.
    • 추천 결과 카드 클릭 시 상세 페이지로 이동할 수 있습니다.
  • 기능 개선

    • 추천 결과 카드에 추천 이유, 가능 동물, 동반 유형, 준비물 등 추가 정보가 표시됩니다.
    • 추천 결과의 시각적 레이아웃이 개선되어 더 보기 쉽고 깔끔하게 변경되었습니다.
  • 버그 수정

    • 분석 시작 시 이전 추천 및 리포트 세션 데이터가 초기화되어 잘못된 정보가 표시되는 문제를 방지합니다.
  • 스타일

    • 추천 결과와 상세 페이지에 새로운 스타일이 적용되어 사용자 경험이 향상되었습니다.
  • 문서화

    • 여행지 상세 정보를 위한 신규 HTML 템플릿이 추가되었습니다.

Walkthrough

추천 컨트롤러가 기존 REST API에서 HTML 뷰 렌더링을 지원하도록 변경되었으며, 추천 상세 페이지를 위한 새로운 GET 엔드포인트와 템플릿이 추가되었습니다. 추천 서비스와 재정렬 로직이 Document 기반으로 변경되고, 추천 결과 템플릿과 스타일이 확장되었습니다. 세션 데이터 초기화 로직도 일부 컨트롤러에 추가되었습니다.

Changes

파일/경로 요약 변경 내용 요약
.../controller/RecommendController.java @RestController@Controller로 변경, /api/recommend POST 엔드포인트 명시 및 @ResponseBody 추가, /recommend/detail/{contentId} GET 엔드포인트 신설, TourService 의존성 주입, 에러 처리 추가
.../dto/RecommendResponseDTO.java record 선언부 공백 및 포맷팅 수정, 구조 및 필드 변경 없음
.../service/GeminiRerankingService.java rerankGemini 메서드 입력을 PlaceRecommend 리스트 → Document 리스트로 변경, 프롬프트 및 JSON 포맷 확장(추천 이유 100자, 타입 필터링 등), 내부 로직 수정
.../service/RecommendServiceImpl.java 추천 로직이 PlaceRecommend 리스트 대신 Document 리스트를 GeminiRerankingService에 전달, rerank 결과를 받아 ContentService로 상세정보 보강, 중복 필터링 및 buildRecommendResponse 메서드 신규 구현, 불필요 메서드 제거
.../pipeline/controller/UnifiedFlowController.java 분석 페이지 진입 및 POST 분석 시 세션 속성(추천 결과 등) 명시적 초기화 추가, 추천 결과 표시 후 세션 삭제 주석 처리, 일부 메서드 시그니처에 주석 파라미터 추가
.../tour/repository/PetTourInfoRepository.java java.util.List import 추가, 인터페이스/메서드 변경 없음
.../static/css/result.css 추천 그리드 및 카드 레이아웃, 이미지, 텍스트에 대한 신규 CSS 스타일 추가
.../static/js/flow.js 파일 끝에 개행 추가, 코드 로직 변경 없음
.../templates/recommend_detail.html 여행지 상세 정보 표시를 위한 신규 Thymeleaf 템플릿 추가, 에러 및 데이터 조건부 렌더링, 반응형 레이아웃 및 스타일 포함
.../templates/recommendation_result.html 각 추천 카드를 상세 페이지 링크로 래핑, 반복 변수 및 조건식 변경, 카드 내 추천 이유/동물/유형/준비물 필드 추가, .card-link 스타일 추가

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RecommendController
    participant RecommendServiceImpl
    participant GeminiRerankingService
    participant ContentService
    participant TourService
    participant View

    User->>RecommendController: POST /api/recommend (promptMap)
    RecommendController->>RecommendServiceImpl: recommend(promptMap)
    RecommendServiceImpl->>GeminiRerankingService: rerankGemini(userPrompt, List<Document>)
    GeminiRerankingService-->>RecommendServiceImpl: GeminiRerankResponseDTO
    RecommendServiceImpl->>ContentService: getContentById (for each ranked place)
    ContentService-->>RecommendServiceImpl: Content details
    RecommendServiceImpl-->>RecommendController: RecommendResponseDTO
    RecommendController-->>User: JSON 응답

    User->>RecommendController: GET /recommend/detail/{contentId}
    RecommendController->>TourService: getTourDetail(contentId)
    TourService-->>RecommendController: Detail data
    RecommendController->>View: recommend_detail.html 렌더링
    View-->>User: 상세 페이지 표시
Loading

Possibly related PRs

Poem

🐰
추천 카드가 반짝반짝,
상세 페이지로 hop hop!
문서와 서비스가 손잡고,
여행지 정보가 쏙쏙.
토끼는 오늘도 즐겁게
코드를 뛰어넘어
새로운 여행을 꿈꿔요!

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (3)
src/main/java/io/github/petty/llm/service/GeminiRerankingService.java (2)

44-91: 🛠️ Refactor suggestion

프롬프트 개선사항이 우수합니다.

프롬프트의 다음 개선사항들이 매우 좋습니다:

  • 추천 이유 길이를 100자로 증가
  • 자연스러운 평문 요구
  • 반려동물 조건 부합 필터링 강화
  • 장소 타입별 필터링 추가

하지만 메타데이터 접근 시 안전성 개선이 필요합니다.

메타데이터 필드 접근 시 null 안전성을 개선해주세요:

-            String contentId = (String) doc.getMetadata().get("contentId");
-            String title = (String) doc.getMetadata().get("title");
-            String addr = (String) doc.getMetadata().get("address");
+            String contentId = (String) doc.getMetadata().getOrDefault("contentId", "Unknown");
+            String title = (String) doc.getMetadata().getOrDefault("title", "제목 없음");
+            String addr = (String) doc.getMetadata().getOrDefault("address", "주소 없음");

118-124: ⚠️ Potential issue

중복된 상태 코드 검사를 제거해주세요.

동일한 상태 코드 검사가 두 번 반복되고 있습니다. 중복 코드를 제거해야 합니다.

다음과 같이 중복 코드를 제거해주세요:

         if (response.statusCode() != 200) {
             throw new RuntimeException("Gemini API 호출 실패: " + response.statusCode());
         }
 
-        if (response.statusCode() != 200) {
-            throw new RuntimeException("Gemini API 호출 실패: " + response.statusCode());
-        }
-
         GeminiResponseDTO resp = objectMapper.readValue(response.body(), GeminiResponseDTO.class);
src/main/java/io/github/petty/llm/service/RecommendServiceImpl.java (1)

70-74: ⚠️ Potential issue

Null 안전성 개선 필요

isDanger가 null일 경우 NullPointerException이 발생할 수 있습니다.

다음과 같이 null-safe 비교를 사용하세요:

-if (isDanger.equals("true")) {
+if ("true".equals(isDanger)) {
     sb.append("맹견이에요\n");
 } else {
     sb.append("소형견, 중형견이에요\n");
 }
🧹 Nitpick comments (7)
src/main/java/io/github/petty/llm/controller/RecommendController.java (2)

22-26: 컨트롤러 역할 분리 고려

동일한 컨트롤러에서 REST API와 HTML 뷰를 모두 처리하고 있습니다. 향후 유지보수를 위해 API 엔드포인트와 웹 페이지 컨트롤러를 분리하는 것을 고려해보세요.


38-51: 상세 페이지 엔드포인트 개선 제안

에러 처리는 적절하나 다음 사항들을 고려해보세요:

  1. contentId 유효성 검증 추가 (예: 음수 값 체크)
  2. 일반 Exception 대신 구체적인 예외 처리 고려

다음과 같이 개선할 수 있습니다:

 public String getRecommendDetail(@PathVariable String contentId, Model model) {
     try {
         Long id = Long.parseLong(contentId);
+        if (id <= 0) {
+            model.addAttribute("error", "유효하지 않은 콘텐츠 ID입니다: " + contentId);
+            return "recommend_detail";
+        }
         DetailCommonDto contentDetail = tourService.getContentDetailById(id);
         model.addAttribute("contentDetail", contentDetail);
         return "recommend_detail";
     } catch (NumberFormatException e) {
         model.addAttribute("error", "잘못된 콘텐츠 ID입니다: " + contentId);
         return "recommend_detail";
-    } catch (Exception e) {
+    } catch (IllegalArgumentException e) {
+        model.addAttribute("error", "콘텐츠를 찾을 수 없습니다: " + contentId);
+        return "recommend_detail";
+    } catch (RuntimeException e) {
         model.addAttribute("error", "콘텐츠 정보를 불러오는데 실패했습니다: " + e.getMessage());
         return "recommend_detail";
     }
 }
src/main/resources/templates/recommend_detail.html (1)

9-165: CSS를 외부 파일로 분리 권장

템플릿 내 인라인 CSS가 너무 많습니다. 유지보수성을 위해 외부 CSS 파일로 분리하는 것을 고려해보세요.

/static/css/recommend_detail.css 파일을 생성하고 다음과 같이 참조하세요:

 <th:block layout:fragment="css">
-    <style>
-        /* 모든 CSS 내용 */
-    </style>
+    <link rel="stylesheet" th:href="@{/css/recommend_detail.css}">
 </th:block>
src/main/java/io/github/petty/pipeline/controller/UnifiedFlowController.java (2)

52-55: 중복된 세션 제거 로직

POST 핸들러에서 세션을 다시 제거하는 것은 불필요해 보입니다. GET 요청에서 이미 제거했기 때문입니다.

POST 핸들러에서 중복 제거 로직을 삭제하거나 주석으로 이유를 명시하세요:

-// 세션 한 번 더 제거
-session.removeAttribute("recommendationResult");
-session.removeAttribute("visionReport");
-session.removeAttribute("lastAccessTime");
+// GET 요청에서 이미 세션을 정리했으므로 추가 제거 불필요

118-119: 주석 처리된 코드 정리 필요

  1. is_danger 파라미터가 주석 처리되어 있습니다
  2. 결과 표시 후 세션 제거 로직이 주석 처리되어 있습니다

사용하지 않는 코드는 삭제하거나, 향후 계획이 있다면 TODO 주석을 추가하세요:

-//  @RequestParam("is_danger") String isDanger,
+// TODO: 맹견 여부 파라미터 추가 예정
+// @RequestParam("is_danger") String isDanger,

Also applies to: 182-185

src/main/java/io/github/petty/llm/service/RecommendServiceImpl.java (2)

5-5: 사용하지 않는 import 제거

PointsInternalService가 사용되지 않고 있습니다.

-import io.qdrant.client.grpc.PointsInternalService;

114-163: 추천 응답 생성 로직 확인

중복 제거와 에러 처리가 적절히 구현되어 있습니다.

로그 레벨 개선을 고려해보세요:

-log.error("contentId {}에 대한 정보 조회 중 오류 발생: {}", contentId, e.getMessage());
+log.warn("contentId {}에 대한 정보 조회 실패, 건너뜁니다: {}", contentId, e.getMessage());
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b57a46 and 4971271.

📒 Files selected for processing (10)
  • src/main/java/io/github/petty/llm/controller/RecommendController.java (2 hunks)
  • src/main/java/io/github/petty/llm/dto/RecommendResponseDTO.java (2 hunks)
  • src/main/java/io/github/petty/llm/service/GeminiRerankingService.java (5 hunks)
  • src/main/java/io/github/petty/llm/service/RecommendServiceImpl.java (7 hunks)
  • src/main/java/io/github/petty/pipeline/controller/UnifiedFlowController.java (4 hunks)
  • src/main/java/io/github/petty/tour/repository/PetTourInfoRepository.java (1 hunks)
  • src/main/resources/static/css/result.css (1 hunks)
  • src/main/resources/static/js/flow.js (1 hunks)
  • src/main/resources/templates/recommend_detail.html (1 hunks)
  • src/main/resources/templates/recommendation_result.html (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/io/github/petty/llm/controller/RecommendController.java (1)
src/main/java/io/github/petty/IndexController.java (1)
  • Controller (7-32)
🔇 Additional comments (12)
src/main/resources/static/js/flow.js (1)

141-141: 개행 추가 승인
파일 끝에 개행(newline)을 추가하여 POSIX 호환성을 확보했습니다.

src/main/resources/static/css/result.css (1)

1-26: 잘 작성된 CSS 스타일입니다.

추천 카드 레이아웃을 위한 CSS가 매우 잘 구현되었습니다:

  • CSS Grid의 repeat(auto-fill, minmax(280px, 1fr)) 사용으로 반응형 디자인 구현
  • 적절한 패딩, 마진, 그림자 효과로 시각적 계층 구조 명확화
  • object-fit: cover를 통한 이미지 비율 유지
  • 일관된 간격 설정으로 깔끔한 UI 제공
src/main/java/io/github/petty/llm/dto/RecommendResponseDTO.java (1)

6-21: 코드 포맷팅 개선이 잘 되었습니다.

일관된 코드 스타일을 위한 포맷팅 변경이 적절하게 적용되었습니다. 기능적 변경 없이 가독성만 향상되었습니다.

src/main/resources/templates/recommendation_result.html (3)

72-82: 카드 링크 스타일이 잘 구현되었습니다.

전체 카드를 클릭 가능하게 만드는 CSS 스타일이 적절하게 구현되었습니다. text-decoration: nonecolor: inherit를 통해 링크임을 숨기면서도 사용성을 향상시켰습니다.


102-105: Null 안전성이 잘 구현되었습니다.

Elvis 연산자(?:)를 사용하여 null 값에 대한 fallback 텍스트 "정보 없음"을 제공하는 것이 좋은 구현입니다. 사용자 경험을 향상시킵니다.


91-109:

Details

❓ Verification inconclusive

데이터 바인딩 변경사항을 검증해주세요.

템플릿에서 ${recommendationResponse}에서 ${recommendation}으로 데이터 바인딩이 변경되었고, 새로운 필드들(추천 이유, 가능 동물 등)이 추가되었습니다. 컨트롤러에서 올바른 모델 속성을 전달하는지 확인이 필요합니다.

다음 스크립트로 컨트롤러의 모델 속성 설정을 확인해보겠습니다:


🏁 Script executed:

#!/bin/bash
# RecommendController에서 모델 속성 설정 확인
ast-grep --pattern 'model.addAttribute("recommendation", $_)'

# 또는 rg로 모델 속성 설정 확인
rg "addAttribute.*recommendation" -A 2 -B 2

Length of output: 1578


🏁 Script executed:

#!/bin/bash
# RecommendResponseDTO 정의 확인
rg "class RecommendResponseDTO" -A 50 -B 0

# 추천 리스트 아이템 DTO(Place) 정의 확인
rg "class .*Recommend.*DTO" -A 50 -B 0

Length of output: 85


#!/bin/bash
# RecommendService 클래스 및 recommend 메서드 시그니처 확인
rg "class .*RecommendService" -n src/main/java/io/github/petty/pipeline/service
rg "recommend(" -n src/main/java/io/github/petty/pipeline/service

# RecommendResponseDTO 또는 DTO 패키지 내 클래스 검색
rg "package .*dto" -n src/main/java/io/github/petty/pipeline
rg "class .*ResponseDTO" -n src/main/java/io/github/petty/pipeline

#!/bin/bash
# 프로젝트 내 Recommend 관련 Java 파일 목록 확인
find src/main/java -type f -name "*Recommend*.java"

# RecommendResponse 또는 Recommendation DTO 클래스 정의 검색
rg "class .*RecommendResponse" -n src/main/java
rg "class .*Recommendation" -n src/main/java

#!/bin/bash
# 프로젝트의 pipeline 패키지 내 파일 구조 살펴보기
find src/main/java/io/github/petty/pipeline -maxdepth 4 -type f

# DTO 또는 응답 모델 클래스 검색
rg "class .*(Response|Recommendation|Result).*" -n src/main/java/io/github/petty/pipeline

# 서비스 클래스 및 recommend 메서드 확인
rg "class .*Service" -n src/main/java/io/github/petty/pipeline/service
rg "recommend(" -n src/main/java/io/github/petty/pipeline/service

컨트롤러에서 전달되는 recommendation 모델 속성 검증 필요

템플릿에서 ${recommendationResponse}${recommendation}으로 바인딩이 변경되었고, 다음과 같은 새로운 필드를 사용하고 있습니다. 컨트롤러와 DTO(또는 응답 모델)에서 이들이 올바르게 설정되는지 확인해주세요.

  • UnifiedFlowController.java (라인 178)
    • model.addAttribute("recommendation", recommendation);
  • PipelineController.java (라인 58)
    • model.addAttribute("recommendation", prompt);

검증 포인트:

  • recommendation 객체에
    • List<?> recommend 필드가 존재하는지
    • 각 요소에 contentId, imageUrl, title, addr
      recommendReason, acmpyPsblCpam, acmpyTypeCd, acmpyNeedMtr 필드 및 getter가 정의되어 있는지
  • 서비스 로직에서 해당 필드들이 정상적으로 채워지는지

위 사항을 확인 후 템플릿 바인딩이 정상 동작하는지 검증 부탁드립니다.

src/main/java/io/github/petty/llm/service/GeminiRerankingService.java (2)

32-42: 메서드 시그니처 변경이 적절합니다.

List<RecommendResponseDTO.PlaceRecommend>에서 List<Document>로 변경한 것은 재정렬 로직을 더 명확하게 분리하는 좋은 개선입니다. 관심사의 분리 원칙을 잘 적용했습니다.


72-76: 프롬프트 지시사항이 잘 개선되었습니다.

특히 다음 개선사항들이 우수합니다:

  • 추천 이유를 자연스러운 평문으로 요구
  • 반려동물 동반 불가능한 장소 제외
  • 사용자 지정 장소 타입별 필터링

이러한 개선으로 추천 품질이 크게 향상될 것으로 예상됩니다.

src/main/java/io/github/petty/llm/controller/RecommendController.java (1)

28-34: API 엔드포인트 변경 사항 확인됨

기존 JSON 응답을 유지하면서 /api/recommend 경로로 명시적으로 매핑한 것이 좋습니다.

src/main/resources/templates/recommend_detail.html (1)

228-276: 반려동물 정보 섹션 구현 확인

조건부 렌더링과 null 체크가 적절히 구현되어 있습니다.

src/main/java/io/github/petty/pipeline/controller/UnifiedFlowController.java (1)

27-29:

Details

❌ Incorrect review comment

의존성 주입 중복 확인 필요

VisionUseCaseVisionServiceImpl이 모두 주입되어 있습니다. 주석에서도 언급했듯이, 이는 중복일 가능성이 있습니다.

다음 스크립트로 두 클래스의 관계를 확인해보세요:


🏁 Script executed:

#!/bin/bash
# VisionServiceImpl이 VisionUseCase를 구현하는지 확인
ast-grep --pattern 'class VisionServiceImpl implements $$$VisionUseCase$$$'

# 두 서비스의 사용처 확인
rg -A 3 "visionUseCase\." 
rg -A 3 "visionService\."

Length of output: 1693


의존성 주입 구조 검토 완료

VisionUseCase(interim 생성)와 VisionServiceImpl(analyze 실행)는 서로 다른 책임을 수행하므로 중복이 아닙니다.

  • 현재 두 필드는 각기 다른 메서드(interim, analyze)를 호출하기 위해 주입된 것이 맞습니다.
  • 다만, 구체 클래스에 직접 의존하지 않도록 VisionServiceImpl 대신 VisionService 인터페이스를 주입하거나, 필드명을 visionServiceImpl 등으로 명확히 표기하는 것을 권장합니다.

Likely an incorrect or invalid review comment.

src/main/java/io/github/petty/llm/service/RecommendServiceImpl.java (1)

42-46: 빈 검색 결과 처리 적절함

검색 결과가 없을 때 빈 리스트를 반환하는 것이 사용자 경험 측면에서 좋습니다.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

import 사용 여부를 확인해주세요.

java.util.List import가 추가되었지만, 현재 인터페이스에서는 List 타입을 사용하는 메서드가 보이지 않습니다. 실제 사용처가 있는지 확인이 필요합니다.

다음 스크립트로 이 import의 실제 사용을 확인해보겠습니다:


🏁 Script executed:

#!/bin/bash
# PetTourInfoRepository에서 List 타입 사용을 확인
ast-grep --pattern 'interface PetTourInfoRepository {
  $$$
  List<$_> $_($$$);
  $$$
}'

# 또는 rg로 List 사용을 확인
rg "List" src/main/java/io/github/petty/tour/repository/PetTourInfoRepository.java -A 3 -B 3

Length of output: 333


java.util.List import 제거 요청

현재 PetTourInfoRepository.java에서 java.util.List가 실제로 사용되지 않고 있으므로 불필요한 import입니다. 아래와 같이 제거 부탁드립니다.

  • 파일: src/main/java/io/github/petty/tour/repository/PetTourInfoRepository.java
  • 라인: 8
-import java.util.List;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import java.util.List;
🤖 Prompt for AI Agents
In src/main/java/io/github/petty/tour/repository/PetTourInfoRepository.java at
line 8, the import statement for java.util.List is not used anywhere in the
interface. Remove this unused import statement to clean up the code and avoid
unnecessary imports.

Comment on lines +214 to +219
<div th:if="${contentDetail.homepage}" class="detail-item">
<strong>🌐 홈페이지:</strong>
<span>
<a th:href="${contentDetail.homepage}" target="_blank" rel="noopener">홈페이지 바로가기</a>
</span>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

외부 링크 보안 개선 필요

target="_blank"를 사용하는 외부 링크에 보안 속성이 누락되었습니다.

이미 rel="noopener"가 있지만 noreferrer도 추가하는 것이 좋습니다:

-<a th:href="${contentDetail.homepage}" target="_blank" rel="noopener">홈페이지 바로가기</a>
+<a th:href="${contentDetail.homepage}" target="_blank" rel="noopener noreferrer">홈페이지 바로가기</a>
🤖 Prompt for AI Agents
In src/main/resources/templates/recommend_detail.html around lines 214 to 219,
the external link uses target="_blank" with rel="noopener" but is missing
rel="noreferrer" for improved security. Update the anchor tag's rel attribute to
include both "noopener" and "noreferrer" to enhance protection against potential
security risks when opening new tabs.

@usn757
Copy link
Copy Markdown
Contributor

usn757 commented May 25, 2025

PR 잘 검토했습니다. 사용자 경험 개선부터 추천 시스템의 핵심 로직 강화까지 매우 인상적인 업데이트입니다. 주요 변경 사항과 긍정적인 부분들을 아래와 같이 정리해 보았습니다:

  • 획기적인 사용자 경험(UX) 개선:

    • 추천 결과를 직관적인 카드 형태로 제공하고, 각 카드 클릭 시 상세 정보 페이지로 이동하는 기능은 사용자 편의성을 크게 높였습니다. (recommendation_result.html, recommend_detail.html, result.css 등)
    • 상세 페이지 내 '뒤로가기' 기능 추가 등 세심한 부분까지 고려한 점이 좋습니다.
    • 상세 페이지에 반려동물 관련 다양한 정보(이미지, 연락처 등)를 풍부하게 제공하여 실질적인 도움이 될 것 같습니다.
  • 추천 품질 및 정확도 대폭 향상:

    • GeminiRerankingService 도입은 이번 PR의 핵심으로, 추천 결과 생성 방식을 기존 유사도 검색에서 Gemini 기반 리랭킹으로 전환하여 추천 품질과 사용자 요구사항 반영도를 한 단계 끌어올렸습니다.
    • 프롬프트 설계를 개선하고(추천 이유 명시, 타입 필터링 등) 관련 DTO, 서비스 로직 전반을 개편하여 AI 기반 추천의 정확성과 만족도를 높인 점이 돋보입니다.
    • 향후 카테고리 관련 프롬프트 확장을 위한 기반을 마련한 것으로 보입니다.
  • 시스템 안정성 및 효율성 증대:

    • 추천/비전 분석/리포트 과정을 UnifiedFlowController를 중심으로 하나의 흐름으로 통합하여 사용자 플로우를 개선하고 시스템 복잡도를 낮추었습니다.
    • 세션 관리 방식을 리팩토링하여, 새로운 분석 시작 시 이전 세션 정보(추천 결과 등)가 명확히 초기화되도록 변경함으로써 데이터 정합성 및 안정성을 강화했습니다. (/analyze GET 진입 시 초기화)
  • 코드 품질 및 구현 완성도:

    • PR 설명에 기술된 모든 주요 목표(카드형 UI, 상세 페이지, Gemini 도입, 세션 관리 등)가 실제 코드 변경 사항에 충실히 반영되었습니다.
    • Controller, Service, DTO, HTML, CSS 등 시스템 전반에 걸쳐 필요한 코드와 리소스가 체계적으로 추가 및 수정되었습니다.
    • 기존 추천 로직의 불필요한 중복(applyRerankingResults 등)을 제거하는 등 코드 리팩토링을 통해 유지보수성을 향상시킨 점도 긍정적입니다.
  • 핵심 변경의 중요성 및 영향력:

    • 특히 Gemini Rerank 도입과 이에 따른 추천 로직의 구조적 개편은 단순 기능 추가를 넘어, 데이터 흐름, 서비스 계층, DTO 처리 등 다수 레이어에 걸친 중요한 변화입니다. 이는 추천 시스템의 확장성과 향후 발전 가능성에 크게 기여할 것으로 기대됩니다.

이번 PR 작업하시면서 고민 많이 하신 게 느껴지네요. 덕분에 사용자 경험도 좋아지고 시스템도 한결 탄탄해진 것 같습니다. 수고 많으셨어요.

@usn757 usn757 merged commit dd5ba84 into PETTY-HUB:main May 25, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants