Skip to content

In 367 영상 상세정보 응답 수정#221

Merged
youcastle03 merged 3 commits into
developfrom
in-367-영상-상세정보-응답-수정
Jul 2, 2026

Hidden character warning

The head ref may contain hidden characters: "in-367-\uc601\uc0c1-\uc0c1\uc138\uc815\ubcf4-\uc751\ub2f5-\uc218\uc815"
Merged

In 367 영상 상세정보 응답 수정#221
youcastle03 merged 3 commits into
developfrom
in-367-영상-상세정보-응답-수정

Conversation

@youcastle03

@youcastle03 youcastle03 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Issue

closed #219


comment

  • 요구사항에 맞게 응답을 수정하였습니다
  • 필터 조건을 변경하였습니다

Summary by CodeRabbit

  • New Features

    • 채널 영상 조회에 필터 옵션이 추가되어, 상위 영상과 신규 구독자 영상 목록을 더 세밀하게 볼 수 있습니다.
    • 채널별 영상 통계에서 평균값과 변동률을 함께 확인할 수 있도록 개선되었습니다.
  • Bug Fixes

    • 통계 값이 비어 있거나 누락된 경우에도 더 안정적으로 처리되도록 보완했습니다.
    • 일부 조회에서 반환되던 오류 기준을 최신 기준으로 정리했습니다.

@youcastle03 youcastle03 self-assigned this Jul 2, 2026
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

채널 상위/신규구독 영상 조회 API의 파라미터가 contentType에서 선택적 filter로 변경되고, 채널 서비스에 parseFilter 헬퍼가 추가되었다. 영상 통계 응답의 changeRate 계산이 채널 평균(VideoStatsChannelAverages) 기반으로 재구성되었고, retention 관련 예외가 RETENTION_NOT_FOUND에서 ANALYTICS_DATA_NOT_FOUND로 통합되었다.

Changes

채널 영상 filter 파라미터

Layer / File(s) Summary
Controller/API filter 파라미터 도입
ChannelApi.java, ChannelController.java
getTopVideos, getNewSubscriberVideos가 contentType 대신 선택적 filter 쿼리 파라미터를 받도록 변경, 서비스 호출부에 filter 전달.
ChannelService parseFilter 및 조회 로직
ChannelService.java
기존 valueOf 파싱을 제거하고 공통 parseFilter(filter) 헬퍼로 VideoType을 결정, null/공백 시 LONG_FORM 기본값, 잘못된 값이면 INVALID_ARGUMENT 예외.
신규구독 영상 조회 isShort 필터링
VideoRepository.java
findTopNewSubscriberVideos 쿼리에 isShort 조건 및 파라미터 추가.

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

영상 통계 평균 및 retention 예외 통합

Layer / File(s) Summary
채널 평균 DTO 및 저장소 쿼리
VideoStatsChannelAverages.java, VideoStatsRepository.java
채널 단위 통계 평균을 담는 record DTO 신설, 이를 반환하는 findChannelAverages JPQL 쿼리 메서드 추가.
VideoStatsResponse changeRate 계산 및 VideoService 연동
VideoStatsResponse.java, VideoService.java
from(...) 시그니처를 averages 기반으로 변경하고 changeRate 계산 로직 추가, VideoService.getVideoStats가 평균을 조회하여 전달, validateVideoStatsAnalytics 제거.
Retention 예외 코드 통합 및 safeDoubleValue 적용
ErrorDefine.java, VideoApi.java, VideoService.java, RetentionSummaryResponse.java, AnalyticsParser.java, VideoServiceTest.java
RETENTION_NOT_FOUND 제거 및 ANALYTICS_DATA_NOT_FOUND로 대체, Double 오버로드 safeDoubleValue 추가 및 RetentionSummaryResponse 적용.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ChannelController
  participant ChannelService
  Client->>ChannelController: GET /tops?filter=SHORT
  ChannelController->>ChannelService: getTopVideos(channelId, filter)
  ChannelService->>ChannelService: parseFilter(filter)
  ChannelService-->>ChannelController: ChannelTopVideosResponse
  ChannelController-->>Client: BaseResponse
Loading
sequenceDiagram
  participant VideoService
  participant VideoStatsRepository
  participant VideoStatsResponse
  VideoService->>VideoStatsRepository: findChannelAverages(channelId)
  VideoStatsRepository-->>VideoService: VideoStatsChannelAverages
  VideoService->>VideoStatsResponse: from(stats, analytics, averages)
  VideoStatsResponse->>VideoStatsResponse: changeRate(value, average)
  VideoStatsResponse-->>VideoService: VideoStatsResponse
Loading

Possibly related PRs

Poem

필터 하나 살랑살랑, 토끼 귀 쫑긋 세워
RETENTION 이름표는 이제 안녕~ 잘 가
평균값 들고서 changeRate 콩콩 뛰네
🥕 굴 속 코드도 깔끔하게 정돈했어요
폴짝폴짝, 리뷰어님 즐거운 리뷰 되세요!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 영상 상세정보 응답 수정이라는 핵심 변경을 간결하게 요약합니다.
Linked Issues check ✅ Passed [#219] 영상 상세정보 응답 수정, 필터 변경, retention 0 처리 개선이 이슈 요구와 일치합니다.
Out of Scope Changes check ✅ Passed 필터·응답·retention 관련 변경만 보이며, 이슈 #219 범위를 벗어나는 별도 기능 추가는 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch in-367-영상-상세정보-응답-수정

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.

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/main/java/com/example/inflace/domain/video/dto/VideoStatsResponse.java (1)

30-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

changeRate 계산식은 DTO 밖으로 옮기는 게 좋겠습니다.

VideoStatsResponse가 응답 조립을 넘어 채널 평균 대비 증감률 계산 규칙까지 갖게 됐습니다. 최소한 계산식은 AnalyticsCalculator로 이동하고, DTO는 값 포장만 담당하게 해주세요. Based on learnings, DTOs under dto/ packages should remain pure data carriers and business/validation logic should live in services.

🤖 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/example/inflace/domain/video/dto/VideoStatsResponse.java`
around lines 30 - 69, `VideoStatsResponse` is doing business logic by
calculating change rates in `changeRate`, so move that percentage calculation
into `AnalyticsCalculator` and keep the DTO focused on assembling `StatValue`
objects. Update `VideoStatsResponse.from(...)` to call the shared calculator
method for each average-based change rate, and remove the local `changeRate`
helper so the DTO remains a pure data carrier.

Source: Learnings

🤖 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/example/inflace/domain/video/repository/VideoStatsRepository.java`:
- Around line 16-39: The aggregate query in VideoStatsRepository is treating
missing VideoStats and VideoAnalytics rows as zero by using coalesce(...) inside
the averages, which pulls incomplete videos into the channel metrics; update the
`@Query` in VideoStatsRepository so averages ignore null stats instead of
defaulting them to 0, and only apply default values when mapping the result into
VideoStatsChannelAverages or another response-layer DTO. Keep the ratio
expressions in the same query but ensure the Video and left-joined vs/va fields
used there are handled in a way that excludes absent stats from the averages.

---

Nitpick comments:
In `@src/main/java/com/example/inflace/domain/video/dto/VideoStatsResponse.java`:
- Around line 30-69: `VideoStatsResponse` is doing business logic by calculating
change rates in `changeRate`, so move that percentage calculation into
`AnalyticsCalculator` and keep the DTO focused on assembling `StatValue`
objects. Update `VideoStatsResponse.from(...)` to call the shared calculator
method for each average-based change rate, and remove the local `changeRate`
helper so the DTO remains a pure data carrier.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c5eb99df-66df-4958-8dc1-40cbf79d04b8

📥 Commits

Reviewing files that changed from the base of the PR and between 79afeb0 and 07d2bfc.

📒 Files selected for processing (13)
  • src/main/java/com/example/inflace/domain/channel/controller/ChannelApi.java
  • src/main/java/com/example/inflace/domain/channel/controller/ChannelController.java
  • src/main/java/com/example/inflace/domain/channel/service/ChannelService.java
  • src/main/java/com/example/inflace/domain/video/controller/VideoApi.java
  • src/main/java/com/example/inflace/domain/video/dto/RetentionSummaryResponse.java
  • src/main/java/com/example/inflace/domain/video/dto/VideoStatsChannelAverages.java
  • src/main/java/com/example/inflace/domain/video/dto/VideoStatsResponse.java
  • src/main/java/com/example/inflace/domain/video/repository/VideoRepository.java
  • src/main/java/com/example/inflace/domain/video/repository/VideoStatsRepository.java
  • src/main/java/com/example/inflace/domain/video/service/VideoService.java
  • src/main/java/com/example/inflace/global/exception/ErrorDefine.java
  • src/main/java/com/example/inflace/global/util/AnalyticsParser.java
  • src/test/java/com/example/inflace/domain/video/service/VideoServiceTest.java

Comment on lines +16 to +39
@Query("""
select new com.example.inflace.domain.video.dto.VideoStatsChannelAverages(
avg(coalesce(vs.viewCount, 0)),
avg(coalesce(vs.likeCount, 0)),
avg(coalesce(vs.commentCount, 0)),
avg(coalesce(va.shareCount, 0)),
avg(coalesce(va.subscribersGained, 0)),
avg(coalesce(va.avgWatchDuration, 0.0)),
avg(case
when coalesce(vs.viewCount, 0) = 0 then 0.0
else ((coalesce(vs.likeCount, 0) + coalesce(vs.commentCount, 0)) * 100.0 / vs.viewCount)
end),
avg(case
when coalesce(vs.viewCount, 0) = 0 then 0.0
else (coalesce(va.unsubscribedViewCount, 0) * 100.0 / vs.viewCount)
end),
avg(coalesce(vs.outlierScore, 0.0)),
avg(coalesce(vs.vph, 0.0))
)
from Video v
left join VideoStats vs on vs.video = v
left join VideoAnalytics va on va.video = v
where v.channel.id = :channelId
""")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 결측 VideoStats/VideoAnalytics가 있는 채널 평균 테스트가 있는지 확인합니다.
rg -n "findChannelAverages|VideoStatsChannelAverages|avg\\(coalesce|missing.*analytics|missing.*stats" src/main/java src/test/java

Repository: JECT-Study/inflace-4th-server

Length of output: 2298


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' src/main/java/com/example/inflace/domain/video/repository/VideoStatsRepository.java
printf '\n---\n'
sed -n '1,220p' src/main/java/com/example/inflace/domain/video/dto/VideoStatsChannelAverages.java
printf '\n---\n'
sed -n '1,220p' src/main/java/com/example/inflace/domain/video/dto/VideoStatsResponse.java
printf '\n---\n'
sed -n '1,220p' src/main/java/com/example/inflace/domain/video/service/VideoService.java
printf '\n---\n'
rg -n "findChannelAverages|VideoStatsChannelAverages|changeRate|avg\\(coalesce|coalesce\\(avg" src/test/java src/main/java

Repository: JECT-Study/inflace-4th-server

Length of output: 16663


결측 통계는 평균에서 제외하세요. left join된 영상에 coalesce(..., 0)를 적용하면 VideoStats/VideoAnalytics가 아직 없는 영상도 0으로 채널 평균에 섞여 changeRate가 실제보다 낮아집니다. 평균은 null을 무시하도록 계산하고, 0 기본값은 응답 단계에서만 채우는 편이 안전합니다.

🤖 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/example/inflace/domain/video/repository/VideoStatsRepository.java`
around lines 16 - 39, The aggregate query in VideoStatsRepository is treating
missing VideoStats and VideoAnalytics rows as zero by using coalesce(...) inside
the averages, which pulls incomplete videos into the channel metrics; update the
`@Query` in VideoStatsRepository so averages ignore null stats instead of
defaulting them to 0, and only apply default values when mapping the result into
VideoStatsChannelAverages or another response-layer DTO. Keep the ratio
expressions in the same query but ensure the Video and left-joined vs/va fields
used there are handled in a way that excludes absent stats from the averages.

@HanYoonSoo HanYoonSoo 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.

좋습니다! 고생많으셨어요!

@youcastle03
youcastle03 merged commit 6841397 into develop Jul 2, 2026
3 checks passed
@youcastle03
youcastle03 deleted the in-367-영상-상세정보-응답-수정 branch July 2, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IN-367 영상 상세정보 응답 수정

2 participants