-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat/#615] 프로비저닝 컨텐츠 카테고리 추가 #616
Conversation
Walkthrough이번 변경 사항은 프로비저닝 컨텐츠에 새롭게 카테고리 정보를 포함하도록 API 응답 및 도메인 모델을 확장하는 작업입니다. 프롬프트 생성 로직에도 카테고리 선택을 위한 기능이 추가되었으며, 관련 데이터 클래스 및 열거형(enum)이 도입되고, 일부 상수 값이 비트 시프트 방식으로 수정되었습니다. 또한, 서비스 로직 내에서 카테고리 생성 및 저장 절차가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as 클라이언트
participant Controller as 컨트롤러
participant Service as ProvisioningService
participant Prompt as PromptGenerator
participant Domain as 도메인 (Category, ProvisioningContents)
Client->>Controller: 요청 전송
Controller->>Service: create(프로비저닝 데이터)
Service->>Prompt: makeCategory(제목, 설명, coreTexts)
Prompt-->>Service: CategorySchema 반환
Service->>Domain: ProvisioningContents 저장 (category 포함)
Domain-->>Controller: 저장된 데이터 반환
Controller->>Client: 응답 전송 (Category.from(code) 적용)
Assessment against linked issues
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (3)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
프로비저닝 컨텐츠에 카테고리 16개 추가되었습니다.
확인 부탁드립니다
enum class Category( | ||
val code: Int, | ||
val title: String, | ||
) { | ||
TECHNOLOGY(1 shl 1, "Technology"), | ||
SCIENCE(1 shl 2, "Science"), | ||
HEALTH(1 shl 3, "Health"), | ||
BUSINESS(1 shl 4, "Business"), | ||
ENTERTAINMENT(1 shl 5, "Entertainment"), | ||
SPORTS(1 shl 6, "Sports"), | ||
POLITICS(1 shl 7, "Politics"), | ||
ENVIRONMENT(1 shl 8, "Environment"), | ||
ECONOMY(1 shl 9, "Economy"), | ||
CULTURE(1 shl 10, "Culture"), | ||
TRAVEL(1 shl 11, "Travel"), | ||
APPLE(1 shl 12, "Apple"), | ||
EV(1 shl 13, "EV"), | ||
EDUCATION(1 shl 14, "Education"), | ||
FOOD(1 shl 15, "Food"), | ||
ETC(1 shl 16, "Etc"), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지피티가 결정할 카테고리 16개
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
domain/generator/src/main/kotlin/com/few/generator/core/gpt/prompt/PromptGenerator.kt (1)
389-423
: 카테고리 선택을 위한 새로운 프롬프트 생성 메서드가 잘 구현되었습니다.
toCategory
메서드는 기존 메서드들과 일관된 패턴을 따르고 있으며, 필요한 모든 정보(제목, 요약, 본문)를 활용하여 적절한 카테고리를 선택하도록 GPT에 지시하고 있습니다. 몇 가지 개선 사항을 제안합니다:
- 카테고리 목록을 JSON으로 직렬화할 때
Category.values().map { it.title }
을 사용하는 대신, 카테고리 정보를 더 풍부하게 제공하는 것이 좋을 수 있습니다.- 프롬프트에 카테고리별 간단한 설명을 추가하면 GPT가 더 정확한 분류를 할 수 있을 것입니다.
다음과 같이 카테고리 정보를 더 풍부하게 제공하는 방법을 고려해보세요:
- val categories = gson.toJson(Category.values().map { it.title }) + val categories = gson.toJson(Category.values().map { mapOf("title" to it.title, "code" to it.code) })그리고 프롬프트에 카테고리 설명을 추가하는 것도 고려해보세요:
## 지시사항 1. 제목, 요약 및 본문을 검토하여 주요 주제와 내용을 파악하세요. 2. 아래 카테고리 목록에서 가장 적합한 항목을 선택하세요: $categories + 3. 카테고리 설명: + - Technology: 기술 관련 주제 (IT, 소프트웨어, 하드웨어 등) + - Science: 과학 관련 주제 (물리, 화학, 생물학 등) + (기타 카테고리 설명...) 3. 주어진 카테고리 중 적합한 것이 없는 경우에만 'etc' 카테고리를 선택하세요.domain/generator/src/main/kotlin/com/few/generator/domain/Category.kt (2)
7-22
: 비트 시프트를 활용한 코드 값 할당이 적절합니다.비트 시프트 연산(
1 shl n
)을 사용하여 각 카테고리에 2의 거듭제곱 값을 할당한 것은 여러 카테고리를 조합해 사용할 수 있도록 한 좋은 접근입니다. 이는 향후 복합 카테고리 지원 시 유용합니다.다만, 현재 코드에서는 이러한 비트 연산의 장점이 활용되지 않는 것으로 보입니다. 카테고리를 조합해서 사용할 계획이 없다면 간단한 순차적 값(1, 2, 3, ...)을 사용하는 것이 더 직관적일 수 있습니다.
비트 연산의 장점을 활용하고자 한다면, 다음과 같은 메서드를 추가하는 것이 좋을 것 같습니다:
fun hasCategory(categories: Int): Boolean = (code and categories) == code companion object { // 기존 코드... fun combine(vararg categories: Category): Int = categories.fold(0) { acc, category -> acc or category.code } }
26-34
: Companion 객체의 유틸리티 메서드가 유용합니다.
from(code: Int)
와from(title: String)
메서드는 카테고리를 조회하는 유용한 유틸리티 기능을 제공합니다. 특히 title 기반 조회 시 대소문자를 무시하는 것이 사용자 친화적입니다.한 가지 개선점은 유효하지 않은 입력에 대한 처리입니다. 현재는 예외를 발생시키지만, 상황에 따라 기본 카테고리(ETC)를 반환하거나 null을 반환하는 메서드도 추가하면 좋을 것 같습니다.
다음과 같은 추가 메서드를 고려해보세요:
companion object { // 기존 코드... fun fromOrNull(code: Int): Category? = values().find { it.code == code } fun fromOrNull(title: String): Category? = values().find { it.title.equals(title, ignoreCase = true) } fun fromOrDefault(code: Int, default: Category = ETC): Category = fromOrNull(code) ?: default fun fromOrDefault(title: String, default: Category = ETC): Category = fromOrNull(title) ?: default }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/core/gpt/prompt/PromptGenerator.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/core/gpt/prompt/schema/CategorySchema.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/Category.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/GenType.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/service/ProvisioningService.kt
(3 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: api-test
- GitHub Check: lint
- GitHub Check: docs
🔇 Additional comments (16)
domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt (1)
30-30
: 카테고리 필드 추가 적절히 구현됨프로비저닝 컨텐츠 응답에 카테고리 정보를 포함시키기 위한
category
필드가 적절히 추가되었습니다. 이 변경으로 클라이언트는 컨텐츠의 분류 정보를 받을 수 있게 되었습니다.domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt (1)
28-28
: 유스케이스 출력에 카테고리 필드 적절히 추가됨프로비저닝 컨텐츠 유스케이스 출력에
category
필드가 잘 추가되었습니다. 이는 컨트롤러 응답 모델과 일관성을 유지하며, 도메인 계층에서 카테고리 정보가 적절히 전달될 수 있도록 합니다.domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt (1)
71-71
: 컨트롤러 응답에 카테고리 필드 매핑 적절히 구현됨유스케이스로부터 받은 카테고리 정보가 API 응답 객체에 올바르게 매핑되었습니다. 이로써 클라이언트는 프로비저닝 컨텐츠의 카테고리 정보를 응답에서 받을 수 있게 됩니다.
domain/generator/src/main/kotlin/com/few/generator/core/gpt/prompt/schema/CategorySchema.kt (1)
1-22
:✅ Verification successful
카테고리 스키마 구현이 적절함
GPT 응답을 위한 카테고리 스키마가 적절히 정의되었습니다. 이 스키마는 카테고리 정보를 JSON 형식으로 구조화하고 필수 필드를 명시하여 유효성 검사를 가능하게 합니다.
다만, 허용 가능한 카테고리 값에 대한 제약이나 열거형이 스키마에 정의되어 있지 않습니다. 카테고리 값이 다른 파일에서 열거형으로 관리되고 있는지 확인하는 것이 좋겠습니다.
🏁 Script executed:
#!/bin/bash # 카테고리 열거형이 정의된 파일이 있는지 확인 fd -e kt | xargs grep -l "enum class Category"Length of output: 183
스키마 및 열거형 관리 검증 결과 확인됨
카테고리 스키마 구현은 적절하며, 필수 필드와 JSON 구조가 잘 정의되어 있습니다.
다만, 스키마에서 직접 열거형 제약 조건이 정의되어 있지는 않으나,
아래 파일에서 열거형으로 관리되고 있음을 확인했습니다.
api/src/main/kotlin/com/few/api/domain/common/vo/CategoryType.kt
domain/generator/src/main/kotlin/com/few/generator/domain/Category.kt
따라서 현재 스키마 구현에 추가 수정은 필요하지 않은 것으로 보입니다.
필요하다면 추후 열거형 목록을 스키마에 포함하는 것도 고려해볼 수 있습니다.domain/generator/src/main/kotlin/com/few/generator/service/ProvisioningService.kt (4)
30-30
: 카테고리 생성 기능이 추가되었습니다.새로운 카테고리 생성 로직이
create
메서드에 추가되었네요. 이제 컨텐츠에 대한 카테고리가 자동으로 생성됩니다.
35-35
: 카테고리 완료 ID가 completionIds 목록에 추가되었습니다.GPT를 통해 생성된 카테고리의 completionId가 ProvisioningContents의 completionIds 목록에 포함되도록 수정되었습니다.
38-38
: 카테고리 코드가 ProvisioningContents에 저장됩니다.CategorySchema의 category 값을 Category enum을 통해 코드 값으로 변환하여 ProvisioningContents에 저장하고 있습니다.
63-71
: makeCategory 메서드 구현이 적절합니다.새롭게 추가된
makeCategory
메서드는 제목, 설명, 핵심 텍스트를 바탕으로 GPT를 통해 카테고리를 결정하는 로직을 구현합니다. 기존의makeBodyTexts
와makeCoreTexts
메서드와 유사한 패턴을 따르고 있어 일관성이 있습니다.domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt (2)
24-25
: ProvisioningContents에 카테고리 필드가 추가되었습니다.
category
필드가Int
타입으로 추가되었고,@Column(nullable = false)
어노테이션을 통해 DB에서 null을 허용하지 않도록 설정되었습니다.
33-33
: 보호된 생성자에 카테고리 기본값이 설정되었습니다.기본 생성자에서
category
의 기본값을 0으로 설정하여 JPA 요구사항을 충족시켰습니다.domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt (2)
4-4
: 도메인 패키지 임포트가 와일드카드로 변경되었습니다.개별 클래스 임포트 대신
com.few.generator.domain.*
으로 변경하여 코드가 더 간결해졌습니다.
58-58
: 응답에 카테고리 정보가 포함되도록 구현되었습니다.BrowseProvisioningContentsUsecaseOut에
category = Category.from(provContents.category).name
을 추가하여 카테고리 코드를 이름으로 변환하여 응답에 포함시켰습니다.domain/generator/src/main/kotlin/com/few/generator/domain/GenType.kt (1)
9-12
: GenType 열거형 상수 값이 비트 시프트 연산으로 변경되었습니다.기존의 고정된 정수 값(2, 4, 8, 16) 대신 비트 시프트 연산(1 shl 1, 1 shl 2 등)을 사용하여 값을 정의하도록 변경되었습니다. 이는 값 자체는 변경되지 않으면서도 각 상수가 고유한 비트 플래그를 나타낸다는 의도를 명확히 합니다.
STRATEGY_NAME_BASIC: 1 shl 1 = 2 STRATEGY_NAME_KOREAN: 1 shl 2 = 4 STRATEGY_NAME_KOREAN_QUESTION: 1 shl 3 = 8 STRATEGY_NAME_KOREAN_LONG_QUESTION: 1 shl 4 = 16
이 방식은 비트 마스킹 연산이 필요할 때 더 명확하고 유지보수하기 쉽습니다.
domain/generator/src/main/kotlin/com/few/generator/core/gpt/prompt/PromptGenerator.kt (2)
3-7
: 새로운 의존성 추가가 적절합니다.필요한 의존성을 추가하여 카테고리 기능을 구현할 수 있도록 했습니다.
Gson
을 주입받아 카테고리 목록을 JSON으로 직렬화하는 것은 좋은 접근 방식입니다.
11-14
: 생성자에 Gson 의존성 주입이 적절합니다.
@Qualifier(GSON_BEAN_NAME)
어노테이션을 사용하여 특정 Gson 인스턴스를 주입받도록 한 점이 좋습니다. 이를 통해 애플리케이션의 다른 부분에서 사용하는 Gson 설정과 충돌 없이 일관된 직렬화가 가능합니다.domain/generator/src/main/kotlin/com/few/generator/domain/Category.kt (1)
3-6
: 카테고리 열거형이 잘 정의되었습니다.
Category
열거형은 코드와 제목을 가지고 있어 다양한 용도로 활용할 수 있습니다. 각 카테고리마다 고유한 코드와 사람이 읽을 수 있는 제목을 갖는 구조가 잘 설계되었습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다~~!
fun from(code: Int): Category = | ||
Category.values().find { it.code == code } | ||
?: throw IllegalArgumentException("Invalid Category code: $code") | ||
|
||
fun from(title: String): Category = | ||
values().find { it.title.equals(title, ignoreCase = true) } | ||
?: throw IllegalArgumentException("Invalid Category title: $title") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Category.values()
랑 values()
통일하면 좋을 것 같아요
val code: Int, | ||
val title: String, | ||
) { | ||
TECHNOLOGY(1 shl 1, "Technology"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shl 은 어떤 의미에요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
쉬프트 연산 <<
bodyTextsJson = gson.toJson(bodyTexts.texts), // TODO: DB 저장 타입 등 정의, 수정 필요 | ||
coreTextsJson = gson.toJson(coreTexts.texts), | ||
category = Category.from(categorySchema.category).code, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
없을 것 같은데 혹시라도 gpt가 선언한 카테고리 이외의 값을 반환했을 때는 Category.from
에서 발생하는 예외로 충분하겠죠?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네네 그럴 경우엔 아에 실행중단하는게 맞을거 같네여 (무조건 ETC 카테고리로 지정하는건 옳지 않아보임)
🎫 연관 이슈
resolved #615
💁♂️ PR 내용
🙏 작업
🙈 PR 참고 사항
📸 스크린샷
🚩 추가된 SQL 운영계 실행계획
🤖 테스트 체크리스트
Summary by CodeRabbit