Skip to content

[✨Feat] 최신 키워드 분석 조회 API 구현#59

Merged
yong203 merged 2 commits into
devfrom
feat/#58
Jul 5, 2026
Merged

[✨Feat] 최신 키워드 분석 조회 API 구현#59
yong203 merged 2 commits into
devfrom
feat/#58

Conversation

@yong203

@yong203 yong203 commented Jul 5, 2026

Copy link
Copy Markdown
Member

작업 내용

  • GET /cover-letters/{coverLetterId}/keyword-analysis/latest API를 추가했습니다.
  • API-021 응답을 화면에 필요한 최소 정보인 statuskeywords만 반환하도록 정리했습니다.
    • 분석 이력이 없으면 status: NOT_STARTED, keywords: []
    • 진행 중이면 status: PROCESSING, keywords: []
    • 완료되면 status: COMPLETED, keywords: [...]
    • 실패하면 status: FAILED, keywords: []
  • KeywordAnalysisKeyword entity/repository를 추가해 완료된 키워드 결과를 keyword_order 기준으로 조회할 수 있게 했습니다.
  • 실패 원인 상세는 KeywordAnalysis가 아니라 기존 LlmJob 책임으로 유지하고, API-021 응답과 keyword_analyses에는 error 필드를 두지 않도록 정리했습니다.
  • API-021 문서, docs/status.md를 구현 상태와 맞췄습니다.

관련 이슈

문서 반영

  • 반영한 문서:
    • docs/api/README.md
    • docs/api/keyword-analysis.md
    • docs/status.md

확인 결과

  • ./gradlew test
  • ./gradlew check
  • 기타: git diff --check, ./gradlew test --tests '*KeywordAnalysisControllerTest', ./gradlew test --tests '*KeywordAnalysis*'
  • 실행하지 못함. 이유:

Summary by CodeRabbit

  • New Features

    • 최신 키워드 분석 결과를 조회할 수 있는 API가 추가되었습니다.
    • 분석 상태와 키워드 목록을 함께 확인할 수 있으며, 완료된 경우에만 결과 키워드가 표시됩니다.
  • Bug Fixes

    • 분석이 아직 시작되지 않았거나 진행/실패 상태인 경우에도 더 일관된 응답 형태로 반환됩니다.
    • 키워드가 저장된 경우 표시 순서가 안정적으로 유지됩니다.

@yong203 yong203 linked an issue Jul 5, 2026 that may be closed by this pull request
7 tasks
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

키워드 분석 결과를 조회하는 GET /cover-letters/{coverLetterId}/keyword-analysis/latest API가 추가되었습니다. KeywordAnalysisKeyword 엔티티/리포지토리, KeywordAnalysiscomplete/fail 상태 전환 메서드, LatestKeywordAnalysisResult/LatestKeywordAnalysisResponse, 서비스 로직, 컨트롤러 엔드포인트, 테스트 및 관련 문서가 추가/갱신되었습니다.

Changes

최신 키워드 분석 조회 API

Layer / File(s) Summary
키워드 저장 엔티티/리포지토리
.../entity/KeywordAnalysisKeyword.java, .../repository/KeywordAnalysisKeywordRepository.java, src/test/.../repository/KeywordAnalysisKeywordRepositoryTest.java
keyword_analysis_keywords 테이블에 매핑되는 엔티티(유니크 제약, 팩토리 메서드 포함)와 keywordOrder 오름차순 조회 리포지토리가 추가되고 관련 JPA 테스트가 추가됨.
분석 상태 전환
.../entity/KeywordAnalysis.java, src/test/.../repository/KeywordAnalysisRepositoryTest.java
complete(Instant)/fail(Instant) 메서드가 statuscompletedAt을 갱신하도록 추가되고, FAILED 상태 round-trip 테스트가 추가됨.
최신 결과 조회 서비스
.../service/LatestKeywordAnalysisResult.java, .../service/KeywordAnalysisService.java, src/test/.../service/KeywordAnalysisServiceTest.java
LatestKeywordAnalysisResult 레코드와 findMyLatestKeywordAnalysis 메서드가 추가되어 소유자/삭제 검증 후 분석 및 정렬된 키워드를 반환하고, 서비스 테스트가 확장됨.
응답 DTO/컨트롤러 엔드포인트
.../dto/LatestKeywordAnalysisResponse.java, .../controller/KeywordAnalysisController.java, src/test/.../controller/KeywordAnalysisControllerTest.java
LatestKeywordAnalysisResponse.from(...)가 status/keywords를 매핑하고, /latest GET 엔드포인트가 추가되며, 상태별/404 컨트롤러 테스트가 추가됨.
문서 갱신
docs/api/README.md, docs/api/keyword-analysis.md, docs/status.md
API-021 상태가 Implemented로 갱신되고, 응답 예시가 status/keywords 기반으로 재정의되며, 로드맵/다음 이슈 후보가 갱신됨.

Possibly related PRs

  • Rewrite-Team/Rewrite-BE#57: 동일한 KeywordAnalysis/KeywordAnalysisService 도메인의 시작/재분석 구현 위에 최신 조회 기능이 이어짐.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 링크된 이슈는 wrapper 구조와 errorCode/errorMessage 저장을 요구하지만, 변경사항은 status/keywords만 반환해 요구사항과 다릅니다. API-021 응답을 {coverLetterId, keywordAnalysis} wrapper로 맞추고, KeywordAnalysis에 nullable errorCode/errorMessage를 추가한 뒤 FAILED 응답을 그 값으로 구성하세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 최신 키워드 분석 조회 API 구현이라는 핵심 변경을 간결하게 잘 설명합니다.
Description check ✅ Passed 작업 내용, 관련 이슈, 문서 반영, 확인 결과 섹션이 모두 있어 템플릿을 충족합니다.
Out of Scope Changes check ✅ Passed 변경은 API-021, 관련 문서, 엔티티/리포지토리/테스트에 집중되어 있어 범위를 벗어난 수정은 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

Backend CI Report

Item Result
Tests ✅ Passed
JaCoCo line coverage 95.69% (1109/1159 lines)
Coverage report ✅ Generated
Codecov upload ✅ Uploaded

View workflow run | View coverage details

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@yong203 yong203 marked this pull request as ready for review July 5, 2026 11:00
@yong203 yong203 self-assigned this Jul 5, 2026
@yong203 yong203 added the ✨ Feature 새로운 기능 구현 label Jul 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/java/com/daon/rewrite/keywordanalysis/dto/LatestKeywordAnalysisResponse.java (1)

15-25: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

내부 enum 이름을 API 응답 문자열로 직접 노출

result.keywordAnalysis().getStatus().name()을 그대로 응답 status로 사용하고 있습니다. 현재는 KeywordAnalysisStatusPROCESSING/COMPLETED/FAILED만 가지고 있어 문제없지만, 이 방식은 내부 엔티티 enum과 외부 API 계약을 암묵적으로 결합시킵니다. 추후 enum 값이 리네임되거나 새로운 상태가 추가되면 API 응답 문자열이 의도치 않게 변경/누출될 수 있습니다. NOT_STARTED_STATUS처럼 명시적으로 매핑하는 편이 계약 안정성 측면에서 더 안전합니다.

♻️ 명시적 상태 매핑 예시
     public static LatestKeywordAnalysisResponse from(LatestKeywordAnalysisResult result) {
         if (result.keywordAnalysis() == null) {
             return new LatestKeywordAnalysisResponse(NOT_STARTED_STATUS, List.of());
         }
         return new LatestKeywordAnalysisResponse(
-                result.keywordAnalysis().getStatus().name(),
+                toStatus(result.keywordAnalysis().getStatus()),
                 result.keywords().stream()
                         .map(KeywordResponse::from)
                         .toList()
             );
     }
+
+    private static String toStatus(KeywordAnalysisStatus status) {
+        return switch (status) {
+            case PROCESSING -> "PROCESSING";
+            case COMPLETED -> "COMPLETED";
+            case FAILED -> "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/main/java/com/daon/rewrite/keywordanalysis/dto/LatestKeywordAnalysisResponse.java`
around lines 15 - 25, The LatestKeywordAnalysisResponse.from mapping is leaking
the internal KeywordAnalysisStatus enum name directly into the API response.
Update the status conversion in LatestKeywordAnalysisResponse.from so it uses an
explicit mapping from result.keywordAnalysis().getStatus() to the outward-facing
status string, similar to NOT_STARTED_STATUS, instead of calling name() on the
enum. Keep the keyword list mapping unchanged.
🤖 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.

Nitpick comments:
In
`@src/main/java/com/daon/rewrite/keywordanalysis/dto/LatestKeywordAnalysisResponse.java`:
- Around line 15-25: The LatestKeywordAnalysisResponse.from mapping is leaking
the internal KeywordAnalysisStatus enum name directly into the API response.
Update the status conversion in LatestKeywordAnalysisResponse.from so it uses an
explicit mapping from result.keywordAnalysis().getStatus() to the outward-facing
status string, similar to NOT_STARTED_STATUS, instead of calling name() on the
enum. Keep the keyword list mapping unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 244beae6-86f7-4ad0-8fbf-9fad091d93aa

📥 Commits

Reviewing files that changed from the base of the PR and between ff3cb79 and af43eeb.

📒 Files selected for processing (14)
  • docs/api/README.md
  • docs/api/keyword-analysis.md
  • docs/status.md
  • src/main/java/com/daon/rewrite/keywordanalysis/controller/KeywordAnalysisController.java
  • src/main/java/com/daon/rewrite/keywordanalysis/dto/LatestKeywordAnalysisResponse.java
  • src/main/java/com/daon/rewrite/keywordanalysis/entity/KeywordAnalysis.java
  • src/main/java/com/daon/rewrite/keywordanalysis/entity/KeywordAnalysisKeyword.java
  • src/main/java/com/daon/rewrite/keywordanalysis/repository/KeywordAnalysisKeywordRepository.java
  • src/main/java/com/daon/rewrite/keywordanalysis/service/KeywordAnalysisService.java
  • src/main/java/com/daon/rewrite/keywordanalysis/service/LatestKeywordAnalysisResult.java
  • src/test/java/com/daon/rewrite/keywordanalysis/controller/KeywordAnalysisControllerTest.java
  • src/test/java/com/daon/rewrite/keywordanalysis/repository/KeywordAnalysisKeywordRepositoryTest.java
  • src/test/java/com/daon/rewrite/keywordanalysis/repository/KeywordAnalysisRepositoryTest.java
  • src/test/java/com/daon/rewrite/keywordanalysis/service/KeywordAnalysisServiceTest.java

@yong203 yong203 merged commit 68a8456 into dev Jul 5, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[✨Feat] 최신 키워드 분석 조회 API 구현

1 participant