-
Notifications
You must be signed in to change notification settings - Fork 0
✨ Feature: index 메타데이터 CRUD 기능 추가 #11
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
Changes from all commits
6b2ff23
675f87c
88dcf54
f91166a
562da35
9d2952c
5a3c8aa
3c0a439
47529f8
de99d88
7e5f981
498a209
9ad88a8
9dddf80
4d77119
83c1099
e70fe40
372ef3f
462fff4
de40020
a963ab4
001e6d4
c10896a
b376f5c
bf3a5b6
3db1d9f
222d038
31c2066
480f4d8
8b8ee56
37da14f
0906b39
d0375ab
11531c3
7b64209
5ae2ac3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package simplerag.ragback.domain.index.controller | ||
|
|
||
| import jakarta.validation.Valid | ||
| import org.springframework.http.HttpStatus | ||
| import org.springframework.validation.annotation.Validated | ||
| import org.springframework.web.bind.annotation.* | ||
| import simplerag.ragback.domain.index.dto.* | ||
| import simplerag.ragback.domain.index.service.IndexService | ||
| import simplerag.ragback.global.response.ApiResponse | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/v1/indexes") | ||
| @Validated | ||
| class IndexController( | ||
| private val indexService: IndexService | ||
| ) { | ||
|
|
||
| @PostMapping | ||
| @ResponseStatus(HttpStatus.CREATED) | ||
| fun createIndex( | ||
| @RequestBody @Valid indexCreateRequest: IndexCreateRequest | ||
| ): ApiResponse<IndexPreviewResponse> { | ||
| val createdIndex = indexService.createIndex(indexCreateRequest) | ||
| return ApiResponse.ok(createdIndex) | ||
| } | ||
|
|
||
| @GetMapping | ||
| fun getIndexes(): ApiResponse<IndexPreviewResponseList> { | ||
| val indexPreviewResponseList = indexService.getIndexes() | ||
| return ApiResponse.ok(indexPreviewResponseList) | ||
| } | ||
|
Comment on lines
+27
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 목록 조회에 페이징/정렬 파라미터 도입 권장 대량 데이터에서 전체 반환은 비효율적입니다. Pageable 주입 + 서비스/레포지토리 연동으로 페이지네이션을 제공하세요. 컨트롤러 예시: - @GetMapping
- fun getIndexes(): ApiResponse<IndexPreviewResponseList> {
- val indexPreviewResponseList = indexService.getIndexes()
+ @GetMapping
+ fun getIndexes(pageable: org.springframework.data.domain.Pageable): ApiResponse<IndexPreviewResponseList> {
+ val indexPreviewResponseList = indexService.getIndexes(pageable)
return ApiResponse.ok(indexPreviewResponseList)
}서비스/레포지토리(참고): // Service
fun getIndexes(pageable: Pageable): IndexPreviewResponseList {
val page = indexRepository.findAll(pageable.sortOr(Sort.by(Sort.Direction.DESC, "createdAt")))
// page.content → DTO 매핑 + total, hasNext 등 노출 필요 시 확장
...
}
// Helper
private fun Pageable.sortOr(defaultSort: Sort) =
if (sort.isSorted) this else PageRequest.of(pageNumber, pageSize, defaultSort) |
||
|
|
||
| @GetMapping("/{indexId}") | ||
| fun getIndex( | ||
| @PathVariable indexId: Long | ||
| ): ApiResponse<IndexDetailResponse> { | ||
| val indexDetailResponse = indexService.getIndex(indexId) | ||
| return ApiResponse.ok(indexDetailResponse) | ||
| } | ||
|
|
||
| @PutMapping("/{indexId}") | ||
| fun updateIndexes( | ||
| @PathVariable indexId: Long, | ||
| @RequestBody @Valid indexUpdateRequest: IndexUpdateRequest, | ||
| ): ApiResponse<IndexPreviewResponse> { | ||
| val indexPreviewResponse = indexService.updateIndex(indexId, indexUpdateRequest) | ||
| return ApiResponse.ok(indexPreviewResponse) | ||
| } | ||
|
|
||
| @DeleteMapping("/{indexId}") | ||
| fun deleteIndex( | ||
| @PathVariable indexId: Long | ||
| ): ApiResponse<Unit> { | ||
| indexService.deleteIndex(indexId) | ||
| return ApiResponse.ok(null, "인덱스가 삭제 되었습니다.") | ||
| } | ||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| package simplerag.ragback.domain.index.converter | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.dto.IndexCreateRequest | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.dto.IndexDetailResponse | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.dto.IndexPreviewResponse | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.dto.IndexPreviewResponseList | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.entity.Index | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fun toIndex(createRequest: IndexCreateRequest): Index { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return Index( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| snapshotName = createRequest.snapshotName.trim(), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| overlapSize = createRequest.overlapSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| chunkingSize = createRequest.chunkingSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| similarityMetric = createRequest.similarityMetric, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| topK = createRequest.topK, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| embeddingModel = createRequest.embeddingModel, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| reranker = createRequest.reranker | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fun toIndexPreviewResponseList( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| indexes: List<Index> | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ): IndexPreviewResponseList { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| val indexList = indexes.map { toIndexPreviewResponse(it) } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return IndexPreviewResponseList(indexList) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 리스트 DTO 네이밍 변경 반영 DTO의 필드명을 fun toIndexPreviewResponseList(
indexes: List<Index>
): IndexPreviewResponseList {
val indexList = indexes.map { toIndexPreviewResponse(it) }
- return IndexPreviewResponseList(indexList)
+ return IndexPreviewResponseList(items = indexList)
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Comment on lines
+26
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain리스트 DTO 생성자: 명시적 파라미터 사용 및 DTO 구조 확인 권장 생성자 위치 의존보다 이름 기반 전달이 안전합니다. DTO 필드명이 items/contents 등으로 변경될 가능성에 대비해 명시적 파라미터를 권장합니다. 현재 DTO 시그니처가 무엇인지 확인해 주세요. 다음 스크립트로 DTO 정의를 확인해 주세요(필드명/생성자 파라미터 명 확인): 🏁 Script executed: #!/bin/bash
# DTO 정의 위치와 필드명을 출력
rg -n -C3 'data\s+class\s+IndexPreviewResponseList' --glob '!**/build/**'
rg -n -C3 'class\s+IndexPreviewResponseList|data\s+class\s+IndexPreviewResponseList' --glob '!**/build/**'Length of output: 1670 리스트 DTO 생성자: 명시적 파라미터 사용 제안 확인된 DTO 시그니처: data class IndexPreviewResponseList(
val indexDetailResponse: List<IndexPreviewResponse>
)생성자 호출 시 위치 의존 대신 이름 기반 전달을 권장드립니다: - return IndexPreviewResponseList(indexList)
+ return IndexPreviewResponseList(indexDetailResponse = indexList)• 파일: src/main/kotlin/simplerag/ragback/domain/index/converter/IndexConverter.kt 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fun toIndexPreviewResponse(index: Index): IndexPreviewResponse { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return IndexPreviewResponse( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| indexId = index.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| snapshotName = index.snapshotName, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 식별자 비널화에 맞춘 매핑: requireNotNull로 fail-fast DTO에서 fun toIndexPreviewResponse(index: Index): IndexPreviewResponse {
return IndexPreviewResponse(
- indexId = index.id,
+ indexId = requireNotNull(index.id) { "Index.id should not be null after persistence" },
snapshotName = index.snapshotName,
)
}참고: 만약 생성 직후 IDENTITY 전략으로 id가 null 가능성이 있으면, 서비스에서 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| fun toIndexDetailResponse(index: Index): IndexDetailResponse { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return IndexDetailResponse( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| indexId = index.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| chunkingSize = index.chunkingSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| overlapSize = index.overlapSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| similarityMetric = index.similarityMetric, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| topK = index.topK, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| embeddingModel = index.embeddingModel, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| reranker = index.reranker, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| snapshotName = index.snapshotName, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+36
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Detail 매핑도 동일하게 비널 보장 Detail 응답도 fun toIndexDetailResponse(index: Index): IndexDetailResponse {
return IndexDetailResponse(
- indexId = index.id,
+ indexId = requireNotNull(index.id) { "Index.id should not be null for detail response" },
chunkingSize = index.chunkingSize,
overlapSize = index.overlapSize,
similarityMetric = index.similarityMetric,
topK = index.topK,
embeddingModel = index.embeddingModel,
reranker = index.reranker,
snapshotName = index.snapshotName,
)
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,48 @@ | ||||||||||||||||||||||||||||
| package simplerag.ragback.domain.index.dto | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import jakarta.validation.constraints.NotBlank | ||||||||||||||||||||||||||||
| import jakarta.validation.constraints.Positive | ||||||||||||||||||||||||||||
| import jakarta.validation.constraints.PositiveOrZero | ||||||||||||||||||||||||||||
| import org.hibernate.validator.constraints.Length | ||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.entity.enums.EmbeddingModel | ||||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.entity.enums.SimilarityMetric | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
Comment on lines
+3
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 교차 필드 유효성 검증 추가 제안: overlapSize ≤ chunkingSize 요구사항을 DTO 레벨에서 선제 검증하면 컨트롤러 단에서 일관된 400 응답을 보장할 수 있습니다. 서비스 레이어 검증은 유지하되, 입력 경계에서도 막는 것을 권장합니다. 추가 import: import jakarta.validation.constraints.NotBlank
+import jakarta.validation.constraints.AssertTrue
import jakarta.validation.constraints.Positive
import jakarta.validation.constraints.PositiveOrZero📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| data class IndexCreateRequest( | ||||||||||||||||||||||||||||
| @field:Length(max = 255) | ||||||||||||||||||||||||||||
| @field:NotBlank | ||||||||||||||||||||||||||||
| val snapshotName: String, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @field:Positive | ||||||||||||||||||||||||||||
| val chunkingSize: Int, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @field:PositiveOrZero | ||||||||||||||||||||||||||||
| val overlapSize: Int, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| val similarityMetric: SimilarityMetric, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @field:Positive | ||||||||||||||||||||||||||||
| val topK: Int, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| val embeddingModel: EmbeddingModel, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| val reranker: Boolean, | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| data class IndexUpdateRequest( | ||||||||||||||||||||||||||||
| @field:Length(max = 255) | ||||||||||||||||||||||||||||
| @field:NotBlank | ||||||||||||||||||||||||||||
| val snapshotName: String, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @field:Positive | ||||||||||||||||||||||||||||
| val chunkingSize: Int, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @field:PositiveOrZero | ||||||||||||||||||||||||||||
| val overlapSize: Int, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| val similarityMetric: SimilarityMetric, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| @field:Positive | ||||||||||||||||||||||||||||
| val topK: Int, | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| val reranker: Boolean, | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
Comment on lines
+47
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) IndexUpdateRequest에 교차 검증 추가 업데이트에서도 동일 제약을 보장해야 합니다. data class IndexUpdateRequest(
@@
val topK: Int,
val reranker: Boolean,
+
+ @get:AssertTrue(message = "overlapSize는 chunkingSize를 초과할 수 없습니다")
+ val isOverlapValid: Boolean
+ get() = overlapSize <= chunkingSize,
)
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||||||||
| package simplerag.ragback.domain.index.dto | ||||||||||||||
|
|
||||||||||||||
| import simplerag.ragback.domain.index.entity.enums.EmbeddingModel | ||||||||||||||
| import simplerag.ragback.domain.index.entity.enums.SimilarityMetric | ||||||||||||||
|
|
||||||||||||||
| data class IndexPreviewResponseList( | ||||||||||||||
| val indexDetailResponse: List<IndexPreviewResponse>, | ||||||||||||||
| ) | ||||||||||||||
|
Comment on lines
+6
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 리스트 필드 네이밍 오류: Preview 목록인데 의미상 혼동됩니다. 적용 예: data class IndexPreviewResponseList(
- val indexDetailResponse: List<IndexPreviewResponse>,
+ val items: List<IndexPreviewResponse>,
)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| data class IndexPreviewResponse( | ||||||||||||||
| var indexId: Long?, | ||||||||||||||
| val snapshotName: String | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| data class IndexDetailResponse( | ||||||||||||||
| var indexId: Long?, | ||||||||||||||
| val snapshotName: String, | ||||||||||||||
| val chunkingSize: Int, | ||||||||||||||
| val overlapSize: Int, | ||||||||||||||
| val similarityMetric: SimilarityMetric, | ||||||||||||||
| val topK: Int, | ||||||||||||||
| val embeddingModel: EmbeddingModel, | ||||||||||||||
| val reranker: Boolean, | ||||||||||||||
| ) | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ package simplerag.ragback.domain.index.entity | |
|
|
||
| import jakarta.persistence.* | ||
| import jakarta.validation.constraints.Min | ||
| import simplerag.ragback.domain.index.dto.IndexUpdateRequest | ||
| import simplerag.ragback.domain.index.entity.enums.EmbeddingModel | ||
| import simplerag.ragback.domain.index.entity.enums.SimilarityMetric | ||
| import simplerag.ragback.global.entity.BaseEntity | ||
|
|
@@ -11,32 +12,46 @@ import simplerag.ragback.global.entity.BaseEntity | |
| class Index( | ||
|
|
||
| @Column(name = "snapshot_name", length = 255, nullable = false) | ||
| val snapshotName: String, | ||
| var snapshotName: String, | ||
|
|
||
|
Comment on lines
14
to
16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 입력 유효성 강화: snapshotName에 @notblank 추가 권장 빈 문자열/공백만 있는 경우를 방지하려면 Bean Validation을 병행하세요(서비스/컨트롤러 @Valid와 함께 사용 권장). @Column(name = "snapshot_name", length = 255, nullable = false)
- var snapshotName: String,
+ @field:jakarta.validation.constraints.NotBlank
+ var snapshotName: String,추가로, 상단 import에 다음을 포함하세요(필요 시): import jakarta.validation.constraints.NotBlank🤖 Prompt for AI Agents |
||
| @Column(name = "chunking_size", nullable = false) | ||
| @Min(1) | ||
| val chunkingSize: Int, | ||
| var chunkingSize: Int, | ||
|
|
||
| @Column(name = "overlap_size", nullable = false) | ||
| @Min(0) | ||
| val overlapSize: Int, | ||
| var overlapSize: Int, | ||
|
|
||
| @Column(name = "similarity_metric", nullable = false) | ||
| @Enumerated(EnumType.STRING) | ||
| val similarityMetric: SimilarityMetric, | ||
| var similarityMetric: SimilarityMetric, | ||
|
|
||
| @Column(name = "top_k", nullable = false) | ||
| @Min(1) | ||
| val topK: Int, | ||
| var topK: Int, | ||
|
|
||
| @Column(name = "embedding_model", nullable = false, length = 255) | ||
| @Enumerated(EnumType.STRING) | ||
| val embeddingModel: EmbeddingModel, | ||
|
|
||
| @Column(name = "reranker", nullable = false) | ||
| val reranker: Boolean, | ||
| var reranker: Boolean, | ||
|
|
||
| @OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true, mappedBy = "index") | ||
| val chunkEmbeddings: MutableList<ChunkEmbedding> = mutableListOf(), | ||
|
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 엔티티 컬렉션 캡슐화: MutableList 직접 노출 지양 엔티티의 연관 컬렉션을 외부에 MutableList로 노출하면 불변식이 깨지기 쉽습니다(임의 추가/삭제, 양방향 일관성 붕괴). JPA 매핑 대상 필드는 private로 숨기고, 읽기 전용 뷰와 편의 메서드를 제공하는 패턴을 권장합니다. 아래처럼 백킹 필드로 매핑하고, 읽기 전용 getter 및 편의 메서드를 추가하세요. - @OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true, mappedBy = "index")
- val chunkEmbeddings: MutableList<ChunkEmbedding> = mutableListOf(),
+ @OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true, mappedBy = "index")
+ private val _chunkEmbeddings: MutableList<ChunkEmbedding> = mutableListOf(),추가(동일 파일 내 다른 위치에 배치): // 읽기 전용 뷰 제공
val chunkEmbeddings: List<ChunkEmbedding> get() = _chunkEmbeddings.toList()
// 편의 메서드: 양방향 일관성 보장
fun addChunkEmbedding(embedding: ChunkEmbedding) {
require(embedding.index === this) { "ChunkEmbedding.index must be this Index" }
_chunkEmbeddings.add(embedding)
}
fun removeChunkEmbedding(embedding: ChunkEmbedding) {
_chunkEmbeddings.remove(embedding)
} |
||
|
|
||
| @Id @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "indexes_id") | ||
| val id: Long? = null, | ||
| ): BaseEntity() | ||
| var id: Long? = null, | ||
| ) : BaseEntity() { | ||
|
|
||
| fun update(req: IndexUpdateRequest) { | ||
| snapshotName = req.snapshotName.trim() | ||
| chunkingSize = req.chunkingSize | ||
| overlapSize = req.overlapSize | ||
| similarityMetric = req.similarityMetric | ||
| topK = req.topK | ||
| reranker = req.reranker | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package simplerag.ragback.domain.index.repository | ||
|
|
||
| import org.springframework.data.jpa.repository.JpaRepository | ||
| import simplerag.ragback.domain.index.entity.ChunkEmbedding | ||
|
|
||
| interface ChunkEmbeddingRepository : JpaRepository<ChunkEmbedding, Long> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,9 @@ | ||||||||||||||||||||||||||
| package simplerag.ragback.domain.index.repository | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| import org.springframework.data.jpa.repository.JpaRepository | ||||||||||||||||||||||||||
| import simplerag.ragback.domain.index.entity.Index | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| interface IndexRepository : JpaRepository<Index, Long> { | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| fun findAllByOrderByCreatedAtDesc(): List<Index> | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+6
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 목록 조회에 페이징 오버로드 추가 제안 데이터가 증가하면 List 전량 로딩은 부담이 큽니다. Desc 정렬을 유지하되 Pageable 오버로드를 추가해 확장성을 확보하는 것을 권장합니다. 적용 예(인터페이스에 오버로드 추가): +import org.springframework.data.domain.Page
+import org.springframework.data.domain.Pageable interface IndexRepository : JpaRepository<Index, Long> {
fun findAllByOrderByCreatedAtDesc(): List<Index>
+ fun findAllByOrderByCreatedAtDesc(pageable: Pageable): Page<Index>
}서비스/컨트롤러에서 pageable을 받아 활용하도록 점진 적용할 수 있습니다(기존 List 메서드는 하위호환 유지). 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
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)
201 Created의 Location 헤더 제공 고려
리소스 생성 시
Location: /api/v1/indexes/{id}헤더를 추가하면 REST 사용성이 좋아집니다.ApiResponse래퍼 정책에 따라 ResponseEntity 사용을 검토하세요.예시:
🤖 Prompt for AI Agents