Skip to content

[FEAT] 히스토리 목록/상세 조회 API 구현 - #52

Merged
ownue merged 8 commits into
developfrom
feat/#29-history-api
Jul 26, 2026
Merged

[FEAT] 히스토리 목록/상세 조회 API 구현#52
ownue merged 8 commits into
developfrom
feat/#29-history-api

Conversation

@ownue

@ownue ownue commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

📍 개요

히스토리 목록/상세 조회 API 구현

⛓️‍💥 관련 이슈


🛠️ 작업 내용

  • 히스토리 목록/상세 조회 API 구현 (GET /api/histories, GET /api/histories/{playingId})
  • 히스토리 조회용 PlayingRepository 신설 및 AnalysisRepository 배치 조회 메서드 추가
  • 파라미터 타입 불일치 시 500 대신 400을 반환하도록 전역 예외 처리 추가

🔥 리뷰 요청 사항

리뷰어가 중점적으로 확인해주었으면 하는 내용을 작성해주세요.

  • 예외 코드 체계 (HISTORY_400_01/400_02/403_01/404_01/409_01) 부여가 적절한지
  • Analysis가 unlinked 컬럼(FK 아님)이라 소유권을 쿼리 조건으로 방어한 방식이 충분한지 (추후 별도 이슈에서 FK로 연결 후 변경 예정)
  • 목록의 scoreChange를 같은 페이지 내 인접 항목끼리만 비교하도록 단순화한 게 괜찮은지
  • AUTO_STOPPED 상태 연주는 지금 히스토리에서 계속 제외되는데, 히스토리에 정확히 어떤 상태값을 남기면 될지/지금처럼 유지해도 되는지

✅ 체크리스트

  • 코드 컨벤션을 준수했습니다.
  • 불필요한 코드 및 import를 제거했습니다.
  • 예외 처리를 적용했습니다.
  • 테스트를 완료했습니다.
  • 관련 Issue를 연결했습니다.

📎 참고 사항

  • totalBars, estimatedSeconds는 현재 저장된 소스가 없어 null로 반환하고 있습니다! totalBarsplaytimeSec/bpm으로 추정 계산도 가능하다고 하는데, 정확도 이슈가 있어 넣을지는 논의 후 결정할 예정입니다. 디스코드에 스레드를 파두었으니 확인 후 답변 부탁드립니다...!
  • Analysis.userId/playingId를 실제 FK로 전환하는 작업은 이번 PR 범위 밖이라 별도 이슈로 분리할 예정입니다. 대신 이번 PR에서는 조회 쿼리에 userId 조건을 직접 걸어 방어 처리를 했습니다.
  • 같은 구간을 재분석할 수 있나요? 가능하다면 상세 조회에서 구간별 최신 1건만 보여줄지/전부 보여줄지 논의해야 할 것 같습니당....

Summary by CodeRabbit

  • 새 기능
    • 히스토리 조회/상세 조회 API를 추가하고, 주간·월간·최근 기간별로 완료된 기록을 페이지 단위로 필터링합니다.
    • 목록에는 최신 분석/점수 변화/재생 시간/상대 날짜를, 상세에는 제목·장르·키·미디 이벤트 및 분석 요약을 제공합니다.
  • 개선
    • 잘못된 파라미터 타입(형식) 불일치에 대해 일관된 오류 응답을 추가했습니다.

@ownue ownue self-assigned this Jul 25, 2026
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ownue, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9ec38432-07d0-4430-98e3-75e66c8822e6

📥 Commits

Reviewing files that changed from the base of the PR and between 5c6366a and fe439ae.

📒 Files selected for processing (1)
  • src/main/java/com/mr/domain/history/dto/res/HistoryDetailResponseDTO.java
📝 Walkthrough

Walkthrough

사용자의 완료된 연습 기록을 기간별·페이지별로 조회하는 목록 API와 특정 기록의 분석 결과를 조회하는 상세 API가 추가되었습니다. 저장소 쿼리, 응답 DTO, 검증·예외 처리 및 서비스·컨트롤러 테스트가 함께 구현되었습니다.

Changes

히스토리 조회 기능

Layer / File(s) Summary
조회 계약과 저장소
src/main/java/com/mr/domain/history/dto/..., src/main/java/com/mr/domain/history/exception/HistoryErrorStatus.java, src/main/java/com/mr/domain/playing/repository/PlayingRepository.java, src/main/java/com/mr/domain/analysis/repository/AnalysisRepository.java
기간 enum, 오류 상태, 목록·상세 응답 DTO와 완료 재생·분석 조회 쿼리가 추가되었습니다.
히스토리 서비스 흐름
src/main/java/com/mr/domain/history/service/HistoryService.java
기간 컷오프, 페이지네이션, 최신 분석, 점수 변화, 상대 날짜, 상세 조회의 소유권·완료 상태 검증을 처리합니다.
HTTP 엔드포인트와 예외 응답
src/main/java/com/mr/domain/history/controller/HistoryController.java, src/main/java/com/mr/global/apipayload/handler/GlobalExceptionHandler.java
인증 사용자 기준의 목록·상세 API를 제공하고 타입 불일치 요청을 공통 오류 응답으로 변환합니다.
조회 동작 검증
src/test/java/com/mr/domain/history/...
서비스와 컨트롤러의 성공, 입력 오류, 권한 없음, 미존재, 미완료 상태 및 분석 조합 동작을 검증합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant HistoryController
  participant HistoryService
  participant Repositories
  Client->>HistoryController: GET /api/histories
  HistoryController->>HistoryService: 사용자 ID와 조회 조건 전달
  HistoryService->>Repositories: 완료 Playing 및 Analysis 조회
  Repositories-->>HistoryService: 페이징 재생 기록과 최신 분석
  HistoryService-->>HistoryController: HistoryListResponseDTO
  HistoryController-->>Client: 성공 응답
Loading

Possibly related PRs

  • Musereview/BE#44: AnalysisRepository의 분석 상태·정렬 기반 조회 메서드가 이번 히스토리 조회 흐름과 연결됩니다.

Poem

기록의 문이 열리고
지난 연주가 줄을 서네
분석은 최신으로 반짝,
점수 차도 살짝 춤추고
히스토리 API, 출발! 🎵

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 히스토리 목록/상세 조회 API 구현이라는 핵심 변경을 정확히 요약합니다.
Linked Issues check ✅ Passed 목록/상세 API, DTO, 저장소, 권한 검증, 페이징, 정렬, 예외 처리까지 갖춰져 있어 #29 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 예외 처리와 테스트를 포함해 히스토리 API 구현 범위에 맞는 변경만 보입니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#29-history-api

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.

❤️ Share

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

@p1001q p1001q left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

은우님 리뷰 요청 답변

1. 에러코드 체계(HISTORY_400_01/02, 403_01, 404_01, 409_01) 적절한지
→ 문제없어요. 5개 다 실제로 throw되고 있고(제가 지난번 리뷰한 PR들은 정의만 해두고 안 쓰는 경우가 많았는데 이건 전부 연결돼있음), HTTP 상태도 상황에 맞게 잘 골랐어요(권한 없음=403, 완료 안 됨=409로 구분한 것도 적절).

2. Analysis 소유권 쿼리 조건 방어가 충분한지
→ 충분해 보여요. Playing.user는 진짜 FK 관계라 validateOwner()에서 먼저 확실하게 걸러지고, 그 다음 Analysis 쿼리의 userId 조건은 "혹시 모를 데이터 불일치에 대한 추가 방어"라 최악의 경우에도 "있어야 할 분석이 안 보이는" 방향이지 "남의 데이터가 새는" 방향은 아니에요. FK 연결 전까지는 이 정도면 안전한 선택이라고 봐요.

3. scoreChange 같은 페이지 내 인접 비교만 하는 게 괜찮은지
→ 기능적으로는 문제없지만 UX적으로 좀 애매한 지점이 있어요: 페이지의 마지막 항목은 실제로는 이전 기록이 있어도(다음 페이지에) 항상 scoreChange: null로 나가요. 페이지 경계가 실제 데이터랑 무관한 곳에서 정보 누락을 만드는 셈이라, 사용자 입장에선 "왜 이 항목만 변화량이 안 보이지" 싶을 수 있어요. 당장 문제는 아니니 이대로 가도 되지만, 나중에 필요하면 size+1개를 조회해서 마지막 항목 비교용으로만 쓰고 응답에선 빼는 방식으로 개선할 수 있어요.

4. AUTO_STOPPED 히스토리 노출 방식
→ 이건 순수 프로덕트 결정이라 디스코드 스레드에서 피엠님과 논의해보는 거 어떤가용

승인해드렸습니다! 수고 많으셨어용
리뷰한 것중에 엉터리 리뷰가 있다면 편하게 무시해주세요 ㄱ ㅡ...

Comment thread src/main/java/com/mr/domain/playing/repository/PlayingRepository.java Outdated
Comment thread src/main/java/com/mr/domain/history/service/HistoryService.java Outdated
Comment thread src/main/java/com/mr/domain/history/service/HistoryService.java

@rkdehdrbs7885-oss rkdehdrbs7885-oss left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

수고하셨습니다!

- HistoryPeriod.RECENT 케이스에 정보성 주석 추가
- relativeDate를 피그마 명세대로 수정
- durationSec을 목록/상세 응답에 추가
@ownue

ownue commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

수연님 리뷰 중 3 / 4 관련

-> 3은 UX적 문제가 있는 것은 확인했으나 디벨롭 기간에 진행하는 게 나을 듯해 (시간 이슈...^^) 서브 이슈로 관리하겠습니다.

-> 4는 별도 스레드 파서 논의 후 수정할 점이 생기면 반영하겠습니다.

ownue added 2 commits July 26, 2026 12:57
- develop 브랜치 반영이 늦어 생긴 오류라 merge 후 필드명 수정
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Feature - 히스토리 목록 및 상세 조회 API 구현

3 participants