[Feature/#271] 타임라인 조회/생성 API 연동 및 mock 데이터 교체 - #281
Conversation
|
Warning Review limit reached
Next review available in: 49 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough타임라인 조회·생성 API와 React Query 훅이 추가되고, 페이지는 mock 데이터 대신 실제 조회 결과와 상세 데이터를 사용하도록 바뀌었다. 기간 계산·그리드·요약 패널 유틸이 신설됐고, 생성 모달은 Changes타임라인 API 연동 및 UI 전환
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
src/api/timeline/timeline.ts (1)
37-44: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value
validateStatus조건 중복 정리 필요.
status === 201은 이미status >= 200 && status < 300조건에 포함되기 때문에 실질적으로 아무 효과가 없는 중복 체크입니다. axios의 기본validateStatus도 2xx는 전부 성공으로 처리하므로, 이 커스텀 옵션 자체가 불필요해 보입니다. 향후 유지보수자가 "201만 특별 취급한다"고 오해할 소지가 있어 정리하는 게 좋습니다.♻️ 제안
const { data } = await axiosInstance.post< ICommonResponse<ITimelineMutationResponse> - >(`/api/org/${orgId}/timeline`, body, { - validateStatus: (status) => - status === 201 || (status >= 200 && status < 300), - }); + >(`/api/org/${orgId}/timeline`, body);🤖 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/api/timeline/timeline.ts` around lines 37 - 44, The custom validateStatus in timeline mutation request is redundant because status === 201 is already covered by the 2xx range and axios defaults to treating 2xx as success. Remove the unnecessary validateStatus override from the axiosInstance.post call in timeline.ts, keeping the request behavior aligned with the default success handling in the timeline API function.src/hooks/timeline/useCreateTimeline.ts (1)
15-34: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win로컬 reject 값과
IApiErrorResponse타입 불일치.
orgId가 없을 때Promise.reject(new Error("워크스페이스를 선택해주세요"))로 거부하는데,useCoreMutation의TError기본 타입은IApiErrorResponse(status,code,method,requestURI포함)입니다. 지금은Error와IApiErrorResponse둘 다message필드를 가지고 있어서userOnError의(error as IApiErrorResponse).message가 우연히 정상 동작하지만, 타입상으로는error.code/error.status등이 항상 존재하는 것처럼 보여 실제로는undefined인 위험한 불일치가 있습니다. 추후 에러 코드 기반 분기나 로깅을 추가하면 조용히 깨질 수 있습니다.로컬 검증 실패는
IApiErrorResponse와 별개의 유니온 타입으로 다루거나, 최소한 로컬 전용 에러 클래스를 만들어 명시적으로 구분하는 걸 권장합니다.As per path instructions, "타입 안정성: TypeScript 타입의 명확성 확인. any 사용 지양, 제네릭 활용 검토."
🤖 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/hooks/timeline/useCreateTimeline.ts` around lines 15 - 34, `useCreateTimeline`의 로컬 검증 실패가 `IApiErrorResponse`와 타입이 섞여 있어 `userOnError`에서 실제 API 에러처럼 취급되는 불일치가 있습니다. `orgId == null`일 때의 reject를 `IApiErrorResponse`와 구분되는 별도 로컬 에러로 처리하거나 `useCoreMutation`의 에러 타입을 유니온으로 명시해, `userOnError`와 `createTimeline` 경로에서 `message` 외의 필드(`status`, `code`, `method`, `requestURI`)를 안전하게 다루도록 정리하세요.Source: Path instructions
🤖 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/pages/dashboard/timeline/Timeline.tsx`:
- Around line 79-82: `Timeline`의 `handleBarClick`에서 `selectedBarId`만 바꾸고
`panelData`를 유지해서 이전 요약이 잠깐 보이는 상태입니다. 새 막대를 클릭할 때 즉시 `panelData`를 null로 초기화해
`TimelinePerformancePanel`이 기존 내용을 렌더링하지 않도록 하고, `useEffect`의
`buildTimelineSummaryPanel(detail)`로 새 `detail`이 도착하면 다시 채우도록 수정하세요.
`selectedBarId`, `panelData`, `handleBarClick`, `useTimelineDetail`,
`buildTimelineSummaryPanel`을 기준으로 고치면 됩니다.
- Around line 55-70: The current isEmpty check in Timeline is based on bars from
buildTimelineGrid, but bars only reflect items in the selected
viewUnit/periodIndex and can incorrectly show TimelineEmptyState when data
exists outside the current period. Update the Timeline component to distinguish
between an empty overall timelineList and an empty current-period result, using
the existing useTimelineList, buildTimelineGrid, and isEmpty logic so the UI can
show “no timeline data” only when timelineList is truly empty and a separate
state when nothing matches the current period.
- Around line 130-144: Update the error UI in Timeline so the container rendered
from the isError branch exposes accessibility feedback with role="alert" and
aria-live="assertive". In the Timeline component, remove the unnecessary
IApiErrorResponse cast around error and read the message directly via
error?.message. Also fix the Korean copy in the fallback string to correct the
typos in “못했습니다” and “잠시 후”.
---
Nitpick comments:
In `@src/api/timeline/timeline.ts`:
- Around line 37-44: The custom validateStatus in timeline mutation request is
redundant because status === 201 is already covered by the 2xx range and axios
defaults to treating 2xx as success. Remove the unnecessary validateStatus
override from the axiosInstance.post call in timeline.ts, keeping the request
behavior aligned with the default success handling in the timeline API function.
In `@src/hooks/timeline/useCreateTimeline.ts`:
- Around line 15-34: `useCreateTimeline`의 로컬 검증 실패가 `IApiErrorResponse`와 타입이 섞여
있어 `userOnError`에서 실제 API 에러처럼 취급되는 불일치가 있습니다. `orgId == null`일 때의 reject를
`IApiErrorResponse`와 구분되는 별도 로컬 에러로 처리하거나 `useCoreMutation`의 에러 타입을 유니온으로 명시해,
`userOnError`와 `createTimeline` 경로에서 `message` 외의 필드(`status`, `code`, `method`,
`requestURI`)를 안전하게 다루도록 정리하세요.
🪄 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: CHILL
Plan: Pro
Run ID: 43ce660c-33d9-441a-8e52-927afe4e0ecf
📒 Files selected for processing (11)
src/api/timeline/timeline.tssrc/components/timeline/TimelineCreateModal.tsxsrc/components/timeline/skeleton/TimelineSkeleton.tsxsrc/hooks/timeline/useCreateTimeline.tssrc/hooks/timeline/useTimelineDetail.tssrc/hooks/timeline/useTimelineList.tssrc/lib/queryKeys.tssrc/pages/dashboard/timeline/Timeline.tsxsrc/utils/timeline/buildTimelineGrid.tssrc/utils/timeline/buildTimelineSummaryPanel.tssrc/utils/timeline/period.ts
📚 Storybook 배포 완료
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/constants/timeline/formOptions.ts`:
- Line 24: The `LAST_YEAR` option in the timeline form is failing type-check
because `TTimelineComparisonPeriodType` is defined with the misspelled value
from `TIMELINE_COMPARISON_PERIOD_TYPES`. Fix the source of truth in
`src/types/timeline/api.ts` by correcting the array entry from the typo to
`LAST_YEAR`, so `formOptions.ts` can use the matching
`TTimelineComparisonPeriodType` value without a compile error.
In `@src/types/timeline/api.ts`:
- Around line 26-30: `TIMELINE_COMPARISON_PERIOD_TYPES` contains a typo that
propagates into `TTimelineComparisonPeriodType` and `timelineCreateSchema`, so
update the array entry in `TIMELINE_COMPARISON_PERIOD_TYPES` from the misspelled
year value to the correct `LAST_YEAR` literal. Use the existing symbols
`TIMELINE_COMPARISON_PERIOD_TYPES`, `TIMELINE_COMPARISON_PERIOD_VALUES`, and
`TTimelineComparisonPeriodType` to verify the type union and enum validation now
match the `LAST_YEAR` usage in `formOptions`.
🪄 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: CHILL
Plan: Pro
Run ID: db4a4e69-e8b1-4184-8735-ea9d070c6e0f
⛔ Files ignored due to path filters (2)
.storybook/main.tsis excluded by none and included by none.storybook/preview.tsxis excluded by none and included by none
📒 Files selected for processing (3)
src/constants/timeline/formOptions.tssrc/pages/dashboard/timeline/Timeline.tsxsrc/types/timeline/api.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/dashboard/timeline/Timeline.tsx
🚨 관련 이슈
Closed #271
✨ 변경사항
✏️ 작업 내용
QUERY_KEYS.timeline및useTimelineList/useTimelineDetail/useCreateTimeline커스텀 훅 추가Timeline.tsx에서 mock데이터 제거, 목록 API + 기간(viewUnit,periodIndex) 기반 그리드 랜더링TimelineCreateModalmock 제출 →createTimelinemutation + 목록 invalidateTimelineSkeleton추가, 목록 조회나 실패시 에러 UI 추가😅 미완성 작업
다음 이슈 작업 - 타임라인 수정, 삭제, AI 요약, Sort/Filter
📢 논의 사항 및 참고 사항
.storybook/main.ts에 dummyVITE_API_BASE_URL설정. Storybook은 mock/UI 전용이라 실제 API 호출 목적 아닙니다Summary by CodeRabbit
Summary (ko-KR)