-
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/#613] GPT 생성 컨텐츠 조회 API 추가 #614
Conversation
""" Walkthrough이번 PR은 생성된 컨텐츠 조회와 관련된 API 엔드포인트 및 내부 로직을 확장합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant C as Client
participant Ctrl as ContentsGeneratorController
participant UC as RawContentsBrowseContentUseCase
participant RCR as RawContentsRepository
participant PCR as ProvisioningContentsRepository
participant GR as GenRepository
participant Resp as ApiResponseGenerator
C->>Ctrl: GET /rawcontents/{id}
Ctrl->>UC: execute(rawContentsId)
UC->>RCR: findById(rawContentsId)
RCR-->>UC: RawContents 데이터
UC->>PCR: findByRawContentsId(rawContentsId)
PCR-->>UC: ProvisioningContents 데이터
UC->>GR: findByProvisioningContentsId(provisioningContentsId)
GR-->>UC: List<Gen> 데이터
UC-->>Ctrl: BrowseContentsUsecaseOut 구성
Ctrl->>Resp: ApiResponseGenerator.success(결과)
Resp-->>C: API 응답 반환
Assessment against linked issues
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
✨ Finishing Touches
🪧 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.
Actionable comments posted: 2
🧹 Nitpick comments (3)
domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt (1)
16-70
: 유스케이스 구현이 잘 되었습니다만, 예외 처리 방식 개선 필요컨텐츠 조회 API를 위한 유스케이스가 잘 구현되었습니다. 트랜잭션 설정도 읽기 전용으로 적절하게 설정되어 있습니다. 다만 몇 가지 개선 사항을 제안합니다:
- 일반
RuntimeException
대신 더 구체적인 예외 타입을 사용하는 것이 좋습니다.- 널 체크를 위해
!!
연산자를 여러 곳에서 사용하고 있는데, 이는 코드가 실행 중에 예기치 않게 실패할 수 있는 위험이 있습니다.다음과 같이 개선할 수 있습니다:
- .orElseThrow { RuntimeException("컨텐츠가 존재하지 않습니다.") } + .orElseThrow { NoSuchElementException("컨텐츠가 존재하지 않습니다.") } - provisioningContentsRepository.findByRawContentsId(rawContents.id!!) - ?: throw RuntimeException("프로비저닝 컨텐츠가 존재하지 않습니다.") + provisioningContentsRepository.findByRawContentsId(rawContents.id) + ?: throw NoSuchElementException("프로비저닝 컨텐츠가 존재하지 않습니다.")그리고 엔티티 ID에 안전하게 접근하는 확장 함수를 만들어 활용하는 것도 고려해보세요:
fun <T> T.requireId(): Long where T : BaseEntity { return id ?: throw IllegalStateException("엔티티 ID가 없습니다") }domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt (1)
5-39
: 응답 클래스와 유스케이스 출력 클래스 간의 중복
BrowseContentsResponse
와BrowseContentsUsecaseOut
클래스 구조가 매우 유사합니다. 이런 중복은 유지보수 비용이 증가할 수 있습니다. 레이어 간 변환 로직을 간소화하기 위한 방법으로 매퍼 패턴 활용이나 공통 인터페이스 정의를 고려해보세요.예를 들어, 매퍼 클래스를 도입하거나 확장 함수를 사용할 수 있습니다:
fun BrowseContentsUsecaseOut.toResponse(): BrowseContentsResponse { return BrowseContentsResponse( rawContents = rawContents.toResponse(), provisioningContents = provisioningContents.toResponse(), gens = gens.map { it.toResponse() } ) } fun BrowseRawContentsUsecaseOut.toResponse(): BrowseRawContentsResponse { return BrowseRawContentsResponse( id = id, url = url, title = title, description = description, thumbnailImageUrl = thumbnailImageUrl, rawTexts = rawTexts, imageUrls = imageUrls, createdAt = createdAt ) } // 다른 변환 함수들도 유사하게 구현domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt (1)
50-83
: 응답 객체 생성 로직 분리 고려현재 컨트롤러에서 복잡한 응답 객체를 직접 구성하고 있습니다. 이 매핑 로직은 단일 책임 원칙을 준수하기 위해 별도의 매퍼 클래스로 이동하는 것이 좋습니다. 또한
!!
연산자 사용에 주의가 필요합니다.아래와 같이 매퍼 클래스를 만들어 사용하는 것을 고려해보세요:
// 매퍼 클래스 예시 object BrowseContentsResponseMapper { fun toResponse(useCaseOut: RawContentsBrowseContentUseCaseOutput): BrowseContentsResponse { return BrowseContentsResponse( rawContents = toRawContentsResponse(useCaseOut.rawContents), provisioningContents = toProvisioningContentsResponse(useCaseOut.provisioningContents), gens = useCaseOut.gens.map { toGenResponse(it) } ) } private fun toRawContentsResponse(rawContents: RawContents): BrowseRawContentsResponse { return BrowseRawContentsResponse( id = rawContents.id ?: throw IllegalStateException("Raw contents ID cannot be null"), // 나머지 필드들... ) } // 다른 매핑 메소드들... } // 컨트롤러에서 사용 return ApiResponseGenerator.success( BrowseContentsResponseMapper.toResponse(useCaseOut), HttpStatus.OK )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt
(3 hunks)domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/BaseEntity.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/repository/GenRepository.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/repository/ProvisioningContentsRepository.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
(1 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 (15)
domain/generator/src/main/kotlin/com/few/generator/repository/ProvisioningContentsRepository.kt (1)
6-8
: 새로운 메서드 구현이 적절합니다.rawContentsId로 ProvisioningContents를 조회하는 메서드가 추가되었습니다. 이 메서드는 Spring Data JPA의 명명 규칙을 따르고 있으며, PR 요약에 언급된 "ID로 컨텐츠를 조회하는 API" 구현에 필요한 기능입니다.
domain/generator/src/main/kotlin/com/few/generator/repository/GenRepository.kt (1)
6-8
: 리포지토리 메서드 추가가 적절합니다.provisioningContentsId를 기반으로 Gen 엔티티 목록을 조회하는 메서드가 추가되었습니다. Spring Data JPA 명명 규칙을 잘 따르고 있으며, 컨텐츠 ID를 통한 데이터 조회 기능 구현에 필요한 메서드입니다.
domain/generator/src/main/kotlin/com/few/generator/domain/BaseEntity.kt (1)
15-15
: 변경된 필드 불변성이 적절합니다.createdAt 필드가 var에서 val로 변경되어 불변(immutable)하게 만들어졌습니다. 생성 시간은 생성 후 변경되지 않아야 하므로 이는 좋은 변경사항입니다. 또한 @column(updatable = false) 애노테이션과도 잘 일치합니다.
domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt (1)
7-10
: 인덱스 추가가 적절합니다.Gen 테이블에 provisioning_contents_id 컬럼에 대한 인덱스를 추가했습니다. PR 요약에 언급된 "gen과 provisioning_contents 테이블에 인덱스 추가"에 해당하는 변경사항으로, GenRepository에 추가된 findByProvisioningContentsId 메서드의 성능을 향상시킬 것입니다.
domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt (1)
7-10
: 인덱스 추가로 인한 성능 개선 좋습니다!
raw_contents_id
컬럼에 unique 인덱스를 추가한 것은 쿼리 성능을 향상시키고 데이터 무결성을 보장하는 좋은 변경사항입니다. PR 목표에 언급된 대로 데이터베이스 성능 향상을 위한 인덱스 추가가 적절하게 구현되었습니다.domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt (4)
5-9
: 응답 데이터 구조가 명확하게 정의되었습니다
BrowseContentsResponse
클래스가 API 응답 구조를 명확하게 정의하고 있습니다. 컨텐츠 조회를 위한 세 가지 주요 데이터(rawContents
,provisioningContents
,gens
)를 포함하고 있어 클라이언트에서 데이터를 쉽게 접근할 수 있습니다.
11-20
: 원본 컨텐츠 응답 구조가 잘 정의되었습니다
BrowseRawContentsResponse
클래스의 구조가 적절하게 정의되어 있습니다. 기본값과 널 허용 필드도 논리적으로 설정되어 있습니다.
22-29
: 프로비저닝 컨텐츠 응답 구조가 잘 정의되었습니다
BrowseProvisioningContentsResponse
클래스의 구조가 적절하게 정의되어 있습니다. JSON 문자열 필드에 대한 기본값 설정이 잘 되어 있습니다.
31-39
: 생성된 컨텐츠 응답 구조가 잘 정의되었습니다
BrowseGenResponse
클래스의 구조가 적절하게 정의되어 있습니다. 필요한 모든 필드가 포함되어 있고 기본값 설정도 잘 되어 있습니다.domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt (1)
5-9
: 유스케이스 출력 구조가 명확하게 정의되었습니다
BrowseContentsUsecaseOut
클래스가 유스케이스의 출력 구조를 명확하게 정의하고 있습니다. 컨트롤러 응답 클래스와 구조적으로 유사하여 매핑이 용이할 것입니다.domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt (5)
4-4
: 필요한 클래스들이 올바르게 추가되었습니다!새로운 기능을 위한 적절한 임포트가 추가되었습니다.
Also applies to: 6-7, 9-9
18-18
: 의존성 주입이 올바르게 수행되었습니다.컨트롤러에
RawContentsBrowseContentUseCase
를 추가하여 새 엔드포인트를 지원합니다.
20-24
: API 명세가 명확해져 좋습니다.
consumes
와produces
속성을 명시적으로 지정하여 API 계약이 더 명확해졌습니다.
42-46
: 경로 변수 검증이 잘 구현되었습니다.
@Min
어노테이션을 사용하여 ID 유효성 검사를 올바르게 구현했습니다.
41-85
: 새 엔드포인트 구현이 잘 되었습니다.ID로 컨텐츠를 조회하는 새 엔드포인트가 잘 구현되었습니다. 응답 구조가 명확하며 필요한 모든 데이터를 포함하고 있습니다.
BrowseContentsResponse( | ||
rawContents = | ||
BrowseRawContentsResponse( | ||
id = useCaseOut.rawContents.id!!, |
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.
🛠️ Refactor suggestion
Null 안전성 확보 필요
여러 곳에서 !!
연산자를 사용하고 있습니다. 이는 런타임에 NullPointerException
을 발생시킬 수 있습니다. 데이터베이스에서 가져온 엔티티의 ID나 생성 시간이 null이 아니라고 확신할 수 있다면 문제가 없지만, 가능하면 ?.let
또는 ?:
연산자를 사용하여 null을 더 안전하게 처리하는 것이 좋습니다.
// 예시
id = useCaseOut.rawContents.id ?: throw IllegalStateException("Raw contents ID cannot be null"),
createdAt = useCaseOut.rawContents.createdAt ?: throw IllegalStateException("Created timestamp cannot be null"),
Also applies to: 60-60, 64-64, 69-69, 74-74, 80-80
domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt
Outdated
Show resolved
Hide resolved
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 (7)
domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt (7)
30-34
: 예외 처리를 더 구체적으로 개선하는 것이 좋겠습니다.일반적인
RuntimeException
대신 도메인에 특화된 예외 클래스를 사용하는 것이 좋습니다. 이렇게 하면 예외 처리가 더 명확해지고 호출자가 더 세밀하게 예외를 처리할 수 있습니다.- .orElseThrow { RuntimeException("컨텐츠가 존재하지 않습니다.") } + .orElseThrow { ContentNotFoundException("컨텐츠가 존재하지 않습니다.") }참고:
ContentNotFoundException
클래스를 별도로 정의해야 합니다.
35-38
: Null 검사 로직을 개선할 수 있습니다.현재 코드에서는 null 체크와 예외 발생 로직이 한 줄에 있습니다. 가독성을 위해 로직을 분리하고, 커스텀 예외를 사용하는 것이 좋습니다.
- val provContents: ProvisioningContents = - provisioningContentsRepository.findByRawContentsId(rawContents.id!!) - ?: throw RuntimeException("프로비저닝 컨텐츠가 존재하지 않습니다.") + val provContents: ProvisioningContents = provisioningContentsRepository.findByRawContentsId(rawContents.id!!) + ?: throw ProvisioningContentNotFoundException("프로비저닝 컨텐츠가 존재하지 않습니다.")
44-52
: null 아님 단언 연산자(!!
) 사용에 주의가 필요합니다.
!!
연산자 사용은 코드가 깔끔해 보이지만 잠재적으로 NullPointerException을 발생시킬 수 있습니다. 데이터베이스에서 가져온 엔티티의 ID나 생성 시간이 null이 아닐 것으로 예상되지만, 안전을 위해requireNotNull()
이나 명시적인 null 체크를 고려해 보세요.- id = rawContents.id!!, + id = requireNotNull(rawContents.id) { "Raw contents ID should not be null" },유사한 변경을 다른
!!
사용 부분에도 적용할 수 있습니다.
50-51
: JSON 파싱 성능 최적화를 고려해 보세요.
gson.fromJson
을 사용한 JSON 파싱이 여러 곳에서 반복됩니다. 대용량 데이터를 처리할 경우 성능 저하가 발생할 수 있습니다. 재사용 가능한 TypeToken 인스턴스를 클래스 수준에서 정의하는 것이 좋습니다.@Component class RawContentsBrowseContentUseCase( private val rawContentsRepository: RawContentsRepository, private val provisioningContentsRepository: ProvisioningContentsRepository, private val genRepository: GenRepository, @Qualifier(GSON_BEAN_NAME) private val gson: Gson, ) { + private val stringListType = object : TypeToken<List<String>>() {}.type @GeneratorTransactional(readOnly = true) fun execute(rawContentsId: Long): BrowseContentsUsecaseOut { // ... return BrowseContentsUsecaseOut( rawContents = BrowseRawContentsUsecaseOut( // ... - imageUrls = gson.fromJson(rawContents.imageUrls, object : TypeToken<List<String>>() {}.type), + imageUrls = gson.fromJson(rawContents.imageUrls, stringListType), // ... ), // 다른 gson.fromJson 호출에도 동일하게 적용 ) } }
41-74
: 매핑 로직을 분리하여 가독성을 향상시키는 것이 좋습니다.도메인 엔티티에서 DTO로의 변환 로직이
execute
메서드 내에 직접 구현되어 있습니다. 이 로직을 별도의 메서드나 매퍼 클래스로 분리하면 코드 가독성과 유지보수성이 향상됩니다.예를 들어, 다음과 같이 매핑 메서드를 추가할 수 있습니다:
private fun mapRawContentsToOut(rawContents: RawContents): BrowseRawContentsUsecaseOut { return BrowseRawContentsUsecaseOut( id = requireNotNull(rawContents.id), url = rawContents.url, title = rawContents.title, description = rawContents.description, thumbnailImageUrl = rawContents.thumbnailImageUrl, rawTexts = rawContents.rawTexts, imageUrls = gson.fromJson(rawContents.imageUrls, stringListType), createdAt = requireNotNull(rawContents.createdAt), ) } // 다른 엔티티에 대해서도 유사한 매핑 메서드 추가그리고
execute
메서드에서는 이러한 매핑 메서드를 호출하여 코드의 가독성을 높일 수 있습니다.
64-73
: Gen 엔티티 매핑 시 성능 최적화를 고려해 보세요.
gens.map { ... }
내부에서 각 Gen 엔티티마다gson.fromJson
을 호출하고 있습니다. Gen 리스트가 큰 경우 성능 저하가 발생할 수 있습니다. 앞서 제안한stringListType
재사용과 함께, 매핑 로직을 별도 메서드로 분리하면 코드가 더 깔끔해집니다.
1-76
: 기능적으로 잘 구현되었으나 코드 품질 향상을 위한 몇 가지 제안이 있습니다.전반적으로 로직은 명확하게 구현되었으나, 다음 사항을 고려해 보세요:
- 구체적인 예외 클래스 사용
- Null 안전성 강화
- JSON 파싱 성능 최적화
- 매핑 로직 분리
- 단위 테스트 작성 (현재 파일에 포함되지 않음)
이러한 개선을 통해 코드의 안정성과 유지보수성을 더욱 높일 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt
- domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: api-test
- GitHub Check: docs
- GitHub Check: lint
🔇 Additional comments (2)
domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt (2)
20-27
: 클래스 설계가 명확하며 의존성 주입이 잘 이루어졌습니다.컴포넌트 구조와 의존성 주입이 적절하게 설계되었습니다.
@Qualifier
어노테이션을 사용하여 특정 Gson 빈을 명시적으로 주입한 것이 좋습니다.
28-29
: 트랜잭션 설정이 적절합니다.읽기 전용 작업에
@GeneratorTransactional(readOnly = true)
를 사용한 것은 좋은 방식입니다. 데이터베이스 성능 최적화에 도움이 됩니다.
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: 1
🧹 Nitpick comments (3)
domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt (1)
24-32
: 기본 생성자 필요성 검토 필요TODO 주석에서 언급하신 것처럼 이 기본 생성자의 필요성을 검토해보세요. JPA에서는 기본 생성자가 필요하지만, 일반적으로 public보다는 protected 접근 제어자를 사용하는 것이 권장됩니다. 또한, rawContentsId를 0L로 초기화하는 것이 비즈니스 로직에 맞는지 확인해주세요.
- constructor() : this( // TODO: 기본 생성자 필요? + protected constructor() : this( // JPA를 위한 기본 생성자또한, 데이터 클래스와 JPA 엔티티 조합 시 프록시 생성과 지연 로딩에 문제가 발생할 수 있으니 주의하세요.
library/web/src/main/kotlin/web/security/config/LocalDelegatedSecurityConfigurer.kt (1)
112-115
: 코드 주석 개선 필요현재
generators
관련 경로에 대한 주석은 있지만, 새로 추가된rawcontents
경로에 대한 설명이 없습니다. 코드 유지보수와 가독성을 위해 이 새로운 API 엔드포인트의 목적과 사용 사례에 대한 간략한 설명을 주석으로 추가하는 것이 좋습니다./** * generator */ AntPathRequestMatcher("/api/v1/generators/contents"), + /** + * raw contents + * GPT 생성 컨텐츠 조회 API + */ AntPathRequestMatcher("/api/v1/rawcontents/**"),domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt (1)
27-34
: 기본 생성자에 대한 검토 필요기본 생성자는 JPA 엔티티에서 일반적으로 필요하지만, TODO 주석에서도 언급된 것처럼 이 생성자가 실제로 필요한지 검토가 필요합니다. Kotlin에서는 data class가 자동으로 생성자와 getter/setter를 생성하지만, JPA는 기본 생성자를 필요로 합니다.
JPA가 기본 생성자를 사용할 때에만 필요하므로, 프로덕션 코드에서 이 생성자를 직접 호출하지 않는다면 protected로 선언하는 것이 안전합니다:
- constructor() : this( // TODO: 기본 생성자 필요? + protected constructor() : this( // JPA가 사용하는 기본 생성자 id = null, provisioningContentsId = 0L, completionIds = mutableListOf(), headline = "", summary = "", highlightTexts = "[]", )또한 TODO 주석은 코드 리뷰 과정에서 해결하고 제거하는 것이 좋습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/RawContents.kt
(1 hunks)library/web/src/main/kotlin/web/security/config/LocalDelegatedSecurityConfigurer.kt
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: api-test
- GitHub Check: docs
- GitHub Check: lint
🔇 Additional comments (3)
domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt (1)
7-10
: 인덱스 추가 - 좋은 성능 개선!unique 인덱스 추가는 데이터 무결성과 조회 성능 개선에 도움이 됩니다. 다만, 기존 데이터베이스에 중복된 raw_contents_id 값이 있는 경우 마이그레이션 시 오류가 발생할 수 있으니 이 부분을 고려해주세요.
library/web/src/main/kotlin/web/security/config/LocalDelegatedSecurityConfigurer.kt (1)
115-115
: 보안 설정에 추가된 경로 패턴 확인 필요새로 추가된
/api/v1/rawcontents/**
경로는 인증 및 권한 검사를 우회하게 됩니다. 이 엔드포인트가 공개적으로 접근 가능해야 하는 이유와 민감한 데이터가 노출되지 않는지 확인해주세요. 또한, 가능하다면/api/v1/rawcontents/**
와 같은 와일드카드보다 더 구체적인 경로 패턴(HTTP 메서드 제한 포함)을 사용하는 것이 보안 측면에서 더 안전할 수 있습니다.- AntPathRequestMatcher("/api/v1/rawcontents/**"), + AntPathRequestMatcher("/api/v1/rawcontents/**", HttpMethod.GET.name()),위 수정안처럼 HTTP 메서드를 명시적으로 제한하는 것이 좋습니다.
domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt (1)
7-10
: 테이블 인덱스 추가는 성능 향상에 도움이 됩니다.
provisioning_contents_id
컬럼에 인덱스를 추가한 것은 PR 목표에 부합하며 조회 성능을 향상시킬 것입니다. 이 필드를 기준으로Gen
엔티티를 조회하는 쿼리가 최적화되어 콘텐츠 ID 기반 API 조회가 더 효율적으로 동작할 것입니다.
domain/generator/src/main/kotlin/com/few/generator/domain/RawContents.kt
Outdated
Show resolved
Hide resolved
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 (4)
domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt (2)
28-29
: JSON 데이터 타입 고려
bodyTextsJson
과coreTextsJson
은 현재 문자열 리스트로 정의되어 있습니다. 이 필드들이 JSON 형태의 데이터를 나타낸다면, 직렬화된 객체 대신 적절한 타입(예: Map 또는 구체적인 데이터 클래스)을 사용하는 것이 타입 안전성을 높일 수 있습니다.데이터 구조가 명확하다면 다음과 같이 변경을 고려해 보세요:
- val bodyTextsJson: List<String>, - val coreTextsJson: List<String>, + val bodyTexts: List<BodyTextData>, + val coreTexts: List<CoreTextData>,여기서
BodyTextData
와CoreTextData
는 실제 데이터 구조를 반영하는 별도의 데이터 클래스입니다.
20-21
: 날짜 형식 코드 중복 개선 고려세 개의 클래스에서 동일한
@JsonFormat
어노테이션이 반복되고 있습니다. 이러한 중복을 줄이기 위해 커스텀 어노테이션이나 기본 클래스를 도입하는 것을 고려해 볼 수 있습니다.// 예시: 커스텀 어노테이션 생성 @Target(AnnotationTarget.FIELD) @Retention(AnnotationRetention.RUNTIME) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") annotation class FormattedDateTime // 사용 예시 @FormattedDateTime val createdAt: LocalDateTime,Also applies to: 30-31, 42-43
domain/generator/src/main/kotlin/com/few/generator/domain/GEN_TYPE.kt (1)
1-25
: GEN_TYPE 열거형 추가 - 잘 설계된 타입 시스템새로 추가된 GEN_TYPE 열거형은 다양한 생성 전략을 명확하게 구분하고 코드와 타이틀을 관리하는 잘 설계된 타입 시스템을 제공합니다. 또한 코드 및 타이틀을 통해 열거형을 조회하는 유틸리티 메서드도 제공하고 있습니다.
각 전략 유형에 비트 플래그처럼 보이는 숫자 코드(2, 4, 8, 16)를 사용한 것은 향후 확장성을 고려한 좋은 설계입니다.
다만, 열거형 선언 끝부분에 불필요한 세미콜론이 있으므로 제거를 고려해보세요. Kotlin에서는 필요하지 않습니다.
- ;
domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt (1)
29-37
: 기본 생성자에 대한 검토가 필요합니다.코드에 TODO 코멘트로 표시된 것처럼 이 기본 생성자가 정말 필요한지 검토해 보세요. JPA에서는 기본 생성자가 필요하지만, 이를 protected로 설정하거나 Kotlin의 no-arg 플러그인을 사용하는 것이 더 안전할 수 있습니다.
또한 기본값들이 비즈니스 로직에 적합한지 확인하세요. 특히 빈 문자열이나 0 값이 도메인 관점에서 의미가 있는지 검토가 필요합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/GEN_TYPE.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/GenService.kt
(5 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/BasicGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/GenGenerationStrategy.kt
(0 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanLongQuestionGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanQuestionGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/support/common/Constant.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt
(1 hunks)
💤 Files with no reviewable changes (1)
- domain/generator/src/main/kotlin/com/few/generator/service/strategy/GenGenerationStrategy.kt
✅ Files skipped from review due to trivial changes (2)
- domain/generator/src/main/kotlin/com/few/generator/service/GenService.kt
- domain/generator/src/main/kotlin/com/few/generator/support/common/Constant.kt
🚧 Files skipped from review as they are similar to previous changes (3)
- domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
- domain/generator/src/main/kotlin/com/few/generator/usecase/out/BrowseContentsUsecaseOut.kt
- domain/generator/src/main/kotlin/com/few/generator/controller/ContentsGeneratorController.kt
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: api-test
- GitHub Check: docs
- GitHub Check: lint
🔇 Additional comments (21)
domain/generator/src/main/kotlin/com/few/generator/controller/response/BrowseContentsResponse.kt (6)
6-10
: 응답 구조가 잘 설계되어 있습니다.이 클래스는 컨텐츠 조회 API의 응답 구조를 명확하게 정의하고 있으며, 원시 컨텐츠, 프로비저닝 컨텐츠 및 생성된 컨텐츠 목록을 포함하는 계층적 구조가 잘 구성되어 있습니다.
12-22
: 원시 컨텐츠 응답 클래스가 필요한 필드를 모두 포함하고 있습니다.
BrowseRawContentsResponse
클래스는 콘텐츠 ID, URL, 제목, 설명, 썸네일 등 필요한 모든 필드를 적절하게 포함하고 있습니다. 썸네일 이미지 URL을 nullable로 설정한 것은 좋은 접근 방식입니다.날짜 형식 지정을 위한
@JsonFormat
어노테이션이 적절하게 사용되었습니다.
18-18
:rawTexts
필드 타입 확인 필요현재
rawTexts
가 단일 String 타입으로 정의되어 있습니다. 이 필드가 여러 텍스트를 포함해야 한다면List<String>
타입으로 변경하는 것이 더 적절할 수 있습니다.이 필드가 실제로 단일 문자열로 사용되는지 확인해 주세요.
24-32
: 프로비저닝 컨텐츠 응답 클래스 구조가 적절합니다.
BrowseProvisioningContentsResponse
클래스는 원시 컨텐츠 ID를 참조하고 완성 ID 목록, 본문 및 핵심 텍스트를 포함하여 계층적 관계를 잘 표현하고 있습니다.
34-44
: 생성된 컨텐츠 응답 클래스 구조가 적절합니다.
BrowseGenResponse
클래스는 생성된 컨텐츠에 필요한 모든 필드를 포함하고 있으며, 프로비저닝 컨텐츠 ID를 참조하여 계층적 관계를 명확히 표현하고 있습니다.
20-21
: 날짜 포맷 일관성이 잘 유지됨
createdAt
필드에 대한 동일한@JsonFormat
패턴이 모든 응답 클래스에서 일관되게 사용되었습니다. 이는 응답 형식의 일관성을 유지하는 좋은 예입니다.Also applies to: 30-31, 42-43
domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanGenGenerationStrategy.kt (3)
7-7
: 새로운 임포트 추가에 대한 긍정적인 변경GEN_TYPE 및 Constant 클래스를 임포트하여 코드의 일관성과 중앙화된 상수 관리를 개선했습니다.
Also applies to: 9-9
12-12
: Component 어노테이션 리팩토링하드코딩된 문자열 대신 Constant.GEN 클래스의 상수를 사용하도록 변경하여 코드 유지보수성이 향상되었습니다.
42-42
: Gen 엔티티에 타입 정보 추가Gen 생성자에 typeCode 속성이 추가되어 컨텐츠 타입 식별이 가능해졌습니다. 이는 컨텐츠 ID 기반 조회 API 구현에 필요한 변경사항으로 보입니다.
domain/generator/src/main/kotlin/com/few/generator/service/strategy/BasicGenGenerationStrategy.kt (3)
7-7
: 새로운 임포트 추가에 대한 긍정적인 변경GEN_TYPE 및 Constant 클래스를 임포트하여 코드의 일관성과 중앙화된 상수 관리를 개선했습니다.
Also applies to: 9-9
12-12
: Component 어노테이션 리팩토링하드코딩된 문자열 대신 Constant.GEN 클래스의 상수를 사용하도록 변경하여 코드 유지보수성이 향상되었습니다.
29-29
: Gen 엔티티에 타입 정보 추가Gen 생성자에 typeCode 속성이 추가되어 컨텐츠 타입 식별이 가능해졌습니다. 이는 컨텐츠 ID 기반 조회 API 구현에 필요한 변경사항입니다.
domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanQuestionGenGenerationStrategy.kt (3)
9-9
: 새로운 임포트 추가에 대한 긍정적인 변경GEN_TYPE 및 Constant 클래스를 임포트하여 코드의 일관성과 중앙화된 상수 관리를 개선했습니다.
Also applies to: 11-11
16-16
: Component 어노테이션 리팩토링하드코딩된 문자열 대신 Constant.GEN 클래스의 상수를 사용하도록 변경하여 코드 유지보수성이 향상되었습니다.
51-51
: Gen 엔티티에 타입 정보 추가Gen 생성자에 typeCode 속성이 추가되어 컨텐츠 타입 식별이 가능해졌습니다. 이는 컨텐츠 ID 기반 조회 API 구현에 필요한 변경사항으로, 모든 전략에 일관되게 적용되었습니다.
domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt (3)
7-10
: 인덱스 추가로 성능 개선이 기대됩니다.
provisioning_contents_id
컬럼에 인덱스를 추가하는 것은 이 컬럼을 기반으로 한 쿼리 성능을 크게 향상시킬 것입니다. 특히 컨텐츠 조회 API가 이 필드를 자주 사용한다면 적절한 최적화입니다.
26-27
:typeCode
필드 추가는 적절합니다.타입 코드를 통해 다양한 생성 전략을 구분할 수 있어 확장성이 향상됩니다. 이는 PR 목표와 일치하는 변경사항입니다.
11-11
: 기존 TODO 코멘트에 대한 계획이 있나요?"DB컬럼 타입 변경 필요"라는 TODO 코멘트가 있습니다. 이 PR의 일부로 이 이슈도 해결할 계획이 있으신지요? 아니라면 별도의 이슈로 트래킹하는 것이 좋겠습니다.
domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanLongQuestionGenGenerationStrategy.kt (3)
16-16
: 컴포넌트 이름 상수화는 좋은 변경입니다.전략 이름을 하드코딩하는 대신
Constant.GEN.STRATEGY_NAME_KOREAN_LONG_QUESTION
와 같은 상수를 사용하는 것은 유지보수성과 일관성을 향상시킵니다. 이는 좋은 프랙티스입니다.
9-9
:typeCode
사용은 적절하나 검증이 필요할 수 있습니다.
GEN_TYPE
enum을 사용하여typeCode
를 설정하는 것은 타입 안전성을 보장하는 좋은 방법입니다. 그러나 이 값이 적절한지 검증하는 메커니즘이 시스템 어딘가에 있는지 확인하세요.또한 기존 데이터나 마이그레이션 계획에 대한 고려가 필요합니다. 기존 데이터에 대해 이
typeCode
필드를 어떻게 처리할 계획인지요?Also applies to: 52-52
24-54
: 전반적인 생성 로직은 잘 구현되어 있습니다.
generate
메소드의 전체 로직은 단계별로 잘 구성되어 있습니다. 헤드라인, 요약, 하이라이트 텍스트를 순차적으로 생성하고 최종Gen
객체를 반환하는 흐름이 명확합니다.typeCode
추가는 기존 로직을 방해하지 않으면서 필요한 정보를 추가하고 있습니다.
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 (4)
domain/generator/src/main/kotlin/com/few/generator/domain/GenType.kt (4)
16-20
: from 메서드 이름을 더 명확하게 변경하는 것을 고려해보세요.
from
메서드는 일반적인 이름입니다.fromCode
와 같이 더 구체적인 이름을 사용하면 메서드의 목적이 더 명확해질 것입니다.- fun from(code: Int): GenType = + fun fromCode(code: Int): GenType =
21-24
: from(title) 메서드 이름을 더 명확하게 변경하는 것을 고려해보세요.마찬가지로 문자열 타이틀을 매개변수로 받는
from
메서드도fromTitle
과 같이 더 구체적인 이름을 사용하면 좋겠습니다.- fun from(title: String): GenType = + fun fromTitle(title: String): GenType =
17-24
: 예외 메시지 언어의 일관성을 확인하세요.예외 메시지가 영어로 작성되어 있습니다. 애플리케이션의 다른 예외 메시지들이 한국어로 되어 있다면, 일관성을 위해 한국어로 메시지를 작성하는 것이 좋겠습니다.
- ?: throw IllegalArgumentException("Invalid GEN_TYPE code: $code") + ?: throw IllegalArgumentException("유효하지 않은 GEN_TYPE 코드: $code") - ?: throw IllegalArgumentException("Invalid GEN_TYPE name: $title") + ?: throw IllegalArgumentException("유효하지 않은 GEN_TYPE 이름: $title")
5-25
: 코드 값과 타이틀의 중복 검사가 필요할 수 있습니다.현재 코드에서는 열거형 상수들 간에 코드 값이나 타이틀이 중복되지 않는지 검사하는 로직이 없습니다. 런타임에 중복된 값이 있을 경우
from
메서드가 첫 번째로 찾은 값을 반환하게 됩니다. 초기화 시 중복 검사를 수행하는 static 초기화 블록을 추가하는 것을 고려해보세요.companion object { init { val codeSet = mutableSetOf<Int>() val titleSet = mutableSetOf<String>() for (type in values()) { if (!codeSet.add(type.code)) { throw IllegalStateException("중복된 GenType 코드 발견: ${type.code}") } if (!titleSet.add(type.title)) { throw IllegalStateException("중복된 GenType 타이틀 발견: ${type.title}") } } } // 기존 메서드들... }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
domain/generator/src/main/kotlin/com/few/generator/domain/GenType.kt
(1 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/BasicGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanLongQuestionGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanQuestionGenGenerationStrategy.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanQuestionGenGenerationStrategy.kt
- domain/generator/src/main/kotlin/com/few/generator/service/strategy/BasicGenGenerationStrategy.kt
- domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanGenGenerationStrategy.kt
- domain/generator/src/main/kotlin/com/few/generator/service/strategy/KoreanLongQuestionGenGenerationStrategy.kt
- domain/generator/src/main/kotlin/com/few/generator/usecase/RawContentsBrowseContentUseCase.kt
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: api-test
- GitHub Check: docs
- GitHub Check: lint
🔇 Additional comments (2)
domain/generator/src/main/kotlin/com/few/generator/domain/GenType.kt (2)
5-8
: 열거형 클래스 설계가 잘 되었습니다.
GenType
열거형 클래스는 코드와 제목을 속성으로 가지는 좋은 설계입니다. 이를 통해 생성 전략들을 체계적으로 관리할 수 있습니다.
9-12
:❓ Verification inconclusive
코드 값이 2의 거듭제곱으로 설정된 이유가 있나요?
현재 코드 값이 2, 4, 8, 16으로 설정되어 있습니다. 이는 비트 연산을 위한 설계인지, 아니면 다른 이유가 있는지 명확하지 않습니다. 만약 비트 연산을 위한 것이라면 주석을 추가하는 것이 좋겠습니다.
🏁 Script executed:
#!/bin/bash # 프로젝트에서 GenType의 코드 값을 비트 연산자로 사용하는 코드가 있는지 확인합니다 rg "GenType.*[&|]" --type kotlinLength of output: 34
비트 연산 의도 명확화 필요 (파일: domain/generator/src/main/kotlin/com/few/generator/domain/GenType.kt, 9-12)
현재
STRATEGY_NAME_BASIC(2, …)
,STRATEGY_NAME_KOREAN(4, …)
,STRATEGY_NAME_KOREAN_QUESTION(8, …)
,STRATEGY_NAME_KOREAN_LONG_QUESTION(16, …)
와 같이 2의 거듭제곱 값이 할당되어 있는데, 검색 결과 코드 내에서 이 값들이 비트 연산(예: & 또는 |)으로 활용되는 흔적은 확인되지 않았습니다.
- 만약 향후 비트 연산 목적으로 사용될 의도가 있다면, 그 점을 명확히 드러내는 주석을 추가해주시기 바랍니다.
- 그렇지 않고 단순히 일정 패턴(2의 거듭제곱)을 따르는 값으로 선택된 것이라면, 이러한 선택 이유를 코드에 명시함으로써 다른 개발자가 이해하기 쉽도록 해주시면 좋겠습니다.
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 (1)
domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt (1)
24-32
: JPA 기본 생성자 추가에 대한 검토TODO 주석에서 이 기본 생성자의 필요성에 의문을 제기하고 있습니다. JPA는 엔티티 클래스에 기본 생성자가 필요하지만, 이 코드가 임시 솔루션인지 확인이 필요합니다.
몇 가지 고려사항:
rawContentsId
의 기본값으로0L
을 사용하는 것이 semantically 올바른지 검토하세요.- 프로덕션 코드에서는 TODO 주석을 남겨두지 않는 것이 좋습니다.
PR 목표에서 언급된 "JPA 엔티티를 위한 기본 생성자의 임시 추가"와 일치하는 변경입니다.
) : BaseEntity() { - protected constructor() : this( // TODO: 기본 생성자 필요? + protected constructor() : this( id = null, rawContentsId = 0L, bodyTextsJson = "[]", coreTextsJson = "[]", completionIds = mutableListOf(), ) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt
(2 hunks)domain/generator/src/main/kotlin/com/few/generator/domain/RawContents.kt
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- domain/generator/src/main/kotlin/com/few/generator/domain/RawContents.kt
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: api-test
- GitHub Check: docs
- GitHub Check: lint
🔇 Additional comments (4)
domain/generator/src/main/kotlin/com/few/generator/domain/Gen.kt (3)
7-10
: DB 최적화를 위한 인덱스 추가에 대해 긍정적으로 평가합니다.
provisioning_contents_id
컬럼에 대한 인덱스를 추가한 것은 조회 성능 향상에 도움이 될 것입니다. PR 목표에서 언급된 대로 컨텐츠 조회 API의 성능을 개선하기 위한 인덱스 추가가 적절하게 구현되었습니다.
26-27
: typeCode 필드 추가가 적절하게 구현되었습니다.
typeCode
필드 추가는 GenType 열거형과 관련된 것으로 보이며, 다양한 생성 전략을 식별하기 위한 용도로 사용될 것으로 이해됩니다. 필수 필드로 설정되어 있어 데이터 무결성을 보장할 수 있습니다.
29-37
: 기본 생성자 관련 TODO 주석을 검토해 주세요.코드에 "TODO: 기본 생성자 필요?" 주석이 있습니다. JPA 엔티티에는 기본 생성자가 필요하지만, PR 설명에서 언급된 대로 이는 임시 추가로 보입니다. 프로젝트 완료 후 이 TODO를 처리할 계획이 있는지 확인하고, 필요하다면 주석을 제거하거나 영구적인 해결책으로 변경하는 것을 권장합니다.
또한, 모든 필드가 이미 기본값을 가지고 있다면 JPA가 일반적으로 기본 생성자 없이도 작동할 수 있습니다. 이 생성자가 정말 필요한지 검토해 보세요.
domain/generator/src/main/kotlin/com/few/generator/domain/ProvisioningContents.kt (1)
7-10
: 데이터베이스 성능 향상을 위한 인덱스 추가
raw_contents_id
컬럼에 유니크 인덱스를 추가한 것은 데이터베이스 성능 향상에 기여할 것입니다. 이는 PR 목표에 명시된 "데이터베이스 성능 향상을 위한 인덱스 추가"와 일치합니다.유니크 제약 조건은 동일한
raw_contents_id
를 가진 중복 레코드가 생성되는 것을 방지하는데, 이는 데이터 무결성 측면에서도 좋은 변경사항입니다.
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.
저희 이야기하던 요청시 어떤 Id로 받을지는 PM과 이야기해보았나요???
궁금한 것은 코멘트 해두었고 어프루브 합니다!
수고하셨습니다~~!
@Table( | ||
name = "gen", | ||
indexes = [Index(name = "idx_gen_1", columnList = "provisioning_contents_id", unique = false)], | ||
) |
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.
idx_gen_1 이라고 한 이유가 있나요?
idx_gen_1 만 보고는 어떤 인덱스인지 잘 모를 수도 있을 것 같아요
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.
인덱스 네이밍 룰을 정해보면 좋을거 같네요. 인덱스 명은 변경 가능하니 나중에 정해보죠
id = null, | ||
provisioningContentsId = 0L, | ||
completionIds = mutableListOf(), | ||
headline = "", | ||
summary = "", | ||
highlightTexts = "[]", | ||
typeCode = 0, | ||
) |
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.
보내 주신 링크의 것 적용이 안되는 것인가요?
@Table( | ||
name = "provisioning_contents", | ||
indexes = [Index(name = "idx_provisioning_contents_1", columnList = "raw_contents_id", unique = true)], | ||
) |
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.
요 인덱스 네이밍도요!
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.
유니크로 한 이유는 따로 있나요?
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.
raw content - prov content 는 1대1이니까 유니크 되어야하고
@Qualifier(GSON_BEAN_NAME) | ||
private val gson: Gson, |
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.
@qualifier(GSON_BEAN_NAME)
gson 빈이 하나만 있을 것 같긴 한데 위에 처럼 지정해줘야하나요?
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.
지정을 안하면 변수명인 gson 이라는 이름의 bean을 찾을텐데 빈명을 지금 GSON_BEAN_NAME로 정해둬서 저렇게 가져오고 있어요
우선 raw content id 기반으로만 조회되도록 추가하는걸로 결정 됐습니다. |
🎫 연관 이슈
resolved #613
💁♂️ PR 내용
🙏 작업
🙈 PR 참고 사항
📸 스크린샷
Response Example
🚩 추가된 SQL 운영계 실행계획
🤖 테스트 체크리스트
Summary by CodeRabbit
New Features
Refactor