Skip to content

[REFACTOR] 사용자 및 주간 통계 집계 책임 분리 - #256

Merged
ownue merged 1 commit into
developfrom
refactor/#246-statistics-aggregation-service
Sep 10, 2026
Merged

ownue merged 1 commit into
developfrom
refactor/#246-statistics-aggregation-service

Conversation

@ownue

@ownue ownue commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

📍 개요

사용자 누적 통계, 주간 연습 통계, 주간 스킬 통계의 집계 책임 분리 및 전체 집계 서비스를 orchestration 중심으로 정리

⛓️‍💥 관련 이슈


🛠️ 작업 내용

  • 사용자 누적 통계 집계 책임을 UserStatisticsAggregationService로 분리
  • 주간 연습 통계 집계 책임을 WeeklyPracticeStatisticsAggregationService로 분리
  • 주간 스킬 통계 집계 책임을 WeeklySkillStatisticsAggregationService로 분리
  • StatisticsAggregationService가 이벤트별 집계 순서만 제어하도록 변경
  • 각 통계 집계 서비스가 실제로 사용하는 Repository만 의존하도록 조정
  • 기존 REQUIRES_NEW 트랜잭션 경계와 Listener 재시도 정책 유지
  • 기존 집계 결과 회귀 테스트 유지 및 이벤트별 orchestration 테스트 추가

🔥 리뷰 요청 사항

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

  • 통계별 책임과 Repository 의존성이 적절하게 분리되었는지
  • 하위 집계 서비스가 기존 REQUIRES_NEW 트랜잭션에 참여하여 이벤트 단위 원자성이 유지되는지
  • 연주 완료 및 분석 완료 이벤트별 집계 호출 순서가 기존 동작과 동일한지

✅ 체크리스트

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

📎 참고 사항

  • StatisticsAggregationServiceTest에서 사용자 누적 통계, 주간 연습 통계, 주간 스킬 통계의 기존 집계 결과를 검증합니다.
  • StatisticsAggregationOrchestrationTest에서 연주 완료 및 분석 완료 이벤트별 집계 대상과 호출 순서를 검증합니다.
  • StatisticsEventListenerRetryTest에서 DataIntegrityViolationException 발생 시 최대 3회 재시도 및 Recover 동작을 검증합니다.

Summary by CodeRabbit

  • 새로운 기능

    • 사용자 누적 통계 집계를 지원합니다.
    • 주간 연습 통계를 집계하고 총 연습 시간, 완료 세션 수, 평균 분석 점수를 반영합니다.
    • 주간 스킬별 평균 점수를 집계하고 이전 주 통계를 활용합니다.
    • 연주 및 분석 완료 시 관련 통계가 자동으로 갱신됩니다.
  • 테스트

    • 연주·분석 완료 시 통계 집계 순서와 대상이 올바른지 검증하는 테스트를 추가했습니다.

@ownue ownue self-assigned this Sep 10, 2026
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: c4d7c0f6-3bd6-4429-a8eb-eec23052ae64

📥 Commits

Reviewing files that changed from the base of the PR and between 5ca0e51 and 7a6d489.

📒 Files selected for processing (6)
  • src/main/java/com/mr/domain/statistics/service/StatisticsAggregationService.java
  • src/main/java/com/mr/domain/statistics/service/UserStatisticsAggregationService.java
  • src/main/java/com/mr/domain/statistics/service/WeeklyPracticeStatisticsAggregationService.java
  • src/main/java/com/mr/domain/statistics/service/WeeklySkillStatisticsAggregationService.java
  • src/test/java/com/mr/domain/statistics/service/StatisticsAggregationOrchestrationTest.java
  • src/test/java/com/mr/domain/statistics/service/StatisticsAggregationServiceTest.java

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

통계 집계 책임을 세 개의 서비스로 분리했다. 사용자 누적 통계와 주간 연습·스킬 통계를 각각 집계한다. StatisticsAggregationService는 이벤트별 호출 순서만 조정한다. 오케스트레이션 테스트를 추가했다.

Changes

통계 집계 책임 분리

Layer / File(s) Summary
사용자 누적 통계 집계
src/main/java/com/mr/domain/statistics/service/UserStatisticsAggregationService.java
완료된 연습과 분석 데이터를 집계한다. 사용자 통계가 없으면 생성한다. 사용자가 없으면 USER_NOT_FOUND 예외를 발생시킨다.
주간 연습 통계 집계
src/main/java/com/mr/domain/statistics/service/WeeklyPracticeStatisticsAggregationService.java
한국 시간 기준 주간 데이터를 조회한다. 연습 시간, 세션 수, 평균 분석 점수를 계산해 주간 통계를 생성하거나 갱신한다.
주간 스킬 통계 집계
src/main/java/com/mr/domain/statistics/service/WeeklySkillStatisticsAggregationService.java
완료된 분석을 스킬별로 집계한다. 현재 주간 통계를 갱신하거나 이전 주 점수를 포함해 새 통계를 저장한다.
집계 오케스트레이션과 검증
src/main/java/com/mr/domain/statistics/service/StatisticsAggregationService.java, src/test/java/com/mr/domain/statistics/service/*
상위 서비스가 세부 집계 서비스를 이벤트별 순서로 호출한다. 연주 완료 시 스킬 통계를 호출하지 않는 동작과 분석 완료 시 세 통계 호출 순서를 검증한다.

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

Merge Risk: ⚪ Minimal · up to 7a6d4

통계 집계 책임이 사용자 누적 및 주간 통계 서비스로 분리되었으며, 이벤트별 집계 순서와 기존 집계 동작이 유지됩니다. 현재 확인된 병합 차단 위험은 없습니다.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 25 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive [ #246 ] 사용자 통계, 주간 연습 통계, 주간 스킬 통계의 서비스 분리와 orchestration 중심 구조는 반영되었습니다. Repository 의존성도 통계별 서비스로 축소되었습니다. 그러나 기존 REQUIRES_NEW 트랜잭션 경계와 Listener 재시도 정책이 유지되었다는 근거가 없습니다. 기존 집계 결과의 회귀를 검증하는 테스트도 요약상 … 각 집계 서비스 또는 적절한 호출 경계에 기존 REQUIRES_NEW 설정이 유지되었는지 확인하고, Listener 재시도 설정을 검증하세요. 기존 집계 결과와 동일함을 검증하는 사용자 누적·주간 연습·주간 스킬 통계 테스트를 추가하거나 결과를 제시하세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed 변경된 서비스와 테스트는 모두 통계 집계 책임 분리 및 orchestration 검증이라는 [ #246 ]의 범위에 포함됩니다. 성능 개선이나 무관한 기능 변경은 확인되지 않습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 사용자 누적 통계와 주간 통계 집계 책임을 별도 서비스로 분리하는 핵심 변경을 정확히 요약합니다. 변경 목적과 범위가 명확합니다.
Full details: Linked Issues check

Explanation

[ #246 ] 사용자 통계, 주간 연습 통계, 주간 스킬 통계의 서비스 분리와 orchestration 중심 구조는 반영되었습니다. Repository 의존성도 통계별 서비스로 축소되었습니다. 그러나 기존 REQUIRES_NEW 트랜잭션 경계와 Listener 재시도 정책이 유지되었다는 근거가 없습니다. 기존 집계 결과의 회귀를 검증하는 테스트도 요약상 충분하지 않습니다.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#246-statistics-aggregation-service

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.

LocalDate weekStart = Instant.now(clock).atZone(KOREA_ZONE_ID).toLocalDate().with(DayOfWeek.MONDAY);
LocalDate weekEnd = weekStart.plusDays(6);
LocalDate lastWeekStart = weekStart.minusWeeks(1);

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.

p3: aggregate에서 User 조회해서 upsert/create 함수에 전달하는 방법으로 수정하는 거 어떨까요ㅎㅎ
성능은 크게 차이 없을 것 같은데, 반복 호출이 되는 것 같아서 제안해 봅니다~!

eg. User user = getUser(userId); // aggregate에서 한 번만 조회

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

좋은 의견 감사합니다!

현재 User 조회는 주간 스킬 통계를 신규 생성하는 경우에만 수행되고, 기존 통계 갱신이나 집계할 점수가 없는 경우에는 수행되지 않습니다. aggregate 시작 시 User를 미리 조회하면 불필요한 조회가 추가되고, 집계 대상 점수가 없는 경우에도 USER_NOT_FOUND가 발생하는 등 기존 동작이 달라질 수 있어 이번 책임 분리 범위에서는 기존 흐름을 유지하려고 합니다.

동일 트랜잭션 내 반복 findById는 JPA 1차 캐시의 도움도 받을 수 있으므로, 실제 조회 성능 개선은 별도 PERF 이슈에서 쿼리를 측정한 뒤 함께 검토하겠습니다!

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

굿굿!! 코멘트 단 거 참고해 주면 될 것 같습니당

@ownue
ownue merged commit 4e502b1 into develop Sep 10, 2026
2 checks passed
@ownue
ownue deleted the refactor/#246-statistics-aggregation-service branch September 11, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

♻️ Refactor - 통계 집계 서비스 책임 분리

2 participants