Skip to content

Conversation

@toychip
Copy link
Member

@toychip toychip commented Jul 17, 2025

요약(개요)

  • 샌드위치 연휴(bridge vacation) 추천 로직과 공휴일/주말 도메인 전체 구조를 리팩토링
  • 퍼블릭 API 키 Jasypt 암호화 등 다양한 개선사항을 포함
  • 현재 샌드위치 연휴 추천 API는 실데이터-목데이터 fallback 없이, 모든 요청에 대해 임시 목데이터만 반환
  • 향후 캐싱을 적용하여 실제 추천 데이터를 안전하게 반환할 예정

작업 내용

  • RecommendClient/Service 전체 구조 및 반환값 개선
  • AI 기반 샌드위치 연휴 추천 기능 추가
  • Weekend 도메인 신규 구현 (엔티티, 리더, 라이터, 스케줄러, JPA)
  • 공휴일/주말 데이터 조회/캐싱 로직 분리 및 리팩토링
  • HolidayService, Reader, Writer 역할 분리
  • Holiday, Weekend 데이터 전체 흐름 점검 및 단위테스트
  • 샌드위치 연휴 추천 API 임시 목데이터만 제공 (catch/fallback 처리 없이 실제 데이터 미반환)
  • Jasypt 기반 퍼블릭 API 키 암호화 적용
  • 필요 없는 파일/클래스 제거 및 코드 정리
  • 샌드위치 연휴 추천 결과 캐싱 미적용 (추후 구현 필요)
  • Vacation(여행 일정) 생성 프롬프트/비즈니스 로직 개선 예정 (향후 적용 필요)

집중해서 리뷰해야 하는 부분

  • RecommendService, RecommendClient 샌드위치 연휴 추천 전체 데이터 플로우
  • Holiday/Weekend 도메인 구조 설계 및 DB 레이어 분리 적정성
  • 신규 도입 Weekend 도메인(JPA Entity, Repository 등) 설계 및 성능 이슈 가능성
  • 현재 샌드위치 연휴 API의 임시 목데이터 고정 반환 구조 및, 캐싱/실데이터 연동 시 고려 사항
  • Vacation(여행 일정) 생성 프로세스의 개선 포인트

기타 전달 사항 및 참고 자료(선택)

  • 테스트 시 실제 추천 데이터가 아닌, 목데이터만 확인 가능함에 유의
  • 캐싱 및 vacation 생성 로직 추가 개선은 추후 별도 PR로 진행 예정
  • application.yml 내 Jasypt 암호화 관련 환경변수 세팅 주의

Summary by CodeRabbit

  • 신규 기능

    • 연속 휴가(샌드위치 휴가) 추천 및 AI 기반 맞춤 휴가 일정 생성 기능이 추가되었습니다.
    • 연중 모든 주말 정보를 자동으로 생성·저장하는 기능이 도입되었습니다.
    • 다양한 여행 스타일, 활동 유형, 휴식/여가 선호 등 개인화 옵션을 반영한 AI 휴가 추천이 가능합니다.
    • 새로운 API 엔드포인트 및 요청/응답 데이터 모델이 추가되었습니다.
  • 버그 수정 및 개선

    • 휴가 추천 응답이 단일 기간에서 여러 연속 휴가 기간 제공으로 개선되었습니다.
    • 주말 및 공휴일 정보를 활용한 휴가 계산 로직이 강화되었습니다.
    • 서버 오류 메시지 및 에러 처리 방식이 개선되었습니다.
  • 문서

    • 연속 휴가 추천 API의 설명, 응답 예시, 오류 예시가 최신 모델에 맞게 업데이트되었습니다.
  • 리팩터 및 기타

    • 내부 코드 구조 및 데이터 접근 방식이 개선되어 성능과 유지보수성이 향상되었습니다.
    • 불필요한 파일 제거 및 설정 파일이 최신화되었습니다.

@toychip toychip requested a review from mkSpace as a code owner July 17, 2025 08:55
@coderabbitai
Copy link

coderabbitai bot commented Jul 17, 2025

Walkthrough

이번 변경에서는 샌드위치 휴가 추천 및 AI 기반 휴가 생성 기능이 전면적으로 확장되었습니다. 주말 데이터 도메인 및 저장소가 신설되었고, 클라이언트-서버-DB 계층 전체에 걸쳐 데이터 모델, API, 예외 처리, 프롬프트 생성, AI 상호작용 로직이 대폭 보강되었습니다. 기존 샌드위치 추천 API의 반환 타입이 복수 기간 리스트로 변경되었으며, AI를 활용한 맞춤형 휴가 생성 API와 주말 데이터 자동 스케줄러가 추가되었습니다.

Changes

파일/경로 그룹 변경 요약
.../client-mcp/McpNotRespondingException.kt MCP 미응답 상황을 위한 커스텀 예외 클래스 추가
.../client-mcp/recommend/RecommendApi.kt, RecommendClient.kt getSandwich 반환 타입을 BridgeVacationPeriod 리스트로 변경, generateVacation API 및 클라이언트 메소드 추가, 예외 처리 강화
.../client-mcp/recommend/model/AiGenerateVacation.kt, Sandwich.kt AI 휴가 생성용 요청/응답 모델 추가, 샌드위치 관련 모델에 주말·연차 필드 및 BridgeVacationPeriod 등 확장
.../core-api/controller/v1/RecommendController.kt, docs/RecommendControllerDocs.kt 샌드위치 추천 API 반환 타입을 SandwichApiResponse(다수 응답)로 변경, 문서 및 예시 응답 수정
.../core-api/domain/holiday/HolidayServiceImpl.kt, .../core-domain/holiday/HolidayReader.kt 휴일 조회 로직을 HolidayReader로 일원화, 월별/남은 휴일 조회 메소드 추가
.../core-api/domain/recommend/RecommendService.kt, RecommendServiceImpl.kt getSandwich 반환 타입 변경, generateVacation 메소드 및 날짜 범위 생성·아이콘 결정 로직 추가
.../core-api/domain/weekend/WeekendScheduler.kt 연 1회 주말 자동 생성 스케줄러 컴포넌트 추가
.../core-api/support/error/ErrorType.kt MCP 서버 내부 오류 메시지 문구 변경(의미 동일)
.../core-domain/weekend/* Weekend, WeekendReader, WeekendWriter, WeekendRepository 등 주말 도메인 및 리더/라이터/저장소 인터페이스 신설
.../mcp-host/config/LangGraphConfig.kt, MyAgentState.kt LangGraphConfig, MyAgentState 클래스 삭제(미사용/불필요)
.../mcp-host/config/RestTemplateConfig.kt 다양한 미디어 타입 지원 RestTemplate 빈 등록
.../mcp-host/controller/ChatbotController.kt getSandwich, generate-vacation 신규 POST 엔드포인트 추가
.../mcp-host/controller/Prompt.kt Prompt 클래스 위치 이동 및 @component화, 동적 프롬프트 생성 메소드 추가
.../mcp-host/controller/request/AiGenerateVacation.kt, SandwichRequest.kt AI 휴가 생성 및 샌드위치 요청용 DTO 추가
.../mcp-host/controller/response/BridgeVacationPeriod.kt BridgeVacationPeriod 데이터 클래스 신설
.../mcp-host/service/ChatbotService.kt 프롬프트 의존성 주입, chat 메소드 삭제, generateVacation/getSandwich 등 AI 기반 신규 로직 대거 추가
.../mcp-host/resources/application.yml spring.ai.retry 및 perplexity-ask stdio 연결 등 설정 추가/수정
.../mcp-server/controller/WeatherController.kt 불필요한 콘솔 출력 제거
.../db-core/weekend/* WeekendCoreRepository, WeekendEntity, WeekendJpaRepository 등 JPA 기반 주말 저장소 및 매핑 로직 추가

Sequence Diagram(s)

1. 샌드위치 휴가 추천(BridgeVacationPeriod 리스트 반환)

sequenceDiagram
    participant Client
    participant RecommendController
    participant RecommendServiceImpl
    participant HolidayReader
    participant WeekendReader
    participant RecommendClient
    participant MCP

    Client->>RecommendController: getSandwich(userId)
    RecommendController->>RecommendServiceImpl: getSandwich(userId)
    RecommendServiceImpl->>HolidayReader: findRemainingHolidays
    RecommendServiceImpl->>WeekendReader: getUpcomingWeekends
    RecommendServiceImpl->>RecommendClient: getSandwich(SandwichRequest)
    RecommendClient->>MCP: getSandwich API 호출
    MCP-->>RecommendClient: List<BridgeVacationPeriod>
    RecommendClient-->>RecommendServiceImpl: List<BridgeVacationPeriod>
    RecommendServiceImpl-->>RecommendController: SandwichApiResponse
    RecommendController-->>Client: ApiResponse<SandwichApiResponse>
Loading

2. AI 기반 휴가 생성

sequenceDiagram
    participant Client
    participant RecommendController
    participant RecommendServiceImpl
    participant RecommendClient
    participant MCP

    Client->>RecommendController: generateVacation(userId, request)
    RecommendController->>RecommendServiceImpl: generateVacation(userId, request)
    RecommendServiceImpl->>RecommendClient: generateVacation(AiGenerateVacationRequest)
    RecommendClient->>MCP: generateVacation API 호출
    MCP-->>RecommendClient: AiGenerateVacationResponse
    RecommendClient-->>RecommendServiceImpl: AiGenerateVacationResponse
    RecommendServiceImpl-->>RecommendController: AiGenerateVacationApiResponse
    RecommendController-->>Client: ApiResponse<AiGenerateVacationApiResponse>
Loading

3. 주말 데이터 연간 자동 생성

sequenceDiagram
    participant Scheduler
    participant WeekendScheduler
    participant WeekendWriter
    participant WeekendRepository

    Scheduler->>WeekendScheduler: generateThisYearWeekends (매년 1월 1일 0시)
    WeekendScheduler->>WeekendWriter: register(Weekend) (연중 모든 주말)
    WeekendWriter->>WeekendRepository: register(Weekend)
Loading

Possibly related PRs

  • mash-up-kr/NoWeekend-Server#45: 샌드위치 추천 API의 초기 구현 및 기본 모델 추가. 본 PR은 해당 기능을 대폭 확장·변경하며, 반환 타입, 예외 처리, AI 기반 휴가 생성 등 추가적인 기능을 포함합니다.
✨ 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

@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: 18

🔭 Outside diff range comments (2)
noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendClient.kt (1)

97-107: 로깅 메시지의 복사-붙여넣기 오류를 수정해야 합니다.

104라인의 로그 메시지에서 메서드명이 잘못되었습니다.

-            log.error("[getSandwich] 예기치 못한 예외, empty 반환.", e)
+            log.error("[generateVacation] 예기치 못한 예외, empty 반환.", e)
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/service/ChatbotService.kt (1)

62-62: Thread.sleep 대신 비동기 처리 고려

Thread.sleep은 스레드를 블로킹하여 성능 저하를 일으킬 수 있습니다.

다음 대안을 고려하세요:

  1. @AsyncCompletableFuture 사용
  2. ScheduledExecutorService 활용
  3. Spring의 TaskScheduler 사용
  4. Kotlin 코루틴의 delay() 함수
// 코루틴 예시
import kotlinx.coroutines.delay

suspend fun retryWithDelay(delayMs: Long) {
    delay(delayMs)
}

Also applies to: 207-207

🧹 Nitpick comments (22)
noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendRepository.kt (2)

5-9: 메서드 명세 모호성 정리 필요

findAfterDate 메서드가 기준 날짜를 포함하는지(≥) 배제하는지(>) 명확하지 않습니다.
도메인 용어(예: findFrom vs findAfterExclusive)로 의도를 드러내거나 KDoc 주석을 추가해 주세요.


5-9: 네이밍 일관성 확인

register 대신 일반적으로 사용하는 saveadd 같은 표현을 고려해 보세요. 동일 계층의 다른 리포지터리와 용어를 맞추면 가독성이 향상됩니다.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/response/BridgeVacationPeriod.kt (1)

5-8: 불변 객체로의 활용 검토

startDate, endDate 만 가지는 단순 DTO라면 @JvmInline value classrecord(Kotlin 1.9+) 도 고려해 볼 수 있습니다. 다만 직렬화 라이브러리 호환성을 먼저 검토하세요.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/SandwichRequest.kt (1)

5-10: 입력 유효성 검사 및 문서화 고려가 필요합니다.

데이터 클래스의 구조는 적절하지만 다음 사항들을 고려해보세요:

  1. 유효성 검사: remainingAnnualLeave에 대한 최소값 검증, 날짜 리스트의 null 체크 등
  2. 문서화: 각 속성의 역할과 제약사항에 대한 KDoc 추가

다음과 같은 개선을 제안합니다:

+import javax.validation.constraints.Min
+import javax.validation.constraints.NotNull
+
+/**
+ * 샌드위치 휴가 추천 요청 데이터
+ */
 data class SandwichRequest(
+    /** 사용자 생일 */
+    @field:NotNull
     val birthDay: LocalDate,
+    /** 공휴일 목록 */
+    @field:NotNull
     val holidays: List<LocalDate>,
+    /** 남은 연차 일수 */
+    @field:Min(0)
     val remainingAnnualLeave: Int,
+    /** 주말 목록 */
+    @field:NotNull
     val weekends: List<LocalDate>,
 )
noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendWriter.kt (1)

6-15: 깔끔한 구조이지만 검증 및 로깅 추가를 고려하세요.

단일 책임 원칙을 잘 따르는 깔끔한 구조입니다. 하지만 운영 환경에서의 안정성을 위해 다음 사항들을 고려해보세요:

+import org.slf4j.LoggerFactory
+
 @Component
 @Transactional
 class WeekendWriter(
     private val weekendRepository: WeekendRepository,
 ) {
+    private val logger = LoggerFactory.getLogger(WeekendWriter::class.java)

     fun register(weekend: Weekend) {
+        logger.debug("Registering weekend: {}", weekend)
+        require(weekend.id.isNotBlank()) { "Weekend ID cannot be blank" }
         weekendRepository.register(weekend)
+        logger.info("Successfully registered weekend: {}", weekend.id)
     }
 }
noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/weekend/WeekendScheduler.kt (2)

33-33: 개별 등록 대신 일괄 등록으로 성능 개선

forEach를 사용한 개별 등록은 성능상 비효율적입니다. 일괄 등록을 고려하세요.

-weekends.forEach { weekendWriter.register(it) }
+weekendWriter.registerAll(weekends)

WeekendWriterregisterAll 메서드 추가가 필요합니다.


18-31: 날짜 반복 로직을 더 간결하게 개선

현재 while 루프 방식보다 더 함수형 접근 방식을 사용할 수 있습니다.

-val year = LocalDate.now().year
-val start = LocalDate.of(year, 1, 1)
-val end = LocalDate.of(year, 12, 31)
-var date = start
-val weekends = mutableListOf<Weekend>()
-
-while (!date.isAfter(end)) {
-    if (date.dayOfWeek == DayOfWeek.SATURDAY || date.dayOfWeek == DayOfWeek.SUNDAY) {
-        weekends.add(
-            Weekend.generate(
-                date = date,
-                dayOfWeek = date.dayOfWeek,
-            ),
-        )
-    }
-    date = date.plusDays(1)
-}
+val start = LocalDate.of(year, 1, 1)
+val end = LocalDate.of(year, 12, 31)
+
+val weekends = generateSequence(start) { it.plusDays(1) }
+    .takeWhile { !it.isAfter(end) }
+    .filter { it.dayOfWeek == DayOfWeek.SATURDAY || it.dayOfWeek == DayOfWeek.SUNDAY }
+    .map { Weekend.generate(it, it.dayOfWeek) }
+    .toList()
noweekend-mcp/mcp-host/src/main/resources/application.yml (2)

8-12: 재시도 설정이 과도할 수 있음

최대 5회 재시도와 3분까지의 백오프는 과도할 수 있습니다. 특히 사용자 대면 서비스에서는 응답 시간이 중요합니다.

-    max-attempts: 5
+    max-attempts: 3
     backoff:
-      initial-interval: 10s
+      initial-interval: 5s
       multiplier: 2
-      max-interval: 3m
+      max-interval: 1m

64-64: 환경 변수 문서화 필요

JASYPT_ENCRYPTOR_PASSWORD 환경 변수가 필수이지만 문서화가 부족합니다.

README 파일이나 배포 문서에 다음 환경 변수 설정을 추가하시겠습니까?

  • JASYPT_ENCRYPTOR_PASSWORD: API 키 암호화/복호화를 위한 Jasypt 암호화 키
noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/holiday/HolidayServiceImpl.kt (1)

37-37: 연도별 휴일 조회 성능 고려사항

findAllByYear 메서드가 이전 직접 레포지토리 접근보다 성능상 이점을 제공하는지 검토가 필요합니다.

대량의 휴일 데이터 처리 시 다음을 고려하세요:

  • 인덱스 확인 (year 컬럼)
  • 캐싱 전략 적용
  • 페이징 처리 (필요한 경우)
noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendEntity.kt (1)

20-21: 날짜 조회 성능을 위한 인덱스 추가를 고려해주세요.

date 컬럼은 범위 검색이 빈번할 것으로 예상되므로 데이터베이스 인덱스 추가를 권장합니다.

 @Column(name = "date", nullable = false)
+@Index(name = "idx_weekend_date")
 val date: LocalDate,
noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/holiday/HolidayReader.kt (1)

17-21: 메모리 필터링 대신 데이터베이스 쿼리 최적화를 고려해주세요.

현재 구현은 연도별 모든 공휴일을 메모리에 로드한 후 필터링하고 있습니다. 데이터가 많아질 경우 성능 이슈가 발생할 수 있습니다.

HolidayRepository에 월별 조회 메서드를 추가하는 것을 권장합니다:

// HolidayRepository에 추가
fun findByYearAndMonth(year: Int, month: Int): List<Holiday>

// HolidayReader에서 사용
fun findMonthHolidays(year: Int, month: Int): List<Holiday> {
    return holidayRepository.findByYearAndMonth(year, month)
        .sortedBy { it.day }
}
noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendReader.kt (1)

13-16: 현재 연도 로직의 테스트 가능성을 개선해주세요.

LocalDate.now()가 하드코딩되어 있어 테스트가 어려울 수 있습니다.

시간을 주입 가능하도록 개선하는 것을 권장합니다:

@Component
@Transactional(readOnly = true)
class WeekendReader(
    private val weekendRepository: WeekendRepository,
    private val clock: Clock = Clock.systemDefaultZone()
) {
    fun getAllThisYearWeekends(): List<Weekend> {
        val year = LocalDate.now(clock).year
        return weekendRepository.findByYear(year)
    }
}
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/AiGenerateVacation.kt (1)

5-29: 문서화 추가 권장

각 필드의 목적과 예상 값에 대한 KDoc 주석을 추가하면 API 사용성이 향상됩니다.

+/**
+ * AI 기반 휴가 생성 요청
+ * @property days 휴가 일수
+ * @property travelStyleOptionLabels 여행 스타일 옵션 목록
+ * @property chosenTravelStyleLabel 선택된 여행 스타일
+ * ...
+ */
 data class AiGenerateVacationRequest(
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/service/ChatbotService.kt (2)

43-43: 재시도 지연 시간 설정 가능하도록 개선

백오프 시간이 하드코딩되어 있습니다. 설정 파일로 외부화하면 환경별 조정이 용이합니다:

+@Value("\${ai.retry.backoff-intervals:1000,2000,4000,8000,16000}")
+private lateinit var backoffIntervals: List<Long>
+
-val backoff = listOf(1000L, 2000L, 4000L, 8000L, 16000L)
+val backoff = backoffIntervals

260-264: 사용하지 않는 메서드 제거

printRaw 메서드는 디버깅 용도로 보이며 프로덕션 코드에 남아있습니다. 로거를 사용하거나 제거하는 것이 좋습니다.

-private fun printRaw(text: String) {
-    println("------------------------------------------------\n")
-    println(text)
-    println("------------------------------------------------\n")
-}
+private fun debugLog(text: String) {
+    logger.debug("Raw response: {}", text)
+}
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/Prompt.kt (2)

14-59: 프롬프트 상수 추출 고려

프롬프트 문자열이 매우 길어서 가독성이 떨어집니다. 별도의 리소스 파일로 관리하면 유지보수가 용이합니다:

@Value("classpath:prompts/weather-prompt.txt")
private lateinit var weatherPromptResource: Resource

val WEATHER_PROMPT: String by lazy {
    weatherPromptResource.inputStream.bufferedReader().use { it.readText() }
}

149-220: detailedPlanPrompt 메서드 매개변수가 과다함

5개의 매개변수는 과도합니다. 데이터 클래스로 묶어서 전달하면 가독성이 향상됩니다:

data class DetailedPlanContext(
    val req: AiGenerateVacationRequest,
    val dates: List<String>,
    val offset: Int,
    val totalDays: Int,
    val prevUsed: List<String>
)

fun detailedPlanPrompt(context: DetailedPlanContext): String {
    // ... implementation
}
noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendServiceImpl.kt (4)

245-247: 유틸리티 메서드는 별도 클래스로 분리

generateDateRange는 도메인 로직과 무관한 유틸리티 메서드입니다. 별도의 유틸리티 클래스로 분리하는 것이 좋습니다:

object DateRangeUtils {
    fun generateDateRange(start: LocalDate, end: LocalDate): List<LocalDate> {
        return (0..ChronoUnit.DAYS.between(start, end)).map { start.plusDays(it) }
    }
}

298-314: solveIcon 로직을 맵 기반으로 개선

중첩된 if 문 대신 맵을 사용하면 가독성과 확장성이 향상됩니다:

private val iconStyleMap = mapOf(
    ActivityType.AT_HOME to IconStyle.HOUSE,
    ActivityType.OUTDOOR to mapOf(
        TravelStyle.PLANNER to IconStyle.PLANE,
        TravelStyle.SPONTANEOUS to IconStyle.TRAIN
    )
)

private fun solveIcon(request: GenerateVacationRequest): IconStyle {
    if (request.activityType == ActivityType.AT_HOME) {
        return IconStyle.HOUSE
    }
    
    val outdoorMap = iconStyleMap[ActivityType.OUTDOOR] as? Map<TravelStyle, IconStyle>
    return outdoorMap?.get(request.travelStyle) ?: IconStyle.STAR
}

258-262: 공휴일 조회 범위 확인 필요

15일 이내의 공휴일만 조회하고 있는데, 사용자가 더 긴 휴가를 계획할 경우 문제가 될 수 있습니다.

-val endDate = today.plusDays(15)
+val endDate = today.plusDays(Math.max(request.days * 2, 30))

또한 이 값을 설정으로 관리하는 것도 고려해보세요.


240-242: 예외 처리 개선 가능

McpNotRespondingException을 catch하고 있지만, 로깅이 없습니다. 디버깅을 위해 로그를 추가하는 것이 좋습니다:

} catch (e: McpNotRespondingException) {
+    logger.error("MCP server not responding for sandwich request", e)
    throw CoreException(ErrorType.MCP_SERVER_INTERNAL_ERROR)
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 35e975d and ad20082.

📒 Files selected for processing (33)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/McpNotRespondingException.kt (1 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendApi.kt (2 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendClient.kt (2 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/AiGenerateVacation.kt (1 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/Sandwich.kt (1 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/RecommendController.kt (2 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/docs/RecommendControllerDocs.kt (5 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/holiday/HolidayServiceImpl.kt (2 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendService.kt (1 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendServiceImpl.kt (4 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/weekend/WeekendScheduler.kt (1 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/support/error/ErrorType.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/holiday/HolidayReader.kt (2 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/Weekend.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendReader.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendRepository.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendWriter.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/McpHostApplication.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/LangGraphConfig.kt (0 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/MyAgentState.kt (0 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/RestTemplateConfig.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/ChatbotController.kt (2 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/Prompt.kt (3 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/AiGenerateVacation.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/SandwichRequest.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/WeatherRequest.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/response/BridgeVacationPeriod.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/service/ChatbotService.kt (5 hunks)
  • noweekend-mcp/mcp-host/src/main/resources/application.yml (2 hunks)
  • noweekend-mcp/mcp-server/src/main/kotlin/noweekend/mcpserver/controller/WeatherController.kt (0 hunks)
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendCoreRepository.kt (1 hunks)
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendEntity.kt (1 hunks)
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendJpaRepository.kt (1 hunks)
💤 Files with no reviewable changes (3)
  • noweekend-mcp/mcp-server/src/main/kotlin/noweekend/mcpserver/controller/WeatherController.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/LangGraphConfig.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/MyAgentState.kt
🧰 Additional context used
🪛 detekt (1.23.8)
noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/McpNotRespondingException.kt

[warning] 5-5: An empty default constructor can be removed.

(detekt.empty-blocks.EmptyDefaultConstructor)

🔇 Additional comments (32)
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/McpHostApplication.kt (1)

12-13: 의미 없는 EOF 개행

기능적 변화가 없는 단순 개행 추가입니다. 팀 컨벤션(예: POSIX-style EOF 개행 여부)에 맞춰 정리해 주세요.

noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendRepository.kt (1)

5-9: LGTM

도메인 레이어에 의존성 없는 인터페이스 선언으로 깔끔하게 분리되었습니다.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/WeatherRequest.kt (1)

3-6: 트레일링 콤마 사용 시 Kotlin 버전 확인

파라미터 마지막에 있는 트레일링 콤마는 Kotlin 1.4 이상에서만 컴파일됩니다.
CI 환경의 Kotlin 버전이 이를 지원하는지 확인 부탁드립니다.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/response/BridgeVacationPeriod.kt (1)

5-8: LGTM

간결한 DTO 정의로 목적이 분명합니다.

noweekend-core/core-api/src/main/kotlin/noweekend/core/support/error/ErrorType.kt (1)

23-23: 개선된 에러 메시지가 사용자 경험을 향상시킵니다.

MCP 서버 내부 에러에 대한 메시지가 더 구체적이고 사용자 친화적으로 변경되었습니다. "추천할 수 있는 상황이 아닙니다"라는 표현이 일시적인 서비스 불가 상태를 명확히 전달합니다.

noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendService.kt (1)

14-14: generateVacation 메서드 선언·구현 정상 확인 및 승인

  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendService.kt
    fun generateVacation(userId: String, request: GenerateVacationRequest): AiGenerateVacationApiResponse 선언 확인
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendServiceImpl.kt
    override fun generateVacation(...) 구현부 확인
    GenerateVacationRequestAiGenerateVacationRequest 매핑 로직
    – 외부 AI 클라이언트 호출 및 AiGenerateVacationApiResponse 반환 로직 정상 동작 예상

AI 기반 휴가 생성 기능 확장에 부합하며, 추가 수정 사항이 없습니다. 승인합니다.

noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/holiday/HolidayServiceImpl.kt (3)

14-14: 읽기 전용 작업 분리로 아키텍처 개선

holidayRepository 대신 holidayReader를 사용하여 읽기 작업을 분리한 것은 좋은 아키텍처 개선입니다.

CQRS 패턴을 따라 읽기와 쓰기 작업을 명확히 분리하였습니다.


27-28: 남은 휴일 필터링 로직 수동 확인 필요

findRemainingHolidays 메서드 구현이 오늘 이후의 날짜만 정확히 필터링하는지 확인이 불가해 스크립트 검증이 실패했습니다. 아래 항목을 직접 검토해 주세요.

  • HolidayReader(또는 HolidayServiceImpl)이 findRemainingHolidays를 어떻게 구현하는지 파일 위치 확인
  • 해당 메서드 내부에서 today 이후의 휴일만 필터링하는 날짜 비교 로직 검토

21-21: findMonthHolidays의 월별 필터링 구현 확인 완료
HolidayReader 인터페이스의 기본 구현에서 .filter { it.month == month } 로 월별 필터링이 적용되어 있어, 별도 추가 작업이 필요 없습니다.

  • core-domain/src/main/kotlin/noweekend/core/domain/holiday/HolidayReader.kt:
    fun findMonthHolidays(year: Int, month: Int): List {

    .filter { it.month == month }

    }
noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendEntity.kt (2)

28-40: 도메인/엔티티 변환 함수 구현이 깔끔합니다.

확장 함수를 활용한 변환 로직이 간결하고 명확합니다. 도메인과 영속성 계층 간의 분리가 잘 구현되어 있습니다.


16-18: ID 생성 전략 확인 완료

도메인 모델의 Weekend.generate()에서 IdGenerator.generate()를 통해 타임스탬프+UUID 기반 고유 ID를 생성하도록 구현되어 있으므로, JPA 엔티티에 @GeneratedValue 없이도 영속화 시 정상 작동합니다. 추가 수정이나 전략 명시가 필요하지 않습니다.

noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendApi.kt (2)

50-55: 새로운 AI 휴가 생성 API 추가가 적절합니다.

generateVacation 메서드 추가로 AI 기반 휴가 추천 기능이 확장되었습니다. 메서드 시그니처와 매핑이 일관성 있게 구현되어 있습니다.


48-48: client-mcp API 반환 타입 변경에 따른 버전 관리 필요

RecommendApi.getSandwich의 반환 타입이 SandwichResponseList<BridgeVacationPeriod>로 변경되었습니다.
내부 RecommendServiceImpl 등은 이미 새로운 타입에 맞춰 정상 동작하지만, 외부 소비자(다른 서비스·모듈)에서는 컴파일 오류나 런타임 에러가 발생할 수 있습니다.

조치 사항:

  • client-mcp 라이브러리의 MAJOR 버전을 올려(v1 → v2) 배포
  • CHANGELOG 및 릴리스 노트에 변경점 명시
  • 필요 시 하위 호환용 래퍼 메서드 제공 또는 마이그레이션 가이드 작성

외부 소비자들이 새 시그니처로 마이그레이션했는지 확인해주세요.

noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendReader.kt (1)

18-21: 메서드 구현이 간결하고 명확합니다.

getUpcomingWeekends 메서드가 저장소에 적절히 위임하고 있으며, 로직이 명확합니다.

noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendJpaRepository.kt (1)

6-9: JPA 저장소 구현이 Spring Data 규칙을 잘 따르고 있습니다.

쿼리 메서드 명명 규칙과 매개변수 타입이 적절하며, Spring Data JPA의 쿼리 파생 기능을 효과적으로 활용하고 있습니다.

성능 향상을 위해 date 컬럼에 인덱스 추가를 고려해주세요:

CREATE INDEX idx_weekend_date ON weekend(date);
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/ChatbotController.kt (2)

7-10: 새로운 데이터 모델 import가 적절하게 추가되었습니다.

AI 기반 휴가 생성과 샌드위치 휴가 추천 기능을 위한 request/response 모델들이 올바르게 import되었습니다.


42-45: getSandwich 엔드포인트가 올바르게 구현되었습니다.

요청을 서비스 레이어로 적절히 위임하고 있으며, 반환 타입이 새로운 데이터 모델과 일치합니다.

noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendClient.kt (1)

4-7: 새로운 데이터 모델과 예외 처리를 위한 import가 추가되었습니다.

AI 휴가 생성 기능과 향상된 샌드위치 휴가 추천을 위한 필요한 import들이 적절하게 추가되었습니다.

noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendCoreRepository.kt (4)

1-11: 리포지토리 구조와 의존성 주입이 적절하게 구현되었습니다.

Spring의 @Repository 어노테이션과 생성자 주입을 사용하여 JPA 리포지토리를 래핑하는 구조가 올바르게 구현되었습니다.


12-14: 도메인 객체 등록 메서드가 간결하게 구현되었습니다.

register 메서드에서 도메인 객체를 엔티티로 변환 후 저장하는 로직이 적절합니다.


16-20: 연도별 주말 조회 로직이 올바르게 구현되었습니다.

연도의 시작일(1월 1일)과 마지막일(12월 31일)을 사용한 날짜 범위 검색이 정확하며, 엔티티를 도메인 객체로 변환하는 매핑도 적절합니다.


22-25: 특정 날짜 이후 주말 조회 기능이 적절하게 구현되었습니다.

findAfterDate 메서드에서 JPA 쿼리 결과를 도메인 객체로 변환하는 로직이 올바르게 구현되었습니다.

noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/Sandwich.kt (4)

8-10: SandwichRequest에 필요한 필드들이 적절히 추가되었습니다.

남은 연차 일수(remainingAnnualLeave)와 주말 날짜 목록(weekends)이 추가되어 더 정확한 휴가 추천이 가능해졌습니다.


12-15: BridgeVacationPeriod 데이터 클래스가 명확하게 정의되었습니다.

연속 휴가 구간을 나타내는 시작일과 종료일 필드가 적절하게 구성되었습니다.


20-22: SandwichResponse에 유용한 정보 필드들이 추가되었습니다.

실제 사용 연차 일수(useAnnualLeave)와 총 휴가 일수(totalVacationDays)가 추가되어 사용자에게 더 상세한 정보를 제공할 수 있습니다.


24-26: SandwichApiResponse 래퍼 클래스가 적절하게 구현되었습니다.

여러 개의 휴가 추천 결과를 담을 수 있는 구조로 API 응답 형태가 향상되었습니다.

noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/docs/RecommendControllerDocs.kt (4)

9-9: import 변경이 새로운 응답 모델과 일치합니다.

SandwichResponse에서 SandwichApiResponse로 변경되어 새로운 다중 휴가 구간 응답 구조를 반영합니다.


252-256: API 설명이 향상된 기능을 정확히 반영합니다.

샌드위치 휴가 추천 기능의 새로운 특징들(남은 연차, 주말 고려, 다중 휴가 구간, 상세 정보 제공)이 잘 설명되어 있습니다.


272-285: 예제 응답이 새로운 데이터 모델과 일치합니다.

다중 휴가 구간을 보여주는 예제 응답이 SandwichApiResponse 구조와 정확히 일치하며, 각 구간별로 useAnnualLeavetotalVacationDays 정보가 포함되어 있습니다.


323-325: 메서드 반환 타입이 새로운 응답 모델로 올바르게 업데이트되었습니다.

ApiResponse<SandwichApiResponse>로 변경되어 다중 휴가 구간 응답을 지원합니다.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/Prompt.kt (1)

124-147: JSON 인젝션 방지 확인 필요

사용자 입력이 프롬프트에 직접 포함되므로 JSON 인젝션 가능성을 확인해야 합니다.

ObjectMapper를 사용하여 JSON을 생성하고 있어 기본적인 이스케이핑은 되지만, 추가 검증이 필요할 수 있습니다:

// 입력 검증 예시
require(req.days in 1..365) { "Invalid days range" }
require(req.upcomingHolidays.all { it.matches(datePattern) }) { "Invalid date format" }
noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendServiceImpl.kt (1)

219-220: 주말과 공휴일 중복 제거 로직 확인

holidayOrWeekendSet을 생성할 때 Set으로 변환하여 중복을 제거하고 있습니다. 이는 적절한 접근입니다.

코드가 명확하고 효율적으로 작성되었습니다.

@toychip toychip force-pushed the feat/sandwich-realdata branch from ec31046 to 9ffaa72 Compare July 17, 2025 11:24
Copy link

@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: 5

♻️ Duplicate comments (3)
noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/McpNotRespondingException.kt (1)

5-5: 불필요한 기본 생성자 및 메시지 전달 누락

이전 리뷰 댓글에서 이미 지적된 것과 동일한 문제입니다. 빈 기본 생성자를 제거하고 의미 있는 메시지나 cause를 전달할 수 있는 생성자를 추가해야 합니다.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/service/ChatbotService.kt (2)

152-235: generateVacation 메서드 복잡도 개선 필요

이전 리뷰에서 지적된 것과 동일한 문제입니다. 이 메서드가 여전히 너무 많은 책임을 담당하고 있습니다:

  • 샌드위치 날짜 계산
  • 청크 단위 일정 생성
  • 사용된 항목 추적
  • 요약 생성

각 단계를 별도 메서드로 분리하여 가독성과 테스트 용이성을 향상시켜야 합니다.


310-310: getSandwich 메서드의 재시도 횟수가 과도함

이전 리뷰에서 지적된 것과 동일한 문제입니다. 10회 재시도는 여전히 과도하며, 재시도 간격이 없어 API 서버에 부담을 줄 수 있습니다.

🧹 Nitpick comments (1)
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/Prompt.kt (1)

149-222: detailedPlanPrompt 메서드 복잡도 높음

이 메서드는 매우 복잡하고 많은 책임을 담당하고 있습니다. 프롬프트 생성 로직을 더 작은 단위로 분리하는 것을 고려해보세요.

fun detailedPlanPrompt(
    req: AiGenerateVacationRequest,
    dates: List<String>,
    offset: Int,
    totalDays: Int,
    prevUsed: List<String>,
): String {
    val headers = generateDayHeaders(dates, offset)
    val usedClause = generateUsedClause(prevUsed)
    val profileJson = generateProfileJson(req)
    val instructions = generateInstructions(dates.size, totalDays, profileJson, usedClause)
    
    return "$instructions\n\nHEADERS:\n$headers\n\nNow generate the itinerary."
}

private fun generateDayHeaders(dates: List<String>, offset: Int): String { ... }
private fun generateUsedClause(prevUsed: List<String>): String { ... }
private fun generateProfileJson(req: AiGenerateVacationRequest): String { ... }
private fun generateInstructions(daysCount: Int, totalDays: Int, profileJson: String, usedClause: String): String { ... }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ad20082 and 9ffaa72.

📒 Files selected for processing (31)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/McpNotRespondingException.kt (1 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendApi.kt (2 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendClient.kt (2 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/AiGenerateVacation.kt (1 hunks)
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/Sandwich.kt (1 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/RecommendController.kt (2 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/docs/RecommendControllerDocs.kt (5 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/holiday/HolidayServiceImpl.kt (2 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendService.kt (1 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendServiceImpl.kt (4 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/weekend/WeekendScheduler.kt (1 hunks)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/support/error/ErrorType.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/holiday/HolidayReader.kt (2 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/Weekend.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendReader.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendRepository.kt (1 hunks)
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendWriter.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/LangGraphConfig.kt (0 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/MyAgentState.kt (0 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/RestTemplateConfig.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/ChatbotController.kt (2 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/Prompt.kt (4 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/AiGenerateVacation.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/SandwichRequest.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/response/BridgeVacationPeriod.kt (1 hunks)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/service/ChatbotService.kt (5 hunks)
  • noweekend-mcp/mcp-host/src/main/resources/application.yml (2 hunks)
  • noweekend-mcp/mcp-server/src/main/kotlin/noweekend/mcpserver/controller/WeatherController.kt (0 hunks)
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendCoreRepository.kt (1 hunks)
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendEntity.kt (1 hunks)
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendJpaRepository.kt (1 hunks)
💤 Files with no reviewable changes (3)
  • noweekend-mcp/mcp-server/src/main/kotlin/noweekend/mcpserver/controller/WeatherController.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/MyAgentState.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/LangGraphConfig.kt
✅ Files skipped from review due to trivial changes (1)
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/SandwichRequest.kt
🚧 Files skipped from review as they are similar to previous changes (23)
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/support/error/ErrorType.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/config/RestTemplateConfig.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/response/BridgeVacationPeriod.kt
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendWriter.kt
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/holiday/HolidayServiceImpl.kt
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/RecommendController.kt
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/weekend/WeekendScheduler.kt
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendEntity.kt
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/Weekend.kt
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendClient.kt
  • noweekend-mcp/mcp-host/src/main/resources/application.yml
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/holiday/HolidayReader.kt
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendReader.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/ChatbotController.kt
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendService.kt
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/AiGenerateVacation.kt
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendJpaRepository.kt
  • noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/docs/RecommendControllerDocs.kt
  • noweekend-core/core-domain/src/main/kotlin/noweekend/core/domain/weekend/WeekendRepository.kt
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/RecommendApi.kt
  • noweekend-storage/db-core/src/main/kotlin/noweekend/storage/db/core/weekend/WeekendCoreRepository.kt
  • noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/request/AiGenerateVacation.kt
  • noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/recommend/model/Sandwich.kt
🧰 Additional context used
🪛 detekt (1.23.8)
noweekend-clients/client-mcp/src/main/kotlin/noweekend/client/mcp/McpNotRespondingException.kt

[warning] 5-5: An empty default constructor can be removed.

(detekt.empty-blocks.EmptyDefaultConstructor)

🔇 Additional comments (8)
noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/service/ChatbotService.kt (4)

6-6: Prompt 의존성 주입으로 개선됨

정적 상수 대신 Prompt 컴포넌트를 주입하여 프롬프트 관리를 개선한 것은 좋은 변경사항입니다.


43-43: 백오프 전략 개선

재시도 간격을 지수적으로 증가시키는 백오프 전략을 도입한 것은 좋은 개선사항입니다.


125-125: 재시도 횟수 증가

재시도 횟수가 2회에서 5회로 증가했습니다. 이는 합리적인 범위 내에서 안정성을 높이는 변경사항입니다.


337-337: 로그 메시지 오류

재시도 횟수가 10회인데 로그 메시지에서는 "5"로 하드코딩되어 있습니다.

-println("getSandwich retry ${attempt + 1}/5: ${e.message}")
+println("getSandwich retry ${attempt + 1}/10: ${e.message}")

Likely an incorrect or invalid review comment.

noweekend-core/core-api/src/main/kotlin/noweekend/core/domain/recommend/RecommendServiceImpl.kt (3)

211-243: getSandwich 메서드 로직 개선

메서드 시그니처 변경과 주말 데이터 통합, 브릿지 휴가 기간 계산 로직이 잘 구현되었습니다. 예외 처리도 적절합니다.


298-314: solveIcon 메서드 로직 개선

아이콘 결정 로직이 명확하고 잘 구현되었습니다. 기본값 처리도 적절합니다.


245-247: generateDateRange 메서드 검증 완료
테스트 결과, 시작일과 종료일을 모두 포함하여 정상적으로 작동함을 확인했습니다.

noweekend-mcp/mcp-host/src/main/kotlin/noweekend/mcphost/controller/Prompt.kt (1)

10-13: Spring 컴포넌트로 전환 개선

정적 상수에서 Spring 컴포넌트로 전환하여 ObjectMapper 주입이 가능해진 것은 좋은 설계 변경입니다.

@toychip toychip merged commit 7d3a3b1 into develop Jul 17, 2025
2 checks passed
@toychip toychip deleted the feat/sandwich-realdata branch July 17, 2025 11:36
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