Skip to content

issue 23#24

Merged
DevelopLee20 merged 3 commits intomasterfrom
issue-23
Oct 13, 2025
Merged

issue 23#24
DevelopLee20 merged 3 commits intomasterfrom
issue-23

Conversation

@DevelopLee20
Copy link
Owner

@DevelopLee20 DevelopLee20 commented Oct 10, 2025

closes: #23

Summary by CodeRabbit

  • New Features

    • 하루 경계(06:00) 기준으로 구간이 나뉘는 공부 세션을 자동 분할해 일자별 누적을 정확히 집계
    • 공부 종료 메시지에 오늘 누적과 전날 누적 시간이 함께 표시
  • Documentation

    • README 기능 목록 확장 및 시작 방법 수정
    • 개발 섹션 추가: 테스트 실행 가이드 및 프리커밋 사용법 안내
  • Tests

    • 컷오프 기준 세션 분할 로직에 대한 단위 테스트 추가
  • Chores

    • 개발용 테스트 의존성 추가 및 테스트 패키지 초기화 파일 추가

@coderabbitai
Copy link

coderabbitai bot commented Oct 10, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

공부 세션을 일(日) 경계(06:00) 기준으로 분할·저장하도록 흐름이 변경되었고, 전날 누적 합계가 메시지에 포함되도록 메시지 포맷과 DB 인터페이스가 확장되었습니다. README와 개발 도구 설정(pytest, pre-commit), 유틸/테스트가 추가/수정되었습니다.

Changes

Cohort / File(s) Summary
Docs & Dev Tooling
README.md, pyproject.toml, tests/__init__.py
README에 기능 목록 및 Development 섹션(테스트·pre-commit) 추가. Poetry dev 그룹에 pytest, pytest-asyncio 추가. tests/__init__.py 신설.
Time Tracking Flow Update
cogs/time_tracking.py
세션 종료 시 split_study_session_by_cutoff로 06:00 기준 분할, 분할된 세션들을 insert_multiple_studies로 일괄 저장. 삽입 후 오늘 합계(today_total)과 필요 시 전일 합계(prev_day_total)를 계산해 메시지에 전달하도록 변경.
Messaging API Change
core/messages.py
end_study_message 시그니처 확장(마지막 인자로 prev_day_total 추가) 및 전날/오늘 누적을 조건부로 포함하도록 메시지 조립 로직 변경.
DB Bulk Insert
db/study_collection.py
StudyCollection.insert_multiple_studies(studies: list[StudyModel]) 추가: 빈 입력 처리, insert_many를 통한 일괄 삽입, inserted_ids 반환, 예외 로깅 후 재전파.
Time Utilities & Tests
utils/time_utils.py, tests/test_time_utils.py
일 경계(hour) 상향 조정(STUDY_DAY_START_HOUR=6) 및 split_study_session_by_cutoff(start_time, end_time) 함수 추가. 다양한 케이스(경계 일치, 교차, 짧은/긴 세션)를 검증하는 단위 테스트 추가.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User as 사용자
    participant Cog as cogs/time_tracking
    participant Utils as utils/time_utils
    participant DB as db.study_collection
    participant Msg as core.messages
    participant Discord as Discord

    User->>Cog: 세션 종료 알림 (start_time, end_time)
    Cog->>Utils: split_study_session_by_cutoff(start_time, end_time)
    Utils-->>Cog: [(s1,e1,min1), (s2,e2,min2)?]

    Cog->>DB: insert_multiple_studies([StudyModel...])
    DB-->>Cog: [inserted_ids]

    alt 세션이 분할되어 전날 부분 존재
        Cog->>DB: 이전 일자 범위 합계 조회
        DB-->>Cog: prev_day_total
    end

    Cog->>DB: 오늘(06:00-다음06:00) 합계 조회
    DB-->>Cog: today_total

    Cog->>Msg: end_study_message(mention, total_minutes_studied, today_total, text, status, prev_day_total)
    Msg-->>Cog: formatted message

    Cog->>Discord: 메시지 전송
    Discord-->>User: 메시지 전달

    Note over Cog,DB: DB 오류 시 로깅 및 알림 채널 통보
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 전체 코드 리팩토링 #22 — utils/time_utils의 공부일 컷오프 및 시간 분할 로직 변경과 직접적으로 연관된 PR로, 컷오프 시간 및 분할 알고리즘의 설계·테스트와 밀접한 관계가 있음.

Poem

새벽 여섯, 시계가 툭 끊어질 때,
토끼는 홱 뛰어와 두 시간으로 쪼갰네.
어제와 오늘을 나눠 담아 전하고,
저장 한번에 깔끔히, 테스트도 씩씩히.
깡총—메시지에 반짝 반짝 합계가 뜨네.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive 제목 “issue 23”은 변경된 주요 기능이나 목적을 전혀 설명하지 않아 PR의 핵심 내용을 파악하기 어렵고 일반적이고 모호합니다. README, 타임 트래킹, 세션 분할·배치 저장 등 실제 변경사항을 반영하는 간결하고 구체적인 제목으로 수정해 주세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 82.35% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 154d8a8 and 38a6266.

📒 Files selected for processing (3)
  • README.md (2 hunks)
  • db/study_collection.py (1 hunks)
  • utils/time_utils.py (3 hunks)

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (7)
README.md (2)

7-9: 시간 경계(06:00) 설명은 좋습니다. 코드/주석의 ‘04:00’ 언급과 일치 확인 필요.

utils/db 쪽 주석/도큐스트링에 ‘오전 4시’로 남아있는 부분이 보입니다. 런타임 로직과 문서 모두 06:00 기준으로 통일해 주세요. 불일치 시 집계/스플릿 해석이 달라질 수 있습니다.


46-55: Poetry 환경 일관성을 위해 pre-commit 명령에 poetry run 권장

다음과 같이 안내하면 사용자 환경 차이에 덜 민감합니다.

- pre-commit install
+ poetry run pre-commit install
- pre-commit run --all-files
+ poetry run pre-commit run --all-files
- pre-commit run --files <파일경로>
+ poetry run pre-commit run --files <파일경로>
core/messages.py (1)

30-42: 메시지 본문과 text 사이에 줄바꿈 추가 권장

가독성 향상을 위해 한 줄 개행을 권장합니다.

-    message += text
+    message += f"\n{text}"
db/study_collection.py (1)

27-49: 도큐스트링/경계 시각 일치 확인 (04:00 vs 06:00)

본 PR은 06:00 기준 스플릿/집계를 도입했습니다. find_total_study_min_in_today의 설명(04:00~)과 실제 get_study_day_range/스플릿 기준(06:00)이 불일치하면 합산 값이 어긋납니다. 주석/도큐를 06:00 기준으로 정리하거나 로직을 일치시켜 주세요.

cogs/time_tracking.py (1)

109-125: 저장소 캡슐화 및 서버측 합산으로 교체 권장

콜렉션 내부 필드에 직접 접근하지 말고, 범위 기반 합산 메서드를 컬렉션에 추가해 재사용/최적화 하세요. Python sum 대신 MongoDB $group으로 서버측 합산.

예시(StudyCollection에 추가):

@classmethod
async def find_total_study_min_in_range(cls, user_id: str, start: datetime, end: datetime) -> int:
    pipeline = [
        {"$match": {"user_id": user_id, "start_time": {"$gte": start, "$lt": end}}},
        {"$group": {"_id": None, "total_min": {"$sum": "$total_min"}}},
    ]
    rows = await cls._collection.aggregate(pipeline).to_list(length=None)
    return rows[0]["total_min"] if rows else 0

사용부 교체:

- prev_records = await StudyCollection._collection.find(
-     {"user_id": str(member.id), "start_time": {"$gte": prev_start, "$lt": prev_end}}
- ).to_list(length=None)
- prev_day_total = sum(record["total_min"] for record in prev_records)
+ prev_day_total = await StudyCollection.find_total_study_min_in_range(
+     str(member.id), prev_start, prev_end
+ )
utils/time_utils.py (1)

47-59: 입력 유효성 검증 추가를 고려하세요.

함수가 end_time > start_time인지 검증하지 않습니다. 잘못된 입력이 전달되면 음수 duration이나 예상치 못한 결과가 발생할 수 있습니다.

함수 시작 부분에 다음 검증을 추가하는 것을 권장합니다:

def split_study_session_by_cutoff(
    start_time: datetime, end_time: datetime
) -> list[tuple[datetime, datetime, int]]:
    """공부 세션이 오전 6시를 넘어가면 전날과 오늘로 분할합니다.

    Args:
        start_time: 공부 시작 시간
        end_time: 공부 종료 시간

    Returns:
        [(start_time, end_time, minutes), ...] 리스트
        오전 6시를 넘지 않으면 1개, 넘으면 2개의 튜플 반환
    """
    if end_time <= start_time:
        raise ValueError("end_time must be greater than start_time")
    
    # 오전 6시 기준 시간 계산
    # ... 나머지 코드
tests/test_time_utils.py (1)

10-147: 테스트 커버리지가 우수합니다. 추가 시나리오 고려를 권장합니다.

현재 테스트는 같은 날짜 내의 다양한 엣지 케이스를 잘 다루고 있습니다. 그러나 자정을 넘는 세션(예: 전날 23시 시작 → 다음날 7시 종료)에 대한 테스트가 없습니다.

다음과 같은 추가 테스트를 고려하세요:

def test_cross_midnight_session(self):
    """자정을 넘어 오전 6시까지 이어지는 세션"""
    # 10월 10일 23시 ~ 10월 11일 7시
    start = datetime(2025, 10, 10, 23, 0, 0)
    end = datetime(2025, 10, 11, 7, 0, 0)
    
    sessions = split_study_session_by_cutoff(start, end)
    
    assert len(sessions) == 2
    # 첫 번째 세션: 23시 ~ 6시 (10월 11일) = 420분
    assert sessions[0][2] == 420
    # 두 번째 세션: 6시 ~ 7시 = 60분
    assert sessions[1][2] == 60
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3aa31ba and 154d8a8.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • README.md (2 hunks)
  • cogs/time_tracking.py (2 hunks)
  • core/messages.py (1 hunks)
  • db/study_collection.py (1 hunks)
  • pyproject.toml (1 hunks)
  • tests/__init__.py (1 hunks)
  • tests/test_time_utils.py (1 hunks)
  • utils/time_utils.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
db/study_collection.py (1)
models/study_model.py (1)
  • StudyModel (8-12)
tests/test_time_utils.py (1)
utils/time_utils.py (1)
  • split_study_session_by_cutoff (47-93)
core/messages.py (2)
core/random_messages.py (1)
  • random_good_job_message (40-41)
utils/time_utils.py (1)
  • min_to_hhmm_str (9-20)
cogs/time_tracking.py (4)
utils/time_utils.py (2)
  • get_study_day_range (23-44)
  • split_study_session_by_cutoff (47-93)
models/study_model.py (1)
  • StudyModel (8-12)
db/study_collection.py (3)
  • StudyCollection (12-78)
  • insert_multiple_studies (28-48)
  • find_total_study_min_in_today (51-78)
core/messages.py (1)
  • end_study_message (19-42)
🔇 Additional comments (2)
tests/__init__.py (1)

1-1: LGTM!

테스트 패키지를 위한 표준적인 __init__.py 파일입니다. 추가 내용이 필요 없습니다.

tests/test_time_utils.py (1)

149-152: LGTM!

직접 스크립트 실행을 위한 표준적인 pytest 호출 패턴입니다. 주석으로 파라미터를 설명한 점도 좋습니다.

@DevelopLee20 DevelopLee20 merged commit 8b1f1e1 into master Oct 13, 2025
2 of 3 checks passed
@DevelopLee20 DevelopLee20 deleted the issue-23 branch October 13, 2025 12:56
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.

누적 공부 0분 문제

1 participant