Skip to content

[FIX] 반복일정 투두의 타이머 카드 동기화 오류 수정#241

Open
jjangminii wants to merge 2 commits into
developfrom
fix/web/236-recurring-todo-timer-sync
Open

[FIX] 반복일정 투두의 타이머 카드 동기화 오류 수정#241
jjangminii wants to merge 2 commits into
developfrom
fix/web/236-recurring-todo-timer-sync

Conversation

@jjangminii

Copy link
Copy Markdown
Contributor

ISSUE 🔗

close #236



What is this PR? 🔍

반복일정으로 설정된 투두가 같은 todoId를 공유하는 다른 날짜에서도 타이머가 실행 중인 것처럼 잘못 표시되던 문제를 수정했습니다.

배경

  • 기존 구조: 클라이언트는 활성 타이머와 화면에 그려진 투두를 오직 todoId로만 매칭해서 "지금 이 투두의 타이머가 실행 중인지"를 판단하고 있었습니다.
  • 발생 문제: 반복일정 투두는 여러 날짜에 걸쳐 같은 todoId를 공유하는데, 한 날짜에서 타이머를 재생하면 같은 todoId를 가진 다른 날짜의 투두 카드들도 전부 실행 중으로 표시됐습니다.
  • 해결 방향: 서버가 타이머 시작/활성 조회 응답에 date(타이머가 귀속되는 날짜) 필드를 추가했고, 클라이언트에서도 활성 타이머와 투두를 (todoId, date) 조합으로 매칭하도록 전 화면의 비교 로직을 수정했습니다.

타이머-투두 매칭 로직

  • 변경 요약: Home/Today/Focus 탭과 할 일 수정 모달에서 활성 타이머와 투두를 매칭할 때 todoId 단독 비교 대신 todoId + date 조합으로 비교하도록 수정했습니다.
  • 이유: /v3/api-docs에서 실제 응답 스펙을 확인해보니 startTimer/getActiveTimer 두 엔드포인트 모두 date가 신규 필수 필드로 추가돼 있었고, API 설명에도 "반복 투두는 여러 날짜에 같은 todoId로 노출되므로, 실행중 표시는 todoId가 아닌 (todoId, date) 조합으로 구분해야 합니다"라고 명시돼 있었습니다.
  • 구현 방식: pnpm gen:api로 orval 코드를 재생성해 TimerActiveResponse/TimerStartResponsedate: string을 반영했습니다(이번 작업과 무관하게 함께 딸려온 다른 도메인 재생성분은 되돌려 diff에서 제외했습니다). 로컬 zod 스키마 activeTimerSchema(schemas/timer/timer-schema.ts)에도 date를 추가해 응답을 한 번 더 검증하도록 했습니다. 이후 activeTimer.todoId === todo.todoId 형태의 비교가 있던 7개 지점(use-focus-session.ts, use-home-todos-by-date.ts 2곳, useTodayTodoList.ts 2곳, HomeTodoContainer.tsx, TodayTodoListContainer.tsx, DetailTodoModalContainer.tsx 2곳)에 activeTimer.date === <해당 스코프의 날짜> 비교를 추가했습니다. Focus 탭은 개별 투두에 날짜가 없어 focusView.date(조회 중인 날짜)와 비교했고, 나머지는 각 화면이 이미 들고 있는 dateKey/todo.date와 비교했습니다.
  • 경계 · 제약: TimeboxPanel.tsx의 타임박스-활성타이머 매칭은 이미 timerId(세션마다 고유)로 비교하고 있어 todoId만으로 인한 모호함이 없었으므로 그대로 뒀습니다.



To Reviewers

activeTimer.date와 비교하는 기준 날짜가 화면마다 다릅니다(Home/Today는 투두가 속한 날짜, Focus는 조회 중인 날짜). 각 지점에서 비교 기준으로 쓴 날짜 값이 맞는지 한 번씩 봐주시면 좋을 것 같습니다.



Screenshot 📷



Test Checklist ✔

  • pnpm check-types 통과
  • pnpm lint 통과
  • 반복일정 투두를 한 날짜에서 재생했을 때 다른 날짜의 같은 투두가 더 이상 실행 중으로 표시되지 않는지 실제 dev 서버에서 확인

- 타이머 시작/활성 조회 API 응답에 추가된 date 필드를 반영하도록 orval 코드를 재생성했습니다
- 활성 타이머와 투두를 매칭할 때 todoId뿐 아니라 date까지 함께 비교하도록 수정해, 반복일정 투두가 다른 날짜에서도 실행 중으로 표시되던 문제를 해결했습니다
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
timo Ready Ready Preview, Comment Jul 15, 2026 6:25pm

Request Review

@github-actions github-actions Bot added the ⏰ Timo-web Timo 웹 서비스 label Jul 15, 2026
@github-actions github-actions Bot requested review from ehye1 and kimminna July 15, 2026 18:25
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

활성 타이머 스키마에 날짜 필드를 추가하고, 타이머 상태 전환·완료 처리·하이라이트 계산에서 todoId와 날짜를 함께 비교하도록 변경했습니다. 반복 투두의 다른 날짜 항목이 활성 타이머로 잘못 표시되지 않습니다.

Changes

날짜 기반 활성 타이머 매칭

Layer / File(s) Summary
활성 타이머 계약
apps/timo-web/schemas/timer/timer-schema.ts
activeTimerSchema에 필수 date 문자열 필드를 추가했습니다.
타이머 상호작용 날짜 검증
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts, apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
완료 처리와 재생·일시정지·재개 분기가 todoIddate가 모두 일치하는 활성 타이머에만 적용됩니다.
타이머 상태 및 하이라이트 날짜 검증
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_containers/HomeTodoContainer.tsx, apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoListContainer.tsx, apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts, apps/timo-web/containers/todo-modal/detail/DetailTodoModalContainer.tsx
활성 상태, 포커스 타이머 선택, 재생 하이라이트 및 타이머 상태 계산에 날짜 일치 조건을 적용했습니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

  • Team-Timo/Timo-client#184 — 홈 화면의 활성 타이머 기반 완료·재생 흐름을 다루며, 본 변경이 해당 매칭 조건을 날짜까지 확장합니다.
  • Team-Timo/Timo-client#209 — 홈·오늘 화면의 활성 상태 및 재생 하이라이트 로직과 관련됩니다.
  • Team-Timo/Timo-client#210 — 상세 투두 모달의 활성 타이머 상태 및 하이라이트 계산과 관련됩니다.

Suggested labels: ⏰ Timo-web, 🐛 Bug, ♠️ 정민

Suggested reviewers: kimminna, yumin-kim2

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 반복일정 투두의 타이머 카드 동기화 오류 수정이라는 핵심 변경을 간결하게 잘 담고 있습니다.
Description check ✅ Passed 설명이 변경 원인, 해결 방식, 영향 범위를 모두 PR의 실제 변경과 맞게 설명합니다.
Linked Issues check ✅ Passed 반복일정 투두를 todoId와 date로 매칭하도록 바꾸고, 관련 화면 전반에 반영해 이슈 #236의 요구를 충족합니다.
Out of Scope Changes check ✅ Passed 요구사항과 무관한 변경은 보이지 않고, 모두 타이머 날짜 매칭 보완에 집중되어 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/web/236-recurring-todo-timer-sync

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.


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.

@github-actions github-actions Bot added 🐛 Bug 기능이 정상적으로 작동하지 않는 문제 수정 ♠️ 정민 정민양 labels Jul 15, 2026
@github-actions

Copy link
Copy Markdown

Timo Performance Report

Bundle Size — timo-web
라우트 크기 First Load JS
/[locale]/home 211.36 kB 🔴 417.22 kB
/[locale]/today 195.47 kB 🔴 401.33 kB
/[locale]/focus 160.60 kB 🔴 366.46 kB
/[locale]/settings 167.12 kB 🔴 372.98 kB
/[locale]/statistics 233.44 kB 🔴 439.30 kB
/[locale]/[...rest] 0 B 🟡 205.86 kB
/[locale]/login 212.96 kB 🔴 418.82 kB
/[locale]/oauth/callback 119.66 kB 🟡 325.52 kB
/[locale]/onboarding 233.42 kB 🔴 439.28 kB
/[locale] 118.97 kB 🟡 324.83 kB
/[locale]/policy 125.09 kB 🟡 330.95 kB

공유 번들: 205.86 kB
🟢 < 200kB  |  🟡 < 350kB  |  🔴 ≥ 350kB (First Load JS · gzip)

Lighthouse — timo-web
URL Perf A11y LCP CLS TBT
/en/home 🟡 70 🟢 95 🔴 15.6s 🟢 0.000 🟡 250ms
/en/today 🔴 63 🟢 95 🔴 15.6s 🟢 0.000 🟡 466ms
/en/focus 🔴 62 🟢 95 🔴 15.2s 🟢 0.000 🟡 486ms
/en/statistics 🔴 63 🟢 95 🔴 15.2s 🟢 0.000 🟡 463ms

Perf ≥ 70 / A11y ≥ 85 목표
LCP 🟢 < 2.5s 🟡 < 4s 🔴 ≥ 4s  |  CLS 🟢 < 0.1 🟡 < 0.25 🔴 ≥ 0.25  |  TBT 🟢 < 200ms 🟡 < 600ms 🔴 ≥ 600ms

Image Optimization — timo-web
파일 크기 포맷 상태
favicon.png 27.84 kB PNG ⚠️ 🟢
images/google-calendar.png 36.20 kB PNG ⚠️ 🟢
images/google-logo.png 26.79 kB PNG ⚠️ 🟢

총 3개 · 90.84 kB  |  🟢 < 200KB  |  🟡 < 500KB  |  🔴 ≥ 500KB
⚠️ 3개 파일 WebP/AVIF 변환 권장

측정 커밋: 4af33f6

@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

🤖 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
`@apps/timo-web/app/`[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts:
- Around line 98-102: The activeTimer condition must explicitly narrow the
nullable value before accessing its properties. Update the condition in
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
lines 98-102,
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
lines 84-88, and
apps/timo-web/containers/todo-modal/detail/DetailTodoModalContainer.tsx lines
75-77 to use activeTimer && followed by the todoId and date comparisons,
preserving the existing completed and matching-date behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a2aed907-ba6d-4bff-8241-7f742c74e628

📥 Commits

Reviewing files that changed from the base of the PR and between dd18e8a and 1fe631c.

⛔ Files ignored due to path filters (4)
  • apps/timo-web/api/generated/endpoints/timer/timer.ts is excluded by !**/generated/**
  • apps/timo-web/api/generated/endpoints/timer/timer.zod.ts is excluded by !**/generated/**
  • apps/timo-web/api/generated/models/timerActiveResponse.ts is excluded by !**/generated/**
  • apps/timo-web/api/generated/models/timerStartResponse.ts is excluded by !**/generated/**
📒 Files selected for processing (7)
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_containers/HomeTodoContainer.tsx
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_containers/TodayTodoListContainer.tsx
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
  • apps/timo-web/app/[locale]/(main)/focus/_hooks/use-focus-session.ts
  • apps/timo-web/containers/todo-modal/detail/DetailTodoModalContainer.tsx
  • apps/timo-web/schemas/timer/timer-schema.ts

Comment on lines +98 to +102
if (
completed &&
activeTimer?.todoId === todoId &&
activeTimer.date === dateKey
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

activeTimer 타입 좁히기(Type Narrowing) 및 코드 일관성 개선

동일한 파일 내 다른 핸들러(예: handleTogglePlay)에서는 activeTimer && activeTimer.todoId === todoId 형태로 안전하게 타입을 좁히고 있습니다. 반면 아래 코드들에서는 옵셔널 체이닝(?.)을 사용한 후 다시 activeTimer.date에 직접 접근하고 있어 코드의 일관성이 떨어지며, TypeScript 환경에 따라 타입 좁히기가 완벽하게 동작하지 않아 컴파일 에러가 발생할 여지가 있습니다. (참고: TypeScript: Type Narrowing)
안전하고 통일성 있는 코드를 위해 명시적 Null 체크 방식으로 맞춰주시는 것을 추천해요! 🛠️

  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts#L98-L102: activeTimer && activeTimer.todoId === todoId && activeTimer.date === dateKey 구조로 수정하세요.
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts#L84-L88: 위와 동일하게 수정하세요.
  • apps/timo-web/containers/todo-modal/detail/DetailTodoModalContainer.tsx#L75-L77: activeTimer && activeTimer.todoId === todoId && activeTimer.date === date 구조로 수정하세요.
📍 Affects 3 files
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts#L98-L102 (this comment)
  • apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts#L84-L88
  • apps/timo-web/containers/todo-modal/detail/DetailTodoModalContainer.tsx#L75-L77
🤖 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
`@apps/timo-web/app/`[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
around lines 98 - 102, The activeTimer condition must explicitly narrow the
nullable value before accessing its properties. Update the condition in
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/home/_hooks/use-home-todos-by-date.ts
lines 98-102,
apps/timo-web/app/[locale]/(main)/(with-time-sidebar)/today/_hooks/useTodayTodoList.ts
lines 84-88, and
apps/timo-web/containers/todo-modal/detail/DetailTodoModalContainer.tsx lines
75-77 to use activeTimer && followed by the todoId and date comparisons,
preserving the existing completed and matching-date behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⏰ Timo-web Timo 웹 서비스 ♠️ 정민 정민양 🐛 Bug 기능이 정상적으로 작동하지 않는 문제 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 반복일정 투두의 타이머 카드 동기화 오류 수정

1 participant