[Feat] rag_responses 저장 - #72
Conversation
rag_responses.llm_model_name을 별도 설정값 재조회 없이, Ollama가 실제로 응답을 생성한 모델명(응답의 model 필드)에서 그대로 가져오도록 한다.
OllamaGenerateResponse 생성자에 model 인자가 추가된 것을 테스트 mocking에 반영하고, 정상 케이스에 result.model() 검증을 추가한다.
OllamaClient 호출 결과(성공/실패)를 rag_responses에 저장한다. SearchQuery와 달리 단일 호출로 성공/실패가 갈리므로 PROCESSING 중간 상태 없이 createSuccess/createFailed로 한 번에 저장한다. answer_text NOT NULL 제약 때문에 FAILED 시에도 고정 문구를 저장하고, 실제 실패 사유는 error_message에 담는다. FAILED 기록은 SearchQueryCommandService.markFailed와 동일하게 REQUIRES_NEW로 상위 트랜잭션 롤백과 무관하게 저장되도록 한다.
createSuccess/createFailed가 저장하려는 RagResponse 필드가 기대한 값과 일치하는지 ArgumentCaptor로 검증한다.
코드 작성이 끝났다고 바로 커밋/PR을 진행하지 않고, 사용자가 결과를 확인하고 명시적으로 승인한 뒤에만 실행하도록 git-conventions.md에 명시한다.
📝 WalkthroughWalkthroughOllama 응답 DTO에 모델 정보를 추가하고, RAG 생성 결과를 성공·실패 상태로 ChangesRAG 응답 저장
개발 작업 규칙
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant OllamaClient
participant RagResponseCommandService
participant RagResponseRepository
OllamaClient->>RagResponseCommandService: 생성 결과 또는 오류 전달
RagResponseCommandService->>RagResponseRepository: SUCCESS/FAILED 응답 저장
RagResponseRepository-->>RagResponseCommandService: 저장 결과 반환
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/opensource/docgrid/domain/rag/repository/RagResponseRepository.java`:
- Around line 7-8: RagResponseRepository에 class-level Javadoc를 추가해 RagResponse의
영속화와 Spring Data가 제공하는 기본 CRUD만 담당하며 그 외 비즈니스 로직은 포함하지 않는다는 역할과 경계를 간략히 설명하세요.
In
`@src/test/java/com/opensource/docgrid/domain/rag/service/command/RagResponseCommandServiceTest.java`:
- Around line 24-32: RagResponseCommandServiceTest의 Mockito 단위 테스트만으로는
createFailed()의 REQUIRES_NEW 경계를 검증할 수 없으므로, Spring/JPA 컨텍스트를 사용하는 별도 통합 테스트를
추가하세요. 상위 트랜잭션에서 롤백이 발생하는 시나리오를 구성한 뒤에도 createFailed()의 FAILED 저장 호출이 진행되고 결과가
실제로 커밋되는지 검증하며, `@InjectMocks` 기반 테스트와 구분해 Spring 프록시를 통해 서비스를 호출하세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d9aab5e6-37a2-4f0c-960a-6b8876380b12
📒 Files selected for processing (9)
.claude/rules/git-conventions.mddocs/design/kangcheolung-#71-rag-response-save.mdsrc/main/java/com/opensource/docgrid/domain/rag/dto/OllamaGenerateResult.javasrc/main/java/com/opensource/docgrid/domain/rag/dto/response/OllamaGenerateResponse.javasrc/main/java/com/opensource/docgrid/domain/rag/repository/RagResponseRepository.javasrc/main/java/com/opensource/docgrid/domain/rag/service/OllamaClient.javasrc/main/java/com/opensource/docgrid/domain/rag/service/command/RagResponseCommandService.javasrc/test/java/com/opensource/docgrid/domain/rag/service/OllamaClientTest.javasrc/test/java/com/opensource/docgrid/domain/rag/service/command/RagResponseCommandServiceTest.java
| public interface RagResponseRepository extends JpaRepository<RagResponse, Long> { | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
새 인터페이스에 역할과 경계를 설명하는 주석을 추가해 주세요.
새로 생성된 RagResponseRepository에 class-level Javadoc가 없습니다. RagResponse의 영속화와 Spring Data 기본 CRUD만 담당한다는 역할을 짧게 명시해 주세요.
코딩 가이드의 “Every newly created class, interface, or record must have a class-level comment explaining its role, responsibility, and boundary.” 규칙에 따릅니다.
제안
+/**
+ * RAG 응답 엔티티의 영속화와 기본 CRUD를 담당하는 저장소.
+ */
public interface RagResponseRepository extends JpaRepository<RagResponse, Long> {📝 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.
| public interface RagResponseRepository extends JpaRepository<RagResponse, Long> { | |
| } | |
| /** | |
| * RAG 응답 엔티티의 영속화와 기본 CRUD를 담당하는 저장소. | |
| */ | |
| public interface RagResponseRepository extends JpaRepository<RagResponse, Long> { | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/opensource/docgrid/domain/rag/repository/RagResponseRepository.java`
around lines 7 - 8, RagResponseRepository에 class-level Javadoc를 추가해 RagResponse의
영속화와 Spring Data가 제공하는 기본 CRUD만 담당하며 그 외 비즈니스 로직은 포함하지 않는다는 역할과 경계를 간략히 설명하세요.
Source: Coding guidelines
| @ExtendWith(MockitoExtension.class) | ||
| @DisplayName("RagResponseCommandService 단위 테스트") | ||
| class RagResponseCommandServiceTest { | ||
|
|
||
| @InjectMocks | ||
| private RagResponseCommandService ragResponseCommandService; | ||
|
|
||
| @Mock | ||
| private RagResponseRepository ragResponseRepository; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate files =="
fd -a 'RagResponseCommandServiceTest.java|RagResponseCommandService.java|RagResponseRepository.java' . || true
echo "== test outline/contents =="
for f in $(fd 'RagResponseCommandServiceTest.java' .); do
echo "--- $f"
wc -l "$f"
cat -n "$f"
done
echo "== service outline/contents =="
for f in $(fd 'RagResponseCommandService.java' .); do
echo "--- $f"
wc -l "$f"
rg -n "`@Transactional`|createFailed|class RagResponseCommandService|REQUIRES_NEW" "$f" -C 3 || true
doneRepository: DocGrid/backend
Length of output: 5751
REQUIRES_NEW 트랜잭션 경계를 Spring/JPA 통합 테스트로 보완하세요.
@InjectMocks 단위는 Spring 프록시를 bypass하므로 createFailed()의 @Transactional(propagation = REQUIRES_NEW)이 현재 커버되지 않습니다. 별도 통합 테스트에서 상위 트랜잭션이 롤백되어도 FAILED 저장 호출이 진행됨을 어설션으로 보증해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/test/java/com/opensource/docgrid/domain/rag/service/command/RagResponseCommandServiceTest.java`
around lines 24 - 32, RagResponseCommandServiceTest의 Mockito 단위 테스트만으로는
createFailed()의 REQUIRES_NEW 경계를 검증할 수 없으므로, Spring/JPA 컨텍스트를 사용하는 별도 통합 테스트를
추가하세요. 상위 트랜잭션에서 롤백이 발생하는 시나리오를 구성한 뒤에도 createFailed()의 FAILED 저장 호출이 진행되고 결과가
실제로 커밋되는지 검증하며, `@InjectMocks` 기반 테스트와 구분해 Spring 프록시를 통해 서비스를 호출하세요.
Source: Path instructions
🔍️ 작업 내용
✨ 상세 설명
RAG 블록 Issue 3(F-RAG-03) 구현입니다. Issue 2(#67)에서 OllamaClient가 만든 답변 생성 결과(성공/실패)를 rag_responses 테이블에 실제로 저장합니다.
RagResponseRepository,RagResponseCommandService신규 구현createSuccess()/createFailed()— SearchQuery와 달리 단일 호출로 성공/실패가 갈리므로 PROCESSING 중간 상태 없이 한 번에 저장answer_text NOT NULL제약 때문에 실패 시에도 고정 문구("답변 생성에 실패했습니다.")를 저장하고, 실제 사유는 error_message에 담음SearchQueryCommandService.markFailed()와 동일하게@Transactional(propagation = REQUIRES_NEW)로 상위 트랜잭션 롤백과 무관하게 저장되도록 함OllamaGenerateResponse/OllamaGenerateResult(Issue 2 산출물)에model필드 추가 — rag_responses.llm_model_name을 별도 설정값 재조회 없이 Ollama 응답에서 그대로 채우기 위함상세 설계 배경은
docs/design/kangcheolung-#71-rag-response-save.md참고해주세요.🛠️ 추후 리팩토링 및 고도화 계획
📸 스크린샷 (선택)
N/A
💬 리뷰 요구사항
Summary by CodeRabbit
새 기능
문서
테스트