-
Notifications
You must be signed in to change notification settings - Fork 0
✨ Feature: erd 수정 #6
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
Conversation
Walkthrough애플리케이션에 JPA 감사가 활성화되고 BaseEntity가 도입되었으며, ERD 변경에 따라 Index/Prompt 관련 엔티티(FewShot, Prompt, Index, Model, ChunkEmbedding, DataFileIndex 등), enums 및 FloatArray ↔ DB 변환기가 추가·리매핑되었습니다. DataFile/Tag 매핑과 관련 서비스·테스트 호출이 감사 기반으로 조정되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Service as 서비스/레포
participant JPA as Hibernate
participant Audit as AuditingEntityListener
participant DB as DB
Client->>Service: 엔티티 생성/저장 요청
Service->>JPA: save(entity)
JPA->>Audit: @CreatedDate/@LastModifiedDate 트리거
Audit-->>JPA: createdAt/updatedAt 설정
JPA->>DB: INSERT/UPDATE
DB-->>JPA: 응답
JPA-->>Service: 영속화된 엔티티 반환
Service-->>Client: 결과 응답
sequenceDiagram
participant Caller
participant Repo
participant Conv as FloatArrayConverter
participant JPA
participant DB
Caller->>Repo: ChunkEmbedding 생성(내용, embedding, index)
Repo->>JPA: persist(entity)
JPA->>Conv: convertToDatabaseColumn(embedding)
Conv-->>JPA: "[f1,f2,...]" 문자열 반환
JPA->>DB: INSERT chunk_embeddings (embedding 문자열 저장)
DB-->>JPA: OK
JPA-->>Repo: 엔티티 반환
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Assessment against linked issues
Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type 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: 17
🔭 Outside diff range comments (4)
src/main/kotlin/simplerag/ragback/domain/document/service/DataFileService.kt (1)
121-129: 태그 연결 시 save N회 호출 — 배치 저장으로 DB 라운드트립 감소현재는 태그마다
exists조회 + 개별save를 수행합니다. 최소한 저장만이라도saveAll로 묶어 호출 수를 줄이는 것을 권장합니다. (추가로, 진짜 최적화는 “기존 매핑 일괄 조회 후 차집합 계산”이지만, 이는 레포지토리 메서드 추가가 필요합니다.)- private fun attachTagsIfMissing(dataFile: DataFile, tags: List<Tag>) { - val fileId = dataFile.id ?: return - tags.forEach { tag -> - val tagId = tag.id ?: return@forEach - val exists = dataFileTagRepository.existsByDataFileIdAndTagId(fileId, tagId) - if (!exists) { - dataFileTagRepository.save(DataFileTag(tag = tag, dataFile = dataFile)) - } - } - } + private fun attachTagsIfMissing(dataFile: DataFile, tags: List<Tag>) { + val fileId = dataFile.id ?: return + val toCreate = tags.mapNotNull { tag -> + val tagId = tag.id ?: return@mapNotNull null + val exists = dataFileTagRepository.existsByDataFileIdAndTagId(fileId, tagId) + if (exists) null else DataFileTag(tag = tag, dataFile = dataFile) + } + if (toCreate.isNotEmpty()) { + dataFileTagRepository.saveAll(toCreate) + } + }추가 최적화(선택):
existsByDataFileIdAndTagIdN회를 대체하기 위해, 레포지토리에
findAllByDataFileIdAndTagIdIn(dataFileId: Long, tagIds: Collection<Long>): List<DataFileTag>같은 메서드를 추가해 기존 매핑을 한 번에 조회한 뒤 차집합만 저장하는 방식을 고려하세요.src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (2)
13-19: 연관 필드는 가능한 불변(val)로 두는 것을 권장DataFileTag는 조인 엔티티 성격이라 생성 후 참조 변경이 드뭅니다. 불변으로 두면 사이드 이펙트가 줄고 equals/hashCode 정의 시에도 안전합니다.
다음과 같이 수정을 제안합니다:
- var tag: Tag, + val tag: Tag, - var dataFile: DataFile, + val dataFile: DataFile,
7-10: 테이블 명명 규칙 통일 제안현재
data_file(단수),data_file_index(단수),data_file_tags(복수)가 혼재합니다. 팀 규칙(단수/복수)을 정해 통일하면 유지보수 시 혼란이 줄어듭니다. 스키마 확정 전이라면 지금 맞추는 것을 권장합니다.src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
1-32: JPA Auditing 설정 및 Kotlin JPA 플러그인 보완 필요확인 결과 다음과 같습니다:
- @EnableJpaAuditing
– 이미 src/main/kotlin/simplerag/ragback/RagBackApplication.kt(8행)에 적용되어 있습니다.- BaseEntity
–@EntityListeners(AuditingEntityListener::class)애노테이션이 누락되어 있어, 생성·수정 시각 자동 채워짐이 동작하지 않습니다.- Gradle 빌드스크립트
–build.gradle.kts(또는build.gradle)에 Kotlin JPA 플러그인(org.jetbrains.kotlin.plugin.jpa또는kotlin("plugin.jpa")), Kotlin Spring 플러그인(org.jetbrains.kotlin.plugin.spring또는kotlin("plugin.spring")), 그리고 no-arg 설정(noArg { annotation("javax.persistence.Entity") })이 적용되어 있지 않습니다.아래 항목들을 반영해 주세요:
- src/main/kotlin/simplerag/ragback/global/entity/BaseEntity.kt
@EntityListeners(AuditingEntityListener::class) abstract class BaseEntity { … }- 루트
build.gradle.kts(또는build.gradle)plugins { kotlin("plugin.spring") version "<버전>" kotlin("plugin.jpa") version "<버전>" // … } kotlin { jvmToolchain { /*…*/ } } noArg { annotation("javax.persistence.Entity") }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (15)
src/main/kotlin/simplerag/ragback/RagBackApplication.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt(2 hunks)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt(2 hunks)src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt(2 hunks)src/main/kotlin/simplerag/ragback/domain/document/service/DataFileService.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/DataFileIndex.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/enums/SimilarityMetric.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/FewShot.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt(1 hunks)src/main/kotlin/simplerag/ragback/global/entity/BaseEntity.kt(1 hunks)src/test/kotlin/simplerag/ragback/domain/document/service/DataFileServiceTest.kt(0 hunks)
💤 Files with no reviewable changes (1)
- src/test/kotlin/simplerag/ragback/domain/document/service/DataFileServiceTest.kt
🧰 Additional context used
🧬 Code Graph Analysis (5)
src/main/kotlin/simplerag/ragback/domain/index/entity/DataFileIndex.kt (1)
src/main/kotlin/simplerag/ragback/domain/document/repository/DataFileTagRepository.kt (1)
existsByDataFileIdAndTagId(6-8)
src/main/kotlin/simplerag/ragback/domain/document/service/DataFileService.kt (4)
src/test/kotlin/simplerag/ragback/domain/document/service/DataFileServiceTest.kt (1)
dataFileService(28-224)src/main/kotlin/simplerag/ragback/domain/document/dto/DataFileRequestDTO.kt (1)
message(13-20)src/main/kotlin/simplerag/ragback/domain/document/controller/DataFileController.kt (1)
dataFileService(17-44)src/main/kotlin/simplerag/ragback/global/util/FileConvertUtil.kt (1)
sha256(8-11)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (2)
src/main/kotlin/simplerag/ragback/domain/document/repository/DataFileTagRepository.kt (2)
existsByDataFileIdAndTagId(6-8)existsByDataFileIdAndTagId(7-7)src/main/kotlin/simplerag/ragback/domain/document/dto/DataFileRequestDTO.kt (1)
message(13-20)
src/main/kotlin/simplerag/ragback/RagBackApplication.kt (1)
src/test/kotlin/simplerag/ragback/RagBackApplicationTests.kt (1)
contextLoads(6-13)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (4)
src/test/kotlin/simplerag/ragback/domain/document/service/DataFileServiceTest.kt (2)
dataFileService(28-224)uploadRollbackCleansDBandS3(182-211)src/main/kotlin/simplerag/ragback/domain/document/dto/DataFileRequestDTO.kt (2)
message(13-20)min(7-11)src/main/kotlin/simplerag/ragback/domain/document/repository/DataFileTagRepository.kt (1)
existsByDataFileIdAndTagId(6-8)src/main/kotlin/simplerag/ragback/domain/document/controller/DataFileController.kt (1)
dataFileService(17-44)
🪛 detekt (1.23.8)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt
[warning] 3-5: The class or object PreSet is empty.
(detekt.empty-blocks.EmptyClassBlock)
🔇 Additional comments (7)
src/main/kotlin/simplerag/ragback/RagBackApplication.kt (1)
5-9: JPA Auditing 활성화 LGTM
@EnableJpaAuditing추가 적절합니다. BaseEntity의@CreatedDate/@LastModifiedDate가 있다면 의도대로 동작할 것입니다.src/main/kotlin/simplerag/ragback/domain/document/service/DataFileService.kt (1)
64-66: Auditing 적용에 맞춘 DataFile 생성자 변경 LGTM
createdAt/updatedAt을 서비스 단에서 제거하고BaseEntity로 이관한 방향성 좋습니다.DataIntegrityViolationException재매핑도 일관적입니다.src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
4-4: BaseEntity 도입 및 PK 컬럼명 명시 매핑, 잘 적용됐습니다공통 감사 필드 상속 + 명시적 PK 컬럼명으로 스키마 가독성과 마이그레이션 안전성이 좋아졌습니다.
Also applies to: 22-24
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
4-4: BaseEntity 적용 및 명시적 PK 매핑, 구성 적절합니다감사 필드 상속, sha256 유니크 제약으로 중복 업로드 방지, 전반적으로 스키마 정의가 명확합니다.
Also applies to: 29-32
src/main/kotlin/simplerag/ragback/domain/index/entity/DataFileIndex.kt (1)
11-18: 연관 매핑은 적절합니다LAZY 로딩, not-null FK 지정으로 무결성 확보가 됩니다. 유니크 제약만 추가되면 조인 테이블 용도로 충분해 보입니다.
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)
11-23: 스키마 정의 전반적으로 적절합니다
- name 길이 제한, enum STRING 매핑, system_prompt TEXT 지정 모두 실사용에 적합합니다.
- BaseEntity 상속으로 감사 필드 일관화된 점 좋습니다.
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (1)
11-16: 단일 컬럼 unique 제약 재검토 요청 (도메인 제약 확인 필요)name과 llm_model 모두 unique=true면, 동일 LLM 모델로는 Model 레코드를 하나만 허용합니다(복수 Index/Prompt 조합 불가). 의도된 제약인지 확인이 필요합니다. 조합 고유 제약이 의도라면 @table(uniqueConstraints=...)로 복합 unique 제약을 정의하는 것이 더 적절합니다.
예시:
@Table( name = "model", uniqueConstraints = [ UniqueConstraint(columnNames = ["name"]), // 또는 의도에 맞는 복합 제약 // UniqueConstraint(columnNames = ["llm_model", "indexes_id", "prompt_id"]) ] )
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt
Outdated
Show resolved
Hide resolved
| @Column(name = "tags_id") | ||
| val id: Long? = null, |
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.
💡 Verification agent
🧩 Analysis chain
id 컬럼명을 "tags_id"로 커스텀하면 기존 FK 매핑(특히 DataFileTag)이 깨질 수 있습니다
다른 엔티티가 기본 조인 규칙(tag_id -> 참조 테이블의 기본키 컬럼명 id)을 가정하고 있을 가능성이 큽니다. Tag의 PK 컬럼명을 tags_id로 바꾸면, @JoinColumn을 모두 맞춰 수정하지 않는 이상 런타임 매핑 오류(컬럼 미존재, FK 불일치)가 발생할 수 있습니다. 확실한 이유가 없다면 기본 컬럼명(id)을 유지하는 편이 안전합니다.
제안(기본 컬럼명으로 복구):
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "tags_id")
val id: Long? = null,검증 스크립트: DataFileTag 등에서의 조인 컬럼을 점검하세요.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "1) Tag 엔티티의 PK 컬럼 커스텀 여부 확인"
rg -n -C2 'class\s+Tag\b|@Column\s*\(\s*name\s*=\s*"tags?_id"' src/main/kotlin
echo
echo "2) DataFileTag 등 Tag를 참조하는 엔티티에서 JoinColumn 확인"
fd DataFileTag.kt -a | while read -r f; do
echo "---- $f ----"
rg -n -C4 '@ManyToOne|@JoinColumn|Tag\b|tags_id|tag_id' "$f" || true
done
echo
echo "3) 전역적으로 tags_id/tag_id 문자열 사용처 확인"
rg -n -C2 '\btags?_id\b' src/main/kotlinLength of output: 3796
Tag 엔티티 PK 컬럼명 커스텀으로 인한 매핑 불일치 확인 및 수정 필요
Tag.kt에서 PK 컬럼명을 tags_id로 변경했으나, DataFileTag.kt 등에서 여전히 @JoinColumn(name = "tag_id")를 사용하고 있어 런타임 매핑 오류가 발생할 수 있습니다.
기본 컬럼명(id)으로 복구하거나, 참조 측 @JoinColumn 이름을 모두 tags_id로 통일해야 합니다.
수정이 필요한 위치:
- src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt:17
- src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt:14
제안 1) Tag 엔티티를 기본 컬럼명으로 복구
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
-@Column(name = "tags_id")
val id: Long? = null,제안 2) 만약 tags_id를 유지하려면 DataFileTag.kt 수정
@ManyToOne(fetch = FetchType.LAZY)
-@JoinColumn(name = "tag_id", nullable = false)
+@JoinColumn(name = "tags_id", nullable = false)
var tag: Tag,🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt around lines
17-18 and
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt around
line 14, the Tag primary key column was renamed to "tags_id" causing a mismatch
with DataFileTag which still uses @JoinColumn(name = "tag_id"); fix by either
reverting Tag.kt to use the default column name "id" (restore @Column or remove
custom name) or, if you intend to keep "tags_id", update the @JoinColumn in
DataFileTag.kt to name = "tags_id" (and adjust any other references) so both
sides use the exact same column name.
| @Column(name = "embedding", nullable = false) | ||
| val embedding: FloatArray, | ||
|
|
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.
FloatArray의 JPA 매핑은 기본으로 지원되지 않습니다 — 변환기/전용 타입 필요
현 상태(@column만 지정)로는 Hibernate가 float[]를 적절히 직렬화/역직렬화하지 못할 가능성이 큽니다. 최소 변경으로 JSON TEXT 저장 + AttributeConverter를 권장합니다.
제안 변경:
- @Column(name = "embedding", nullable = false)
- val embedding: FloatArray,
+ @Column(name = "embedding", nullable = false, columnDefinition = "TEXT")
+ @Convert(converter = FloatArrayJsonConverter::class)
+ val embedding: FloatArray,아래 컨버터 클래스를 추가해 주세요(새 파일):
package simplerag.ragback.global.jpa.converter
import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter
@Converter(autoApply = false)
class FloatArrayJsonConverter : AttributeConverter<FloatArray, String> {
override fun convertToDatabaseColumn(attribute: FloatArray?): String =
attribute?.joinToString(prefix = "[", postfix = "]") { it.toString() } ?: "[]"
override fun convertToEntityAttribute(dbData: String?): FloatArray {
if (dbData.isNullOrBlank()) return floatArrayOf()
// 매우 단순한 파서 (필요시 Jackson 등으로 교체)
return dbData.trim().removePrefix("[").removeSuffix("]")
.split(",")
.mapNotNull { it.trim().toFloatOrNull() }
.toFloatArray()
}
}추후 PostgreSQL + pgvector 사용 계획이 있으면 columnDefinition = "vector(<dim>)" + 전용 타입 라이브러리(com.pgvector:pgvector) 도입을 검토하세요.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
around lines 13-15, the FloatArray field embedding cannot be mapped by
JPA/Hibernate as-is; add a JSON/text AttributeConverter and apply it on the
field. Create a new file
simplerag.ragback.global.jpa.converter.FloatArrayJsonConverter implementing
AttributeConverter<FloatArray,String> (convert FloatArray to/from a JSON-like
string as in the suggested snippet), then annotate the embedding property with
@Convert(converter = FloatArrayJsonConverter::class) and set the column to a
text-compatible type (e.g., @Column(name = "embedding", nullable = false,
columnDefinition = "text")). Ensure the converter class is non-autoApply or
adjust accordingly.
src/main/kotlin/simplerag/ragback/domain/prompt/entity/FewShot.kt
Outdated
Show resolved
Hide resolved
| @MappedSuperclass | ||
| @EntityListeners(AuditingEntityListener::class) | ||
| abstract class BaseEntity { |
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.
💡 Verification agent
🧩 Analysis chain
JPA Auditing 활성화 및 Kotlin JPA 플러그인 적용 여부 확인 필요
감사 필드 자동 세팅(@CreatedDate/@LastModifiedDate)과 Kotlin/JPA 호환성(엔티티 오픈/무인자 생성자)은 설정 의존적입니다. 실제로 적용되어 있는지 확인해 주세요.
아래 스크립트로 점검 가능합니다.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Check @EnableJpaAuditing =="
rg -nP '@EnableJpaAuditing' -C2 || { echo 'EnableJpaAuditing not found'; exit 1; }
echo
echo "== Check Kotlin JPA plugins (all-open/no-arg) =="
fd -HI --max-depth 2 'build.gradle*' | while read -r f; do
echo "--- $f ---"
rg -nP 'kotlin\("plugin\.jpa"\)|allOpen|noArg' "$f" || true
doneLength of output: 786
JPA 감사 활성화 확인 완료, Kotlin JPA 플러그인 설정 보완 필요
- src/main/kotlin/simplerag/ragback/RagBackApplication.kt:
@EnableJpaAuditing적용 확인 - build.gradle:
allOpen { … }블록만 발견,noArg { … }또는kotlin("plugin.jpa")/id "org.jetbrains.kotlin.plugin.jpa"설정 미발견
위 플러그인 누락 시 엔티티가 open되지 않거나 무인자 생성자가 자동으로 생성되지 않아 JPA 동작에 문제가 발생할 수 있습니다.
build.gradle에 아래와 같이 Kotlin JPA 플러그인 및 설정을 추가·검증해 주세요:
plugins {
id "org.jetbrains.kotlin.plugin.jpa" version "<버전>"
id "org.jetbrains.kotlin.plugin.allopen" version "<버전>"
id "org.jetbrains.kotlin.plugin.noarg" version "<버전>"
}
allOpen {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}
noArg {
annotation("javax.persistence.Entity")
annotation("javax.persistence.MappedSuperclass")
annotation("javax.persistence.Embeddable")
}🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/global/entity/BaseEntity.kt around lines 11
to 13, JPA auditing is enabled but the Gradle Kotlin JPA plugins/settings are
missing; update build.gradle (or build.gradle.kts) to apply the Kotlin JPA
plugin or kotlin("plugin.jpa") and enable the allOpen and noArg plugins (or
corresponding plugin ids), configure allOpen and noArg to target
javax.persistence.Entity, javax.persistence.MappedSuperclass and
javax.persistence.Embeddable, and ensure plugin versions match the Kotlin
version so entities are opened and a no-arg constructor is generated for JPA.
| @CreatedDate | ||
| @Column(name = "created_at", nullable = false, updatable = false) | ||
| lateinit var createdAt: LocalDateTime | ||
|
|
||
| @LastModifiedDate | ||
| @Column(name = "updated_at", nullable = false) | ||
| lateinit var updatedAt: LocalDateTime |
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
lateinit + 공개 setter는 안전하지 않습니다. null 허용 + protected set으로 전환 권고
엔티티 생성 전 접근 시 UninitializedPropertyAccessException 위험이 있고, 외부에서 임의로 수정 가능한 공개 setter는 감사를 무력화할 수 있습니다. JPA 감사 리스너가 채우도록 null 허용 + protected set 패턴이 더 안전합니다.
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
- lateinit var createdAt: LocalDateTime
+ var createdAt: LocalDateTime? = null
+ protected set
@LastModifiedDate
@Column(name = "updated_at", nullable = false)
- lateinit var updatedAt: LocalDateTime
+ var updatedAt: LocalDateTime? = null
+ protected set참고: 시간대 일관성이 중요하다면 LocalDateTime 대신 Instant/OffsetDateTime 사용도 고려해 주세요.
📝 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.
| @CreatedDate | |
| @Column(name = "created_at", nullable = false, updatable = false) | |
| lateinit var createdAt: LocalDateTime | |
| @LastModifiedDate | |
| @Column(name = "updated_at", nullable = false) | |
| lateinit var updatedAt: LocalDateTime | |
| @CreatedDate | |
| @Column(name = "created_at", nullable = false, updatable = false) | |
| var createdAt: LocalDateTime? = null | |
| protected set | |
| @LastModifiedDate | |
| @Column(name = "updated_at", nullable = false) | |
| var updatedAt: LocalDateTime? = null | |
| protected set |
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/global/entity/BaseEntity.kt around lines 14
to 20, the createdAt/updatedAt properties use lateinit and public setters which
can throw UninitializedPropertyAccessException if accessed before JPA populates
them and allow external mutation; change them to nullable types (e.g.
LocalDateTime?) and give them protected setters so the fields can be null until
the JPA auditing listener sets them and cannot be modified externally; update
annotations to remain (@CreatedDate/@LastModifiedDate) and consider switching to
Instant or OffsetDateTime for timezone safety if needed.
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.
우리 팀은 setter 안쓰기로 해서 괜찮을것 같아요
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.
@catturtle123 팀에서 setter를 사용하지 않는 정책이라면 충분히 합리적입니다. 그렇다면 현재 구현이 적절하겠네요. 팀의 코딩 스타일을 존중합니다!
/| /|
( :v: )
)._.(
o_(")(")
✏️ Learnings added
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/global/entity/BaseEntity.kt:14-20
Timestamp: 2025-08-17T07:34:46.937Z
Learning: The team working on simplerag.ragback project doesn't use setters as a coding standard, so public setter concerns for JPA audit fields in BaseEntity are not applicable.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
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: 9
♻️ Duplicate comments (8)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt (1)
3-5: 빈 enum 이슈 해소됨 — 기본 상수(NONE) 추가 승인이전 커멘트에서 지적된 빈 enum 문제를 NONE 상수로 해결했습니다. Prompt.preSet이 non-null 매핑이라면 DB 기본값/마이그레이션에서 기존 레코드에 대해 NONE으로 채워지는지 확인만 부탁드립니다.
기존 테이블/데이터에 대해 기본값 적용 여부를 점검하려면 아래를 실행해 주세요.
#!/bin/bash # pre_set 컬럼 정의 및 기본값/널 허용 여부, 마이그레이션 흔적 확인 rg -n -C2 -i 'pre_set|prompt|prompts' rg -n -C2 -i 'DEFAULT.*pre_set|ALTER TABLE .*prompts.* ADD COLUMN .*pre_set'src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
26-27: 컬럼명 명시(file_url) 반영 — 일관성 OKNamingStrategy 의존 제거 및 명시적 컬럼명 지정이 잘 반영되었습니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt (2)
15-29: @min 제약으로 파라미터 유효성 강화 — 👍chunkingSize/topK ≥ 1, overlapSize ≥ 0 제약이 반영되었습니다. 도메인 불변식에 부합합니다.
Bean Validation이 런타임에 활성화되어야 제약이 작동합니다. 의존성 확인 스크립트:
#!/bin/bash # Gradle/Maven에서 Bean Validation 활성화 여부 점검 rg -n -C2 'spring-boot-starter-validation|hibernate-validator|jakarta\.validation' build.gradle* pom.xml **/build.gradle.kts 2>/dev/null || true
23-25: Enum STRING 매핑 적용 — ORDINAL 위험 제거@Enumerated(EnumType.STRING) 지정으로 추후 enum 상수 변경 시에도 안전합니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/DataFileIndex.kt (2)
8-9: 조인 테이블명 규칙 통일 제안현재 테이블명이 "data_files_indexes"인데, 기존 조인 테이블("data_file_tags")과 단/복수 사용 규칙이 상이합니다. 팀 컨벤션에 맞게 통일하는 것을 권장합니다.
가능한 방향 예시(팀 규칙에 맞추어 선택):
-@Table(name = "data_files_indexes") +@Table(name = "data_file_indexes")
8-17: (data_files_id, indexes_id) 중복 방지를 위한 복합 유니크 제약 추가 권장동일 DataFile에 동일 Index가 중복 연결될 수 있습니다. 조인 엔티티 특성상 복합 유니크 제약을 DB 차원에서 강제하는 것을 권장합니다.
제안 diff:
-@Table(name = "data_files_indexes") +@Table( + name = "data_files_indexes", + uniqueConstraints = [ + UniqueConstraint( + name = "uk_data_files_indexes_data_file_and_index", + columnNames = ["data_files_id", "indexes_id"] + ) + ] +) class DataFileIndex(src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)
7-9: 프롬프트 식별을 위한 (pre_set, name) 복합 유니크 제약 권장동일 Preset 내 동일 이름 중복 생성을 방지하기 위해 복합 유니크 제약 추가를 권장합니다.
제안 diff:
-@Table(name = "prompts") +@Table( + name = "prompts", + uniqueConstraints = [UniqueConstraint(columnNames = ["pre_set", "name"])] +)src/main/kotlin/simplerag/ragback/domain/prompt/entity/FewShot.kt (1)
6-8: 프롬프트별 question 중복 방지용 복합 유니크 제약 권장(prmopts_id, question)로 복합 유니크 제약을 추가해 데이터 무결성을 강화하세요.
제안 diff:
-@Table(name = "few_shots") +@Table( + name = "few_shots", + uniqueConstraints = [UniqueConstraint(columnNames = ["prompts_id", "question"])] +)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (11)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt(2 hunks)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/DataFileIndex.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/FewShot.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt(1 hunks)src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.kt(1 hunks)src/main/resources/application-local.yml(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-17T07:14:26.887Z
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt:6-22
Timestamp: 2025-08-17T07:14:26.887Z
Learning: ChunkEmbedding 엔티티에서 embedding 필드는 벡터 임베딩 저장용이고, content 필드는 원본 파일/텍스트 청크 저장용으로 설계됨 (catturtle123 프로젝트)
Applied to files:
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
🧬 Code Graph Analysis (5)
src/main/kotlin/simplerag/ragback/domain/index/entity/DataFileIndex.kt (2)
src/main/kotlin/simplerag/ragback/domain/document/repository/DataFileTagRepository.kt (1)
existsByDataFileIdAndTagId(6-8)src/main/kotlin/simplerag/ragback/domain/document/service/DataFileService.kt (1)
tag(124-130)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (1)
src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (4)
src/main/kotlin/simplerag/ragback/domain/document/service/DataFileService.kt (2)
tag(124-130)attachTagsIfMissing(122-131)src/main/kotlin/simplerag/ragback/domain/document/repository/DataFileTagRepository.kt (2)
existsByDataFileIdAndTagId(6-8)existsByDataFileIdAndTagId(7-7)src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)src/main/kotlin/simplerag/ragback/domain/document/dto/DataFileRequestDTO.kt (1)
message(13-20)
src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt (1)
src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)
src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)
🔇 Additional comments (7)
src/main/resources/application-local.yml (1)
7-11: pgvector 확장 설치 여부 확인 필요
로컬에서psql명령을 찾을 수 없어 vector 확장 설치 여부를 자동으로 확인하지 못했습니다. 다음 중 하나로 재검증해 주시고 결과를 알려주세요:
- 로컬에 psql 클라이언트를 설치한 뒤:
psql "$DB_URL_LOCAL" -c "SELECT installed_version FROM pg_available_extensions WHERE name='vector';"- Docker 기반 로컬 DB라면:
docker exec -i <postgres_container> psql -U <user> -d <database> \ -c "SELECT installed_version FROM pg_available_extensions WHERE name='vector';"확장이 미설치 상태라면, 제안드린
src/main/resources/schema-local.sql파일에CREATE EXTENSION IF NOT EXISTS vector;를 추가하고 Spring Boot
sql.init설정을 적용해 주세요.src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
9-31: DDL 마이그레이션 스크립트 확인/추가 필요레거시 식별자(
data_file,data_file_id,fileUrl)를 신규 식별자(data_files,data_files_id,file_url)로 변경하는 테이블·컬럼명 리네임 마이그레이션이 코드베이스 내에서 확인되지 않았습니다.
런타임에 스키마 불일치로 인한 에러가 발생하지 않도록 아래 사항을 점검해 주세요:
- 마이그레이션 디렉터리 위치 및 파일(
*.sql,*.xml,*.yml)에 리네임 스크립트 존재 여부
(예: src/main/resources/db/migration/V2__rename_data_file.sql)- ALTER TABLE … RENAME TO data_files
- ALTER TABLE … RENAME COLUMN old_name TO file_url
- 외래 키(FK) 참조 업데이트 반영 여부
위 스크립트가 외부 관리(예: Flyway, Liquibase)로 분리되어 있다면 해당 위치를 검토하거나, 없다면 새로 추가해 주세요.
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
8-10: 복합 유니크 제약으로 중복 태깅 방지 — 리포지토리 쿼리와 합치됨(data_files_id, tags_id) 유니크 제약이 existsByDataFileIdAndTagId와 일관되며, 중복 관계 생성을 안전하게 막습니다. 매핑과 네이밍도 명확합니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt (1)
18-20: FK not-null, LAZY 매핑 적절함임베딩은 특정 Index에 종속되므로 FK not-null 설정과 LAZY 로딩 선택이 합리적입니다. 이 부분은 그대로 가도 좋습니다.
src/main/kotlin/simplerag/ragback/domain/prompt/entity/FewShot.kt (1)
13-19: @lob 사용 적절함answer, evidence에 @lob을 적용해 장문 데이터에 대비한 매핑이 잘 되어 있습니다.
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (2)
12-16: name, llm_model 유니크 제약 도메인 적합성 검증 필요두 컬럼 모두 unique=true인데, 동일 llm_model을 서로 다른 Index/Prompt 조합에서 재사용하지 못해도 되는지 확인이 필요합니다. 재사용 허용이 도메인상 맞다면, (index, prompt, llm_model) 또는 (name)만 유니크로 재정의하는 것이 맞을 수 있습니다.
18-24: 관계 매핑(LAZY + not-null) 적절함Index/Prompt에 대한 LAZY, not-null 설정이 도메인 의도를 잘 반영합니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.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: 5
♻️ Duplicate comments (4)
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt (2)
11-13: 대용량 LOB 컨텐츠는 지연 로딩으로 전환 권장content는 원본 텍스트 청크(프로젝트 러닝 반영)로 길어질 수 있습니다. 기본 fetch 전략에서 즉시 로딩될 여지가 있으므로 명시적으로 LAZY로 전환해 N+1/불필요 메모리 사용을 줄이세요.
- @Column(name = "content", nullable = false) - @Lob + @Column(name = "content", nullable = false) + @Lob + @Basic(fetch = FetchType.LAZY) val content: String,
7-9: FK 조회 성능 향상을 위한 보조 인덱스 추가 (선택사항)
indexes_id조인 빈도가 높다면 보조 인덱스를 권장합니다. 도메인 클래스명Index와jakarta.persistence.Index충돌을 피하기 위해 alias 사용을 제안합니다.-@Table(name = "chunk_embeddings") +@Table( + name = "chunk_embeddings", + indexes = [ + JpaIndex(name = "idx_chunk_embeddings_indexes_id", columnList = "indexes_id") + ] +) class ChunkEmbedding(파일 상단 import 추가:
import jakarta.persistence.Index as JpaIndexsrc/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)
7-9: 프리셋 내 이름 중복 방지를 위한 (pre_set, name) 복합 유니크 제약 추가 권장동일 PreSet에서 같은 이름의 Prompt 중복 생성을 방지하려면 복합 유니크가 유용합니다.
-@Table(name = "prompts") +@Table( + name = "prompts", + uniqueConstraints = [UniqueConstraint(columnNames = ["pre_set", "name"])] +) class Prompt(src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (1)
8-10: FK 조인 성능을 위한 보조 인덱스 추가 (선택사항)
models.indexes_id,models.prompts_id에 인덱스를 두면 조인/필터 성능이 개선됩니다. 이름 충돌을 피하려 alias import를 사용하세요.-@Table(name = "models") +@Table( + name = "models", + indexes = [ + JpaIndex(name = "idx_models_indexes_id", columnList = "indexes_id"), + JpaIndex(name = "idx_models_prompts_id", columnList = "prompts_id") + ] +) class Model(파일 상단 import 추가:
import jakarta.persistence.Index as JpaIndex
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt(1 hunks)src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.kt(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-17T07:14:26.887Z
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt:6-22
Timestamp: 2025-08-17T07:14:26.887Z
Learning: ChunkEmbedding 엔티티에서 embedding 필드는 벡터 임베딩 저장용이고, content 필드는 원본 파일/텍스트 청크 저장용으로 설계됨 (catturtle123 프로젝트)
Applied to files:
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
🧬 Code Graph Analysis (3)
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt (3)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
name(5-22)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
name(6-36)src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (2)
src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
name(5-22)
src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt (3)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
name(5-22)src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
name(6-36)
🔇 Additional comments (4)
src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.kt (1)
14-24: 역직렬화 로직 LGTM공백 처리와 파싱 오류 메시지 래핑이 적절합니다. 운영 시 장애 분석에 도움이 되겠습니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt (1)
15-17: pgvector 스키마 및 컨버터 포맷 검증 필요현재 Converter(
FloatArrayToPgVectorStringConverter)는"[a,b,c,…]"형태의 문자열을 반환하며, 코드베이스 내에서는 별도 pgvector 전용 마이그레이션 스크립트나 툴(liquibase/flyway 등)이 확인되지 않습니다. 아래 사항을 운영 환경 기준으로 직접 점검해 주세요:
- 운영 DB의
chunk_embeddings.embedding컬럼이vector(<dim>)타입으로 생성되어 있는지 확인- JDBC 드라이버 및 pgvector 확장 모듈이 Converter가 반환하는
"[a,b,c,…]"문자열을 입력값으로 허용하는지 테스트- 벡터 차원(
dim) 관리 현황 및 마이그레이션 전략(툴 사용 여부, 수동 관리 등) 점검src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)
18-20: @lob 적용 적절합니다장문 system prompt 특성상 @lob 매핑이 이식성과 의도를 잘 반영합니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt (1)
23-25: Enum을 STRING으로 고정한 점 좋습니다ORDINAL 기본값 리스크를 제거해 스키마 변경에도 안전합니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
Outdated
Show resolved
Hide resolved
| @Id @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "indexes_id") | ||
| val id: Long? = null, |
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.
🧹 Nitpick (assertive)
id 컬럼 명시는 선택 사항 — 컨벤션 일관성 검토
다른 엔티티(Tag/DataFile)는 기본 컬럼명(id)을 사용합니다. 여기서만 indexes_id를 유지할 특별한 이유가 없다면 기본값으로 단순화(또는 프로젝트 전반 동일 네이밍 채택)해 컨벤션 일관성을 맞추는 것을 고려해 주세요.
예시(선택):
- @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "indexes_id")
- val id: Long? = null,
+ @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+ val id: Long? = null,📝 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.
| @Id @GeneratedValue(strategy = GenerationType.IDENTITY) | |
| @Column(name = "indexes_id") | |
| val id: Long? = null, | |
| @Id @GeneratedValue(strategy = GenerationType.IDENTITY) | |
| val id: Long? = null, |
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt around lines
37 to 39, the explicit @Column(name = "indexes_id") breaks naming consistency
with other entities using the default "id"; remove the explicit name (or rename
other entities to the same convention) so the field uses the default column name
`id`, and if your database schema must keep the existing column, update the
mapping consistently or add a migration to rename the column to `id` to maintain
project-wide naming consistency.
| package simplerag.ragback.global.util | ||
|
|
||
| import jakarta.persistence.AttributeConverter | ||
| import jakarta.persistence.Converter | ||
|
|
||
| @Converter(autoApply = false) | ||
| class FloatArrayToPgVectorStringConverter : AttributeConverter<FloatArray, String> { |
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.
🧹 Nitpick (assertive)
파일명-클래스명 불일치 (정리 권장)
클래스명이 FloatArrayToPgVectorStringConverter인데 파일명이 FloatJsonConverter.kt입니다. 탐색성과 컨벤션(파일=공개 클래스명 일치)을 위해 파일명을 FloatArrayToPgVectorStringConverter.kt로 변경하는 것을 권장합니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.kt around
lines 1 to 7, the public class name FloatArrayToPgVectorStringConverter does not
match the file name; rename the file to FloatArrayToPgVectorStringConverter.kt
to follow Kotlin/Java convention. Use a file move (git mv) or rename in your IDE
to preserve history, and update any references/imports if your build tooling or
other code explicitly referenced the old filename.
| override fun convertToDatabaseColumn(attribute: FloatArray?): String { | ||
| requireNotNull(attribute) { "Embedding (FloatArray) must not be null" } | ||
| require(attribute.isNotEmpty()) { "Embedding must not be empty; expected fixed dimension (e.g., 1536)" } | ||
| return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() } | ||
| } |
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.
🧹 Nitpick (assertive)
pgvector 입력에 NaN/Infinity 값 유입 차단 권장
DB vector 타입은 NaN/Infinity 처리에 취약할 수 있습니다. 직렬화 전에 유한값만 허용하도록 방어 코드를 추가해 주세요.
아래처럼 보강을 제안합니다:
override fun convertToDatabaseColumn(attribute: FloatArray?): String {
requireNotNull(attribute) { "Embedding (FloatArray) must not be null" }
require(attribute.isNotEmpty()) { "Embedding must not be empty; expected fixed dimension (e.g., 1536)" }
+ require(attribute.all { !it.isNaN() && !it.isInfinite() }) {
+ "Embedding must not contain NaN/Infinity"
+ }
return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() }
}📝 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.
| override fun convertToDatabaseColumn(attribute: FloatArray?): String { | |
| requireNotNull(attribute) { "Embedding (FloatArray) must not be null" } | |
| require(attribute.isNotEmpty()) { "Embedding must not be empty; expected fixed dimension (e.g., 1536)" } | |
| return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() } | |
| } | |
| override fun convertToDatabaseColumn(attribute: FloatArray?): String { | |
| requireNotNull(attribute) { "Embedding (FloatArray) must not be null" } | |
| require(attribute.isNotEmpty()) { "Embedding must not be empty; expected fixed dimension (e.g., 1536)" } | |
| require(attribute.all { !it.isNaN() && !it.isInfinite() }) { | |
| "Embedding must not contain NaN/Infinity" | |
| } | |
| return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() } | |
| } |
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/global/util/FloatJsonConverter.kt around
lines 8 to 12, the converter currently does not guard against NaN/Infinity
values which can break DB vector types; add a validation after the existing
null/empty checks to require that every Float in the array is finite (use
Float.isFinite()) and throw a clear error if any element is NaN or infinite,
keeping the rest of the serialization logic unchanged.
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: 9
♻️ Duplicate comments (2)
src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt (1)
39-41: ID 컬럼 명명 컨벤션 재확인(선택 사항)다른 엔티티가 기본
id를 쓰는 반면 여기만indexes_id입니다. 스키마 호환성이 문제 없다면 컨벤션 통일을 검토해 주세요. 필요 시 마이그레이션 스크립트 제안 가능합니다.src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (1)
18-24: 관계 카디널리티 확인: @OnetoOne 가 맞나요?여러 모델이 동일 Index/Prompt를 참조하는 시나리오가 일반적입니다. 진짜 1:1 의도라면 현 매핑(JoinColumn unique=true)이 맞고, 1:N 허용이 목적이라면 @manytoone이 적합합니다.
옵션 A) 1:1 유지(현 상태 OK)
옵션 B) 다대일로 변경:- @OneToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "indexes_id", nullable = false, unique = true) val index: Index, - @OneToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "prompts_id", nullable = false, unique = true) val prompt: Prompt,※ B를 선택하면 JoinColumn의
unique = true도 제거해야 합니다. 의도 공유해 주시면 후속 변경 전체 패치 드리겠습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt(1 hunks)src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-17T07:14:26.887Z
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt:6-22
Timestamp: 2025-08-17T07:14:26.887Z
Learning: ChunkEmbedding 엔티티에서 embedding 필드는 벡터 임베딩 저장용이고, content 필드는 원본 파일/텍스트 청크 저장용으로 설계됨 (catturtle123 프로젝트)
Applied to files:
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
🧬 Code Graph Analysis (2)
src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt (2)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
name(5-22)src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (3)
src/main/kotlin/simplerag/ragback/domain/document/entity/DataFileTag.kt (1)
name(5-22)src/main/kotlin/simplerag/ragback/domain/document/entity/Tag.kt (1)
name(5-17)src/main/kotlin/simplerag/ragback/domain/document/entity/DataFile.kt (1)
name(6-36)
🔇 Additional comments (1)
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt (1)
3-40: 모델-차원(enum) 캡슐화 설계 좋습니다엔티티 쪽에서
index.embeddingModel.dim으로 차원 일관성을 보장하는 구조가 명확합니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
Outdated
Show resolved
Hide resolved
| @Column(name = "chunking_size", nullable = false) | ||
| @Min(1) | ||
| val chunkingSize: Int, | ||
|
|
||
| @Column(name = "overlap_size", nullable = false) | ||
| @Min(0) | ||
| val overlapSize: Int, |
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.
🧹 Nitpick (assertive)
교차 필드 제약 추가: overlapSize ≤ chunkingSize
일반적으로 overlap은 청킹 크기를 초과할 수 없습니다. Bean Validation으로 빠르게 실패시키고, 스키마에도 CHECK 제약을 고려하세요.
예시(클래스 내부에 추가):
import jakarta.validation.constraints.AssertTrue
@get:AssertTrue(message = "overlapSize must be <= chunkingSize")
val isValidOverlap: Boolean
get() = overlapSize <= chunkingSizeAlso applies to: 28-31
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt around lines
16-22 (and also apply the same change around lines 28-31), add a Bean Validation
cross-field check to ensure overlapSize ≤ chunkingSize by introducing a
read-only boolean property annotated with @get:AssertTrue that returns
overlapSize <= chunkingSize; also update the DB schema to include a CHECK
constraint (e.g., CHECK (overlap_size <= chunking_size)) so the constraint is
enforced at the database level as well.
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.
@catturtle123 네, 맞습니다! 서비스 레이어에서 검증하는 것도 충분히 좋은 접근법입니다. 서비스 레이어에서 검증하면 더 구체적인 에러 메시지를 제공할 수 있고, 비즈니스 로직과 함께 관리하기도 편하죠.
엔티티 레벨 검증은 선택사항이니까 나중에 필요하다고 느끼시면 그때 추가하셔도 됩니다.
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.
그럼 나중에 제가 chunking embedding 저장 관련 PR 올렸을때 언질해주세요
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.
@catturtle123 네, 알겠습니다! chunking embedding 저장 관련 PR에서 overlapSize ≤ chunkingSize 검증 로직을 서비스 레이어에 추가하는 것을 잊지 않고 언급해드리겠습니다.
✏️ Learnings added
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/index/entity/Index.kt:16-22
Timestamp: 2025-08-17T13:12:02.200Z
Learning: catturtle123이 Index 엔티티의 overlapSize ≤ chunkingSize 검증을 엔티티 레벨이 아닌 서비스 레이어에서 구현하기로 결정했으며, chunking embedding 저장 관련 PR에서 이 검증 로직을 추가할 예정이므로 해당 PR에서 언급해야 함 (Simple-RAG/BACK 프로젝트)
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt:6-22
Timestamp: 2025-08-17T07:14:26.887Z
Learning: ChunkEmbedding 엔티티에서 embedding 필드는 벡터 임베딩 저장용이고, content 필드는 원본 파일/텍스트 청크 저장용으로 설계됨 (catturtle123 프로젝트)
src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt
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: 16
♻️ Duplicate comments (5)
src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt (1)
21-30: 이전 리뷰 반영 확인 — DB→엔티티 역직렬화시 NaN/Infinity 차단 완료과거에 제기된 NaN/Infinity 검증 누락 이슈가
.also { require(arr.all { it.isFinite() }) }로 정확히 해결되었습니다. 저장/로드 양방향에서 유한성 보장이 생겼습니다. 굿.src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt (4)
12-15: 벤더 종속 TEXT 제거 후 @lob로 이식성 강화 — 잘 반영됨
content를 @lob으로 매핑하여 DB 이식성/대용량 텍스트에 적합하게 처리했습니다. 과거 코멘트가 잘 반영되었습니다.
16-19: 내부 상태 보호 및 컨버터 적용 — 방향성 적절
_embedding을 private으로 두고,- 컨버터를 통해 안전하게 직렬화하는 구조는 바람직합니다.
23-26: FK not-null 적용 확인 — 무결성 강화 OK
@JoinColumn(nullable = false)로 FK 무결성을 명시했습니다. 의도에 맞습니다.
32-34: 파생 getter의 영속성 제외 처리 적절
@get:Transient로 파생 프로퍼티 매핑 충돌을 방지했습니다. 좋습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt(1 hunks)src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt(1 hunks)src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-17T07:14:26.887Z
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt:6-22
Timestamp: 2025-08-17T07:14:26.887Z
Learning: ChunkEmbedding 엔티티에서 embedding 필드는 벡터 임베딩 저장용이고, content 필드는 원본 파일/텍스트 청크 저장용으로 설계됨 (catturtle123 프로젝트)
Applied to files:
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
🔇 Additional comments (3)
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt (1)
3-6: 설계 방향 적절 — dim + modelId를 enum에 포함한 구조 좋습니다실행 시 API 라우팅과 차원 검증을 모두 enum에서 일원화할 수 있어 유지보수성/가독성이 좋아졌습니다.
src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt (1)
8-15: 정책 일치 여부 확인: 저장 금지(빈 배열) vs 로드 시 빈 배열 반환
- 저장 시: 빈 배열 금지(requireNotNull + isNotEmpty)
- 로드 시: null/공백/빈 본문 → 빈 배열 반환
의도된 정책인지 확인 필요합니다. DB가 pgvector(vector(N))라면 로드에서 빈 배열이 나올 케이스가 거의 없지만, TEXT를 사용하는 경우엔 불일치가 생길 수 있습니다.
원하시면 로드에서 빈 배열 대신 예외를 던지도록 통일하는 패치도 제공하겠습니다.
src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt (1)
16-18: 마이그레이션에서chunk_embeddings.embedding컬럼 정의 확인 필요실제 DB 스키마에
chunk_embeddings테이블의embedding컬럼이 아래 중 하나로 정확히 설정되었는지 확인해주세요:
vector(<차원>)타입 (pgvector 사용 시)- 충분한 길이의
TEXT또는VARCHAR타입 (예: 1536차원 문자열 저장용)현재 리포지토리 내 마이그레이션/DDL(예: Flyway/Liquibase/Kotlin 스크립트)에서 해당 정의를 찾을 수 없습니다. 마이그레이션 파일이 누락되었거나 컬럼 타입 지정이 빠지지 않았는지 검토 부탁드립니다.
| @Table(name = "chunk_embeddings") | ||
| class ChunkEmbedding( |
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.
🧹 Nitpick (assertive)
쿼리 성능 대비: 인덱스 전략 제안
- FK 인덱스:
chunk_embeddings(indexes_id)에 보조 인덱스를 생성해 Index 단위 조회/삭제 성능을 보장하세요. - pgvector 사용 시:
embedding컬럼에 IVFFlat/HNSW 인덱스 생성(적절한 lists/efConstruction 튜닝).
원하시면 Flyway/Liquibase용 마이그레이션 스니펫을 제공하겠습니다.
| fun updateEmbedding(newVec: FloatArray) { | ||
| require(newVec.size == embeddingDim) { | ||
| "Embedding dimension mismatch: expected=$embeddingDim, got=${newVec.size}" | ||
| } | ||
| _embedding = newVec.copyOf() | ||
| } | ||
|
|
||
| } No newline at end of 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.
🛠️ Refactor suggestion
초기 생성 시 차원/유한성 불변식 보강: 영속화 훅 추가 권장
주석대로 서비스단 검증을 하더라도, 엔티티 차원에서 한 번 더 방어하면 데이터 오염을 원천 차단할 수 있습니다. LAZY FK 접근 없이 embeddingDim만 사용하면 안전합니다.
적용 diff:
fun updateEmbedding(newVec: FloatArray) {
require(newVec.size == embeddingDim) {
"Embedding dimension mismatch: expected=$embeddingDim, got=${newVec.size}"
}
_embedding = newVec.copyOf()
}
+ @PrePersist
+ @PreUpdate
+ private fun verifyBeforeSave() {
+ require(_embedding.size == embeddingDim) {
+ "Embedding dimension mismatch: expected=$embeddingDim, got=${_embedding.size}"
+ }
+ require(_embedding.isNotEmpty()) { "Embedding must not be empty" }
+ require(_embedding.all { it.isFinite() }) {
+ "Embedding must not contain NaN/Infinity"
+ }
+ }
}🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/ChunkEmbedding.kt
around lines 35 to 42, add defensive validation on the entity itself (not just
service-level) by introducing a persistence hook method (e.g., annotated
@PrePersist and @PreUpdate) that verifies the _embedding array length equals
embeddingDim and that every element is finite (no NaN or infinite values); throw
an IllegalArgumentException if checks fail; keep using newVec.copyOf() on
updates and avoid relying on lazy FK access — read embeddingDim directly so the
entity enforces its own invariants before being persisted or updated.
| enum class EmbeddingModel( | ||
| val dim: Int, | ||
| val modelId: String | ||
| ) { |
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.
🧹 Nitpick (assertive)
toString 오버라이드로 로깅/표시 안정성 향상 (선택)
운영 로그/에러 메시지 가독성을 위해 override fun toString() = modelId를 고려해 보세요. 외부 노출 시에도 공급자 식별자가 직접 보여 가독성이 좋아집니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 3 to 6, add an override of toString that returns the modelId to
improve logging/readability; implement override fun toString() = modelId inside
the enum so when instances are logged or displayed the provider identifier is
shown directly.
🧹 Nitpick (assertive)
Provider 메타데이터 추가를 고려해 주세요 (OPENAI/HF/MISTRAL 등)
API 라우팅, 레이트리밋/자격증명 분리, 로깅 필터링을 위해 provider 필드를 enum에 추가하는 것을 권장합니다. 예: enum class EmbeddingProvider { OPENAI, HUGGING_FACE, MISTRAL, LOCAL } 후 val provider: EmbeddingProvider를 각 상수에 채워두면 클라이언트 선택이 단순해집니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 3 to 6, the enum lacks provider metadata which makes routing,
rate-limiting and credential handling harder; add a new enum EmbeddingProvider
(e.g., OPENAI, HUGGING_FACE, MISTRAL, LOCAL) and add a provider:
EmbeddingProvider property to EmbeddingModel, then update each enum constant to
supply the appropriate provider value and adjust usages/constructors throughout
the codebase to accept the new parameter.
🧹 Nitpick (assertive)
JPA 저장 전략 재검토 — Enum 이름 변경 리스크 완화
AI 요약에 따르면 Index 엔티티에서 @Enumerated(EnumType.STRING)으로 저장 중입니다. enum 상수명을 바꾸면(이번 distiluse 케이스처럼) 기존 데이터가 깨집니다. Enum 대신 modelId를 영속화하도록 AttributeConverter를 도입하는 방식을 권장합니다.
다음 예시는 Converter 스켈레톤입니다:
import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter
import simplerag.ragback.domain.index.entity.enums.EmbeddingModel
@Converter(autoApply = false)
class EmbeddingModelConverter : AttributeConverter<EmbeddingModel, String> {
override fun convertToDatabaseColumn(attribute: EmbeddingModel?): String? =
attribute?.modelId
override fun convertToEntityAttribute(dbData: String?): EmbeddingModel? =
dbData?.let { EmbeddingModel.findByModelId(it) }
}엔티티 필드에 @Convert(converter = EmbeddingModelConverter::class)를 부여하면 enum 상수명 변경에도 DB 값은 안정적으로 유지됩니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 3 to 6, the enum is currently persisted via its constant name which
breaks when you rename constants; replace this by implementing a JPA
AttributeConverter that persists the modelId string instead, add a companion
lookup method on EmbeddingModel (e.g., findByModelId) to map DB values back to
enum instances, update the Index entity field to use @Convert(converter =
EmbeddingModelConverter::class) (and remove/stop using
@Enumerated(EnumType.STRING) for that field), and ensure the converter handles
nulls safely so existing DB values remain valid when enum constant names change.
| TEXT_EMBEDDING_ADA_002(1536, "text-embedding-ada-002"), | ||
| TEXT_EMBEDDING_3_SMALL(1536, "text-embedding-3-small"), | ||
| TEXT_EMBEDDING_3_LARGE(3072, "text-embedding-3-large"), |
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.
🧹 Nitpick (assertive)
OpenAI Ada-002는 폐기 권장 — @deprecated 부여 제안
운영 상의 안전(신규 모델 권장)과 호출 혼선을 줄이기 위해 명시적 비권장 표시가 유용합니다. 대체 모델로 TE3 Small/Large를 안내하세요.
- TEXT_EMBEDDING_ADA_002(1536, "text-embedding-ada-002"),
+ @Deprecated(
+ message = "OpenAI가 text-embedding-3 계열로 대체했습니다. TEXT_EMBEDDING_3_SMALL 또는 TEXT_EMBEDDING_3_LARGE 사용을 권장합니다.",
+ replaceWith = ReplaceWith("EmbeddingModel.TEXT_EMBEDDING_3_SMALL")
+ )
+ TEXT_EMBEDDING_ADA_002(1536, "text-embedding-ada-002"),| ALL_MINILM_L6_V2(384, "sentence-transformers/all-MiniLM-L6-v2"), | ||
| ALL_MP_NET_BASE_V2(768, "sentence-transformers/all-mpnet-base-v2"), | ||
| MULTI_QA_MP_NET_BASE_DOT_V1(768, "sentence-transformers/multi-qa-mpnet-base-dot-v1"), |
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.
🧹 Nitpick (assertive)
상수명 일관성(Nit): MPNET 철자 통일 고려
ALL_MP_NET_BASE_V2, MULTI_QA_MP_NET_BASE_DOT_V1는 보통 “MPNET”로 붙여 표기합니다. 신규 파일이고 아직 DB에 enum 문자열이 저장되지 않았다면 ALL_MPNET_BASE_V2, MULTI_QA_MPNET_BASE_DOT_V1로의 리네이밍을 검토해 주세요. 만약 이미 JPA로 문자열이 저장된다면 마이그레이션이 필요합니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 13 to 15, the enum constant names use inconsistent spelling
“MP_NET” vs common “MPNET”; rename ALL_MP_NET_BASE_V2 to ALL_MPNET_BASE_V2 and
MULTI_QA_MP_NET_BASE_DOT_V1 to MULTI_QA_MPNET_BASE_DOT_V1, then update all
references/usages (imports, switch/when branches, tests, serializers)
accordingly; if enum names are persisted as strings via JPA/DB, do not rename
without adding a migration that maps old stored values to the new names (or keep
@EnumValue/explicit persisted strings) and verify serialization/deserialization
and API contract after the change.
| companion object { | ||
| fun findByModelId(modelId: String): EmbeddingModel? { | ||
| return entries.find { it.modelId == modelId } | ||
| } | ||
|
|
||
| fun getAllModelIds(): List<String> { | ||
| return entries.map { it.modelId } | ||
| } | ||
| } |
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.
🧹 Nitpick (assertive)
간단한 단위 테스트 추가 제안
- 모든 상수에 대해
findByModelId(modelId) == constant보장 getAllModelIds()가 중복 없이 전체를 포괄하고 선언 순서를 유지
원하시면 테스트 템플릿 생성해 드리겠습니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 44 to 52, add unit tests that (1) iterate every enum entry and
assert findByModelId(entry.modelId) == entry to guarantee the lookup maps to the
exact constant, and (2) assert getAllModelIds() returns a list equal to
entries.map { it.modelId } (no duplicates, covers all entries and preserves
declaration order); implement these tests using the project test framework
(e.g., JUnit + Kotest/assertJ) and include clear failure messages for easier
debugging.
| companion object { | ||
| fun findByModelId(modelId: String): EmbeddingModel? { | ||
| return entries.find { it.modelId == modelId } | ||
| } | ||
|
|
||
| fun getAllModelIds(): List<String> { | ||
| return entries.map { it.modelId } | ||
| } |
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
O(n) 선형 탐색 제거 및 Kotlin 버전 호환성 보강 (entries 의존 제거)
entries.find { ... }는 빈번 호출 시 비용이 누적되고, Kotlin < 1.9 환경에선 entries 미지원 이슈가 발생합니다. 정적 맵으로 O(1) 조회 + values() 기반으로 호환성 확보를 권장합니다. 또한 모델 ID 목록은 선언 순서를 유지하도록 values()를 사용하세요.
- companion object {
- fun findByModelId(modelId: String): EmbeddingModel? {
- return entries.find { it.modelId == modelId }
- }
-
- fun getAllModelIds(): List<String> {
- return entries.map { it.modelId }
- }
- }
+ companion object {
+ private val ALL: Array<EmbeddingModel> = values()
+ private val BY_MODEL_ID: Map<String, EmbeddingModel> = ALL.associateBy { it.modelId }
+
+ @JvmStatic
+ fun findByModelId(modelId: String): EmbeddingModel? = BY_MODEL_ID[modelId]
+
+ @JvmStatic
+ fun getAllModelIds(): List<String> = ALL.map { it.modelId }
+ }📝 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.
| companion object { | |
| fun findByModelId(modelId: String): EmbeddingModel? { | |
| return entries.find { it.modelId == modelId } | |
| } | |
| fun getAllModelIds(): List<String> { | |
| return entries.map { it.modelId } | |
| } | |
| companion object { | |
| private val ALL: Array<EmbeddingModel> = values() | |
| private val BY_MODEL_ID: Map<String, EmbeddingModel> = ALL.associateBy { it.modelId } | |
| @JvmStatic | |
| fun findByModelId(modelId: String): EmbeddingModel? = BY_MODEL_ID[modelId] | |
| @JvmStatic | |
| fun getAllModelIds(): List<String> = ALL.map { it.modelId } | |
| } |
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 44 to 51, replace the current entries-based linear search and
entries dependency with a static lookup map built from values() for O(1) lookup
and use values() to produce the model-id list to preserve declaration order and
ensure Kotlin <1.9 compatibility; add a private val MODEL_BY_ID =
values().associateBy { it.modelId } in the companion object and change
findByModelId to return MODEL_BY_ID[modelId], and change getAllModelIds to
return values().map { it.modelId } so you no longer rely on entries and get
constant-time lookups and stable ordering.
| require(attribute.all { !it.isNaN() && !it.isInfinite() }) { | ||
| "Embedding must not contain NaN/Infinity" | ||
| } | ||
| return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() } |
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.
🧹 Nitpick (assertive)
유한성 체크 표현 통일: isFinite() 사용 권장
저장 경로에선 !isNaN && !isInfinite를, 로드 경로에선 isFinite()를 사용하고 있어 표현이 다릅니다. 가독성/일관성을 위해 isFinite()로 통일하세요.
적용 diff:
- require(attribute.all { !it.isNaN() && !it.isInfinite() }) {
- "Embedding must not contain NaN/Infinity"
- }
+ require(attribute.all { it.isFinite() }) {
+ "Embedding must not contain NaN/Infinity"
+ }📝 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.
| require(attribute.all { !it.isNaN() && !it.isInfinite() }) { | |
| "Embedding must not contain NaN/Infinity" | |
| } | |
| return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() } | |
| require(attribute.all { it.isFinite() }) { | |
| "Embedding must not contain NaN/Infinity" | |
| } | |
| return attribute.joinToString(prefix = "[", postfix = "]", separator = ",") { it.toString() } |
🤖 Prompt for AI Agents
In
src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt
around lines 11 to 14, the finiteness check currently uses require(attribute.all
{ !it.isNaN() && !it.isInfinite() }) { "Embedding must not contain NaN/Infinity"
}; replace that predicate with the unified Kotlin idiom attribute.all {
it.isFinite() } (you can keep the existing error message or adjust wording if
desired) so the code matches the load path style and improves
readability/consistency.
| override fun convertToEntityAttribute(dbData: String?): FloatArray { | ||
| if (dbData.isNullOrBlank()) return floatArrayOf() | ||
| val body = dbData.trim().removePrefix("[").removeSuffix("]").trim() | ||
| if (body.isBlank()) return floatArrayOf() | ||
| return try { | ||
| body.split(',') | ||
| .map { it.trim().toFloat() } | ||
| .toFloatArray() | ||
| .also { arr -> | ||
| require(arr.all { it.isFinite() }) { | ||
| "Embedding must not contain NaN/Infinity (db → entity)" | ||
| } | ||
| } | ||
| } catch (e: NumberFormatException) { | ||
| throw IllegalArgumentException("Invalid vector literal for pgvector: '$dbData'", e) | ||
| } | ||
| } |
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.
🧹 Nitpick (assertive)
경계 테스트 보강 제안
다음 케이스에 대한 단위 테스트를 추가하면 회귀 방지에 도움이 됩니다.
- 정상: "[1, 2.5, -3e-2]" → FloatArray(1f, 2.5f, -0.03f)
- 공백/빈: null, "", "[]", "[ ]" → floatArrayOf()
- 오류: "[1,2,]", "[a,1]", "1,2,3"(괄호 없음), "[NaN, 1]", "[Infinity]"
필요하시면 JUnit5 코틀린 테스트 스텁을 생성해 드립니다.
🤖 Prompt for AI Agents
In
src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt
around lines 17 to 33, the converter lacks unit tests for edge and error cases;
add JUnit5 Kotlin tests that assert: valid input "[1, 2.5, -3e-2]" returns
floatArrayOf(1f, 2.5f, -0.03f); null, "", "[]", and "[ ]" return empty
floatArrayOf(); malformed inputs "[1,2,]", "[a,1]", and "1,2,3" (missing
brackets) throw IllegalArgumentException; and "[NaN, 1]" and "[Infinity]" also
trigger IllegalArgumentException (or otherwise ensure the converter enforces
isFinite and fails); implement tests using assertArrayEquals for arrays and
assertThrows for exceptions.
| override fun convertToEntityAttribute(dbData: String?): FloatArray { | ||
| if (dbData.isNullOrBlank()) return floatArrayOf() | ||
| val body = dbData.trim().removePrefix("[").removeSuffix("]").trim() | ||
| if (body.isBlank()) return floatArrayOf() | ||
| return try { |
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
입력 포맷 엄격화: 대괄호 존재 여부를 명시적으로 검증하세요
현재는 removePrefix/removeSuffix로 포맷을 느슨하게 처리합니다. 예상치 못한 문자열(예: 괄호 없는 “1,2,3”)도 통과할 수 있으므로, 표준 포맷([1,2,3])을 엄격히 요구하는 편이 안전합니다.
적용 diff:
- if (dbData.isNullOrBlank()) return floatArrayOf()
- val body = dbData.trim().removePrefix("[").removeSuffix("]").trim()
- if (body.isBlank()) return floatArrayOf()
+ if (dbData.isNullOrBlank()) return floatArrayOf()
+ val trimmed = dbData.trim()
+ require(trimmed.startsWith("[") && trimmed.endsWith("]")) {
+ "Invalid vector literal for pgvector: '$dbData' (missing brackets)"
+ }
+ val body = trimmed.substring(1, trimmed.length - 1).trim()
+ if (body.isBlank()) return floatArrayOf()🤖 Prompt for AI Agents
In
src/main/kotlin/simplerag/ragback/global/util/FloatArrayToPgVectorStringConverter.kt
around lines 17–21, the converter currently uses removePrefix/removeSuffix and
thus accepts strings without explicit surrounding brackets; change to strictly
require the input to start with '[' and end with ']' after trimming, and if not,
throw an IllegalArgumentException (or return an empty array per project
convention) to reject malformed input; then extract the inner substring by
slicing off the first and last character (rather than removePrefix/removeSuffix)
and continue parsing the comma-separated numbers as before.
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
♻️ Duplicate comments (1)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (1)
3-6: FK 보조 인덱스로 조인 성능 개선 + JPA Index 네이밍 충돌 회피(옵셔널, 중복 제안)조인/필터가 잦다면 models.indexes_id, models.prompts_id에 보조 인덱스를 추가하세요. 도메인 Index와 jakarta.persistence.Index 이름 충돌은 alias로 회피합니다.
예시 diff:
import jakarta.persistence.* import simplerag.ragback.domain.index.entity.Index import simplerag.ragback.domain.prompt.entity.Prompt import simplerag.ragback.global.entity.BaseEntity +import jakarta.persistence.Index as JpaIndex @@ -@Table(name = "models") +@Table( + name = "models", + indexes = [ + JpaIndex(name = "idx_models_indexes_id", columnList = "indexes_id"), + JpaIndex(name = "idx_models_prompts_id", columnList = "prompts_id") + ] +)Also applies to: 8-10
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-17T13:13:20.202Z
Learnt from: catturtle123
PR: Simple-RAG/BACK#6
File: src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt:12-16
Timestamp: 2025-08-17T13:13:20.202Z
Learning: Model 엔티티에서 llmModel 필드는 unique 제약을 제거하여 동일한 LLM으로 다른 프롬프트/인덱스를 가진 여러 모델 구성을 허용해야 함. name 필드만 unique로 유지하여 각 모델 구성의 고유 식별자 역할을 함.
Applied to files:
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt
🔇 Additional comments (2)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (2)
15-16: llmModel의 unique 제거 결정 반영 — OK제품 의도(동일 LLM으로 다양한 프롬프트/인덱스 조합 허용)를 정확히 반영했습니다. name만 unique로 유지하는 현재 설계가 적절합니다. (learnings 반영)
1-29: Kotlin JPA 플러그인(all-open/no-arg) 적용 확인됨
build.gradle6번 라인에id 'org.jetbrains.kotlin.plugin.jpa' version '1.9.25'가 선언되어 있어
JPA 엔티티에 필요한 all-open 및 no-arg 기능이 자동 활성화됩니다.- 별도의
allOpen { … }/noArg { … }설정 블록이 없어도 충분하므로 추가 조치가 필요 없습니다.
| @Column(name = "name", nullable = false, unique = true, length = 100) | ||
| val name: String, | ||
|
|
||
| @Column(name = "llm_model", nullable = false) | ||
| val llmModel: String, |
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.
🧹 Nitpick (assertive)
입력 유효성 보강 제안 — @notblank로 공백 문자열 방지(옵셔널)
DB 제약만으로는 빈 문자열을 막지 못합니다. Bean Validation을 추가하면 API/서비스 레이어에서 조기에 검증 가능합니다.
예시 diff:
import jakarta.persistence.*
+import jakarta.validation.constraints.NotBlank
@@
- @Column(name = "name", nullable = false, unique = true, length = 100)
+ @field:NotBlank
+ @Column(name = "name", nullable = false, unique = true, length = 100)
val name: String,
@@
- @Column(name = "llm_model", nullable = false)
+ @field:NotBlank
+ @Column(name = "llm_model", nullable = false)
val llmModel: String,📝 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.
| @Column(name = "name", nullable = false, unique = true, length = 100) | |
| val name: String, | |
| @Column(name = "llm_model", nullable = false) | |
| val llmModel: String, | |
| // at the top of src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt | |
| import jakarta.persistence.* | |
| import jakarta.validation.constraints.NotBlank | |
| @field:NotBlank | |
| @Column(name = "name", nullable = false, unique = true, length = 100) | |
| val name: String, | |
| @field:NotBlank | |
| @Column(name = "llm_model", nullable = false) | |
| val llmModel: String, |
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt around lines 12
to 16, the String fields lack Bean Validation to prevent blank values; add
Kotlin field-level NotBlank annotations to both properties (use @field:NotBlank
on name and llmModel), import the appropriate NotBlank class
(jakarta.validation.constraints.NotBlank or
javax.validation.constraints.NotBlank matching the project), and ensure Bean
Validation is enabled on the application so blank strings are rejected before
hitting the DB.
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "indexes_id") | ||
| val index: Index, | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "prompts_id") | ||
| val prompt: Prompt, |
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
FK 컬럼이 NULL 허용 상태 — DB 무결성 보장을 위해 optional=false + nullable=false 지정 권장
ManyToOne의 기본 optional=true, @joincolumn의 기본 nullable=true라 DB에서 NULL을 허용합니다. 모델이 항상 Index/Prompt를 가져야 한다면 명시적으로 비허용으로 바꿔 무결성을 보장하세요.
적용 diff:
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "indexes_id")
+ @ManyToOne(fetch = FetchType.LAZY, optional = false)
+ @JoinColumn(name = "indexes_id", nullable = false)
val index: Index,
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "prompts_id")
+ @ManyToOne(fetch = FetchType.LAZY, optional = false)
+ @JoinColumn(name = "prompts_id", nullable = false)
val prompt: Prompt,📝 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.
| @ManyToOne(fetch = FetchType.LAZY) | |
| @JoinColumn(name = "indexes_id") | |
| val index: Index, | |
| @ManyToOne(fetch = FetchType.LAZY) | |
| @JoinColumn(name = "prompts_id") | |
| val prompt: Prompt, | |
| @ManyToOne(fetch = FetchType.LAZY, optional = false) | |
| @JoinColumn(name = "indexes_id", nullable = false) | |
| val index: Index, | |
| @ManyToOne(fetch = FetchType.LAZY, optional = false) | |
| @JoinColumn(name = "prompts_id", nullable = false) | |
| val prompt: Prompt, |
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt around lines 18
to 24, the ManyToOne associations for index and prompt default to optional=true
and the JoinColumn defaults to nullable=true which allows NULLs in the FK
columns; update each association to declare non-optional and non-nullable by
setting @ManyToOne(optional = false) and @JoinColumn(name = "...", nullable =
false) so the ORM and DB enforce presence of Index and Prompt.
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.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
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
♻️ Duplicate comments (3)
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt (3)
13-14: 상수명 오탈자 정리 제안: MP_NET → MPNET로 일관화공식 표기는 “MPNET”으로 붙여 쓰는 경우가 일반적입니다. 신규 코드라면 상수명을 일관화해 두는 편이 유지보수에 유리합니다. 다만, 해당 enum이 JPA
EnumType.STRING으로 영속화되고 있다면 DB 마이그레이션 또는 Converter 전환 없이는 바로 리네이밍하지 마세요.아래 리네이밍(선호) 패치를 제안합니다:
- ALL_MP_NET_BASE_V2(768, "sentence-transformers/all-mpnet-base-v2"), - MULTI_QA_MP_NET_BASE_DOT_V1(768, "sentence-transformers/multi-qa-mpnet-base-dot-v1"), + ALL_MPNET_BASE_V2(768, "sentence-transformers/all-mpnet-base-v2"), + MULTI_QA_MPNET_BASE_DOT_V1(768, "sentence-transformers/multi-qa-mpnet-base-dot-v1"),리네이밍 결정 시, 사용처/직렬화 포맷/DB 값 영향 범위를 반드시 확인해 주세요.
다음 스크립트로 상수 사용처를 빠르게 점검할 수 있습니다:
#!/bin/bash # 리네이밍 영향 범위 파악 rg -nP -C2 '\b(ALL_MP_NET_BASE_V2|MULTI_QA_MP_NET_BASE_DOT_V1)\b'
40-47: O(1) 조회 및 Kotlin 버전 호환성 확보: entries 제거, 정적 맵 도입빈번 호출 시 선형 탐색은 누적 비용이 큽니다. 또한
entries는 Kotlin 버전에 따라 가용성 이슈가 있습니다.values()+ 정적 맵으로 교체하고, 중복 modelId 방지 가드 및 Java 상호운용(@JvmStatic)도 함께 제안합니다.- companion object { - fun findByModelId(modelId: String): EmbeddingModel? { - return entries.find { it.modelId == modelId } - } - - fun getAllModelIds(): List<String> { - return entries.map { it.modelId } - } - } + companion object { + private val ALL: Array<EmbeddingModel> = values() + private val BY_MODEL_ID: Map<String, EmbeddingModel> = ALL.associateBy { it.modelId } + + init { + require(BY_MODEL_ID.size == ALL.size) { + "EmbeddingModel.modelId must be unique; duplicates detected" + } + } + + @JvmStatic + fun findByModelId(modelId: String): EmbeddingModel? = BY_MODEL_ID[modelId] + + @JvmStatic + fun getAllModelIds(): List<String> = ALL.map { it.modelId } + }추가로, 이 두 API에 대한 간단한 단위 테스트(모든 상수에 대해 findByModelId(modelId) == 상수, getAllModelIds() == values().map { it.modelId })를 권장합니다. 원하시면 템플릿 제공 가능합니다.
37-41: 로깅/표시 일관성 개선: toString을 modelId로 노출운영 로그/메트릭/에러 메시지에서 즉시 식별 가능하도록
toString()오버라이드를 권장합니다.- FASTTEXT_KO(300, "fasttext-ko-300d"); + FASTTEXT_KO(300, "fasttext-ko-300d"); + + override fun toString(): String = modelId
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt(1 hunks)
🔇 Additional comments (1)
src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt (1)
24-26: LGTM: Mistral 임베딩 차원 1024 반영이 정확합니다공식 문서 기준 mistral-embed의 차원은 1024가 맞습니다. 최신 사양과 일치합니다.
| package simplerag.ragback.domain.index.entity.enums | ||
|
|
||
| enum class EmbeddingModel( | ||
| val dim: Int, | ||
| val modelId: String | ||
| ) { |
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.
🧹 Nitpick (assertive)
JPA 영속 안정성 강화: enum 이름 대신 modelId로 저장하도록 Converter 전환 권장
AI 요약상 Index 엔티티에서 @Enumerated(EnumType.STRING)으로 저장 중이라면, 상수명 변경 시 기존 데이터가 깨집니다. modelId를 DB에 저장하도록 AttributeConverter로 전환하면 리네이밍 리스크를 제거할 수 있습니다.
예시 Converter:
import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter
@Converter(autoApply = false)
class EmbeddingModelConverter : AttributeConverter<EmbeddingModel, String> {
override fun convertToDatabaseColumn(attribute: EmbeddingModel?): String? =
attribute?.modelId
override fun convertToEntityAttribute(dbData: String?): EmbeddingModel? =
dbData?.let { EmbeddingModel.findByModelId(it) }
}엔티티 필드 적용 예시:
@Convert(converter = EmbeddingModelConverter::class)
@Column(name = "embedding_model", nullable = false)
var embeddingModel: EmbeddingModel이후에는 enum 상수명을 정리(예: MPNET 표기)하더라도 DB 값(=modelId)은 변하지 않아 안전합니다.
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/index/entity/enums/EmbeddingModel.kt
around lines 1 to 6, switch persistence from storing enum names to storing the
stable modelId by implementing a Jakarta Persistence AttributeConverter that
maps EmbeddingModel ⇄ String using modelId (convertToDatabaseColumn returns
attribute?.modelId, convertToEntityAttribute looks up EmbeddingModel by modelId
via a findByModelId function), then annotate the entity field with
@Convert(converter = EmbeddingModelConverter::class) and set the @Column to use
the existing embedding_model column; ensure the converter handles nulls and that
EmbeddingModel exposes a lookup method to find an enum by modelId.
📌 PR 개요
erd 수정
🔍 관련 이슈
✨ 변경 사항
✨ feature: 인덱스 관련 엔티티 생성
✨ feature: 인덱스 관련 엔티티 생성
✨ feature: 시간 자동 생성 로직
✨ feature: 모델 엔티티 생성
✨ feature: datafile 관련 엔티티 수
📸 스크린샷 / 동작 확인 결과 (선택)
필요하다면 이미지나 동영상 첨부.
✅ 체크리스트
🗒️ 추가 메모
기타 참고 사항을 적어주세요.
Summary by CodeRabbit
New Features
Tests