Skip to content

[refactor] #201 - 통계 API가 반복 투두 발생 규칙 기준으로 집계되도록 수정 - #202

Open
aneykrap wants to merge 1 commit into
developfrom
refactor/#201-statics-timer-date
Open

aneykrap wants to merge 1 commit into
developfrom
refactor/#201-statics-timer-date

Conversation

@aneykrap

@aneykrap aneykrap commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

관련 이슈 🛠

작업 내용 요약 ✏️

  • 통계(/api/v1/statistics/summary, /calendar, /daily) API가 실제 TodoInstance row(완료 토글·타이머 시작 등으로 사용자가 건드릴 때만 생성됨)만 보고 집계하던 방식을 반복 투두의 발생 규칙(target_date) 기준으로 집계하도록 수정
  • 반복 투두의 예정된 발생일도 통계의 "총 개수"에 정상적으로 포함

주요 변경 사항 🛠

  • StatisticsOccurrenceCalculator 추가: TodoRepository.findRulesInRange + TodoDateCalculator.occursOn + TodoInstanceRepository.findByTodoIdsAndDateRange를 통해
    반복 규칙상 발생하는 날짜는 인스턴스 유무와 무관하게 집계하고 완료 여부만 실제 인스턴스가 있을 때 덧입히도록 계산
  • StatisticsService.getCalendar/getSummary/getDaily가 위 계산로직을 사용하도록 변경
  • 더 이상 쓰이지 않는 TodoRepository의 통계 전용 쿼리 2개(findDailyCompletionStats, findMonthlySummaryStats)와 프로젝션 인터페이스 2개(TodoDailyCompletionStats,TodoMonthlySummaryStats) 삭제

트러블 슈팅 ⚽️

  • 작업 시작 시점에 TodoRepository의 쿼리는 이미 TodoInstance.date/completed 기준으로 바뀌어 있었지만 StatisticsService가 옛 시그니처(Todo.createdAt 기반)를 그대로
    호출하고 있어 컴파일 자체가 깨진 상태였음 — 우선 바로잡음
  • WEEKLY 반복 투두를 만들어 검증하던 중 반복 규칙상 발생하는 날짜라도 사용자가 한 번도 안 건드리면(=TodoInstance가 지연 생성되지 않으면) 통계에서 통째로 빠지는 걸 발견 — totalTodoCount가 실제 발생 9회 중 완료 처리한 3회로만 집계됨.
  • getDaily의 응답 정렬 순서가 기존 TodoInstance.sortOrder(사용자가 수동 정렬한 순서) 대신 Todo 규칙 등록순(createdAt asc)으로 바뀜 — 통계 조회 화면이라 UI 정렬과는 무관하다고 판단하고 진행함

테스트 결과 📄

  • ./gradlew compileJava, ./gradlew test 전체 통과
  • WEEKLY(월/목) 반복 투두를 만들어 일부 발생일만 완료 처리한 뒤 세 API를 직접 호출해 검증
    - summary: 9월 8회 발생 중 2회만 완료 처리 → totalTodoCount: 8, completedTodoCount: 2, activeDayCount: 8로 정상 반영 (수정 전에는 2/2/2로 누락됐었음)
    - calendar: 완료한 날짜는 100%, 발생했지만 미완료인 날짜는 0%로 정상 표시(날짜 자체가 누락되지 않음)
    - daily: 아직 오지 않은/한 번도 안 건드린 발생일도 투두 목록에 정상적으로 포함됨

스크린샷 📷

스크린샷 2026-09-11 오후 7 09 59 스크린샷 2026-09-11 오후 7 10 31 스크린샷 2026-09-11 오후 7 10 59

리뷰 요구사항 📢

뭔가 복잡한 느낌과 빼먹은 기분이 드네여... 티모버들이 한번 더 확인해주시면 감사하겠습니당

📎 참고 자료 (선택)

없음

Summary by CodeRabbit

  • 개선 사항
    • 캘린더와 요약 화면의 일일·월간 할 일 통계 산정 방식이 통합되었습니다.
    • 반복 할 일의 실제 발생 횟수와 완료 횟수를 기준으로 통계가 계산됩니다.
    • 특정 날짜에 발생하는 반복 할 일을 바탕으로 일일 할 일 정보가 제공됩니다.
    • 완료율, 전체 할 일 수, 완료한 할 일 수가 실제 발생한 할 일을 기준으로 표시됩니다.

@aneykrap aneykrap self-assigned this Sep 11, 2026
@coderabbitai

coderabbitai Bot commented Sep 11, 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: c7d8283b-a164-45f8-ad77-b1f3abd03192

📥 Commits

Reviewing files that changed from the base of the PR and between 99218bf and 9b4b653.

📒 Files selected for processing (5)
  • src/main/java/com/Timo/Timo/domain/statistics/service/StatisticsService.java
  • src/main/java/com/Timo/Timo/domain/statistics/support/StatisticsOccurrenceCalculator.java
  • src/main/java/com/Timo/Timo/domain/todo/repository/TodoDailyCompletionStats.java
  • src/main/java/com/Timo/Timo/domain/todo/repository/TodoMonthlySummaryStats.java
  • src/main/java/com/Timo/Timo/domain/todo/repository/TodoRepository.java
💤 Files with no reviewable changes (3)
  • src/main/java/com/Timo/Timo/domain/todo/repository/TodoDailyCompletionStats.java
  • src/main/java/com/Timo/Timo/domain/todo/repository/TodoMonthlySummaryStats.java
  • src/main/java/com/Timo/Timo/domain/todo/repository/TodoRepository.java

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


Walkthrough

통계 서비스가 규칙 발생 데이터를 기준으로 일별·월별 통계를 계산하도록 변경되었습니다. 기존 통계 전용 저장소 쿼리와 프로젝션은 제거되었습니다. 미래 날짜의 규칙 발생도 통계 계산에 포함됩니다.

Changes

통계 발생 집계 전환

Layer / File(s) Summary
발생 데이터 계산기 추가
src/main/java/com/Timo/Timo/domain/statistics/support/StatisticsOccurrenceCalculator.java
StatisticsOccurrenceCalculator가 날짜별 발생 수와 완료 수를 계산합니다. 특정 날짜에 발생하는 규칙 목록과 인스턴스 완료 상태를 처리합니다.
통계 서비스 연동
src/main/java/com/Timo/Timo/domain/statistics/service/StatisticsService.java
getCalendar, getSummary, getDaily가 발생 계산기를 사용합니다. 응답 변환과 완료율 계산이 DailyOccurrenceTodo 기준으로 변경되었습니다.
기존 통계 쿼리 계약 제거
src/main/java/com/Timo/Timo/domain/todo/repository/TodoRepository.java, src/main/java/com/Timo/Timo/domain/todo/repository/TodoDailyCompletionStats.java, src/main/java/com/Timo/Timo/domain/todo/repository/TodoMonthlySummaryStats.java
기존 일별·월별 통계 프로젝션과 관련 저장소 쿼리가 제거되었습니다.

Priority: ➖ Normal

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

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 9b4b6

No confirmed merge-blocking risk remains in the statistics occurrence transition.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 이슈 #201은 미래 타이머 실행일을 통계에 포함하도록 요구합니다. StatisticsOccurrenceCalculator는 날짜 범위의 반복 Todo 규칙을 발생일 기준으로 계산합니다. TodoInstance가 없어도 해당 발생일의 totalCount를 집계합니다. 인스턴스가 있으면 완료 상태를 completedCount에 반영합니다. …
Out of Scope Changes check ✅ Passed 변경 사항은 이슈 #201의 통계 집계 수정에 연결됩니다. 발생일 계산기 추가와 통계 서비스 전환은 미래 발생일 집계를 구현합니다. 통계 전용 저장소 쿼리와 프로젝션 삭제는 새 계산 경로에 맞춘 정리입니다. getDaily 정렬 변경도 통계 결과 동작에 포함됩니다. 독립적인 기능 추가나 다른 도메인 변경은 확인되지 않습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 반복 투두의 발생 규칙을 기준으로 통계 API를 집계하도록 변경한 주요 내용을 정확하고 간결하게 설명합니다.
  • 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/#201-statics-timer-date

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

@aneykrap

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@aneykrap

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 37 minutes.

@aneykrap

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@Jy000n Jy000n left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

고생하셨습니다아!! 반복 일정에 맞게 통계도 잘 바뀐 것 같네용

코리를 달던 중 궁금한 점이 생겼는데요,, 그러면 화목에 반복 일정이 있는 투두라고 쳤을 때, 1주차는 화목 투두를 완료한 후에, 해당 반복 투두 일정을 그 이후부터 월요일로 변경하고 싶으면 어떻게 되는걸까요..?? 변경하게 된다면 현재 코드로서는 기존에 1주차(화목)에 완료했던 투두 기록이 사라지는 것 같아서 관련하여 리뷰 같이 남겨보았으니 참고해주시면 감사하겠습니다 :)

Comment on lines +44 to +57
private DailyOccurrence summarizeDate(List<Todo> rules, Map<InstanceKey, TodoInstance> instancesByKey, LocalDate date) {
int totalCount = 0;
int completedCount = 0;

for (Todo rule : rules) {
if (!todoDateCalculator.occursOn(rule, date)) {
continue;
}
totalCount++;
TodoInstance instance = instancesByKey.get(new InstanceKey(rule.getId(), date));
if (instance != null && instance.isCompleted()) {
completedCount++;
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P3] 반복 규칙 변경 시 기존 완료 기록이 통계에서 누락될 수 있는 것 같습니다! summarizeDateoccursOn이 false면 바로 continue해서 이미 존재하는 TodoInstance도 무시하게 돼서 그런 것 같습니다!
ex) 화/목 반복 투두를 1주차에서 완료 처리한 뒤 그 이후 반복 요일을 월요일로 바꾸면 통계(summary/calendar)에서는 해당 완료 기록이 사라집니다.

@laura-jung laura-jung left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

계획된 일정과 다른 날짜에 실행된 경우를 집계하는게 좀 많이 복잡하네용.....
코멘트 남겨두었으니 확인부탁드립니다!!
수고하셨습니다!

Map<Long, String> tagNamesById = findTagNames(instances);
List<DailyTodoResponse> todos = instances.stream()
.map(instance -> toDailyTodoResponse(instance, actualSecondsByTodoId, tagNamesById))
List<Todo> occurringTodos = statisticsOccurrenceCalculator.findOccurringRules(userId, date);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] 예정일과 실행일이 다른 타이머 기록이 일별 상세 목록에서 누락될 수 있는 로직인 것 같습니다.

예를 들어 9/10에 예정된 투두를 9/11에 30분 실행한 뒤 /statistics/daily?date=2026-09-11을 조회하면, 타이머 쿼리는 실제 기록 시각 기준으로 30분을 가져옵니다. 하지만 todosfindOccurringRules()로 9/11에 예정된 규칙만 조회하므로 해당 투두가 제외될 수도 있을 것 같아요
예정된 투두 목록에 해당 날짜의 타이머 기록에 등장한 todoId도 합쳐서 반환하는 방식도 있어야 할 것 같습니다!

int completedCount = 0;

for (Todo rule : rules) {
if (!todoDateCalculator.occursOn(rule, date)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[p3] 이부분에서 원래의 반복 계획을 먼저 확인하는것 같네요! 이렇게 되면 반복 계획일과 실행된 날짜가 맞지 않을경우 제외될 수 있을 것 같습니다!

예를 들어 ‘매주 월요일 독서’ 투두를 화요일에 실행할 때, 타이머 시작 요청에서 targetDate를 생략하면 오늘인 화요일을 사용합니다. 이 경우 화요일 TodoInstance가 생성되고, 타이머 종료 시 ‘화요일 독서 완료’로 저장될 수 있습니다.
하지만 현재 계산기는 ‘화요일은 월요일 반복 규칙의 발생일이 아니다’라는 이유로 바로 제외합니다. 따라서 실제로 화요일 완료 기록이 저장돼 있어도 완료 개수에는 반영되지 않습니다.

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] 미래타이머 실행시 통계 수정

3 participants