Conversation
Walkthrough카테고리 삭제 기능을 추가했다. API 레이어에 DELETE 요청 함수를 도입하고, React Query mutation 훅을 추가했으며, Sidebar에서 삭제 확인 동작을 실제 삭제 호출과 캐시 무효화로 연결했다. 일부 코드 스타일(세미콜론, 공백, 개행)을 정비했다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant S as Sidebar
participant RQ as useDeleteCategory (React Query)
participant AX as axios.deleteCategory
participant API as Server API
U->>S: 삭제 확인 클릭(id)
S->>RQ: mutate(id)
RQ->>AX: deleteCategory(id)
AX->>API: DELETE /api/v1/categories/{id}
API-->>AX: 200 OK / Error
AX-->>RQ: 응답 전달
alt 성공
RQ->>S: onSuccess 콜백
S->>RQ: invalidate "dashboardCategories"
S->>S: 모달 닫기
else 실패
RQ->>S: onError 콜백
S->>S: 오류 로그 출력
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing touches
🧪 Generate unit tests
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 Pre-merge checks❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
|
|
✅ Storybook chromatic 배포 확인: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
apps/client/src/shared/apis/axios.ts (1)
42-45: DELETE API 반환 타입/값 일관화 제안현재 raw AxiosResponse를 그대로 반환합니다. 하위 사용처가 응답 바디를 쓰지 않는다면 void를 반환하도록 단순화해도 됩니다. 선택지:
- 옵션 A(권장): void 반환
- 옵션 B: 다른 CRUD와 동일 정책으로 data/data.data만 반환하도록 표준화
예시(옵션 A):
-export const deleteCategory = async (id: number) => { - const response = await apiRequest.delete(`/api/v1/categories/${id}`); - return response; -}; +export const deleteCategory = async (id: number): Promise<void> => { + await apiRequest.delete(`/api/v1/categories/${id}`); +}apps/client/src/shared/apis/queries.ts (1)
36-40: useDeleteCategory: 키/함수 참조 간결화mutationKey를 부여해 디버깅/개발자도구 추적성을 높이고, 화살표 대신 함수 참조로 간결화 제안.
-export const useDeleteCategory = () => { - return useMutation({ - mutationFn: (id: number) => deleteCategory(id), - }); -}; +export const useDeleteCategory = () => { + return useMutation({ + mutationKey: ['category.delete'], + mutationFn: deleteCategory, + }); +};apps/client/src/shared/components/sidebar/Sidebar.tsx (1)
31-31: 변수명 충돌/가독성 개선: mutate 별칭 명확화API 함수명과 동일한
deleteCategory별칭은 혼동 여지 있습니다.mutateDeleteCategory등으로 명확히 해주세요.- const { mutate: deleteCategory } = useDeleteCategory(); + const { mutate: mutateDeleteCategory } = useDeleteCategory();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/client/src/shared/apis/axios.ts(1 hunks)apps/client/src/shared/apis/queries.ts(2 hunks)apps/client/src/shared/components/sidebar/Sidebar.tsx(4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-17T09:18:13.818Z
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#102
File: apps/extension/src/components/modalPop/ModalPop.tsx:166-172
Timestamp: 2025-07-17T09:18:13.818Z
Learning: In apps/extension/src/components/modalPop/ModalPop.tsx, the categories array should include "안 읽은 정보" (Unread Information) as the first default category that cannot be deleted. This default category is used consistently across the client-side dashboard and should be protected from deletion in the extension as well.
Applied to files:
apps/client/src/shared/components/sidebar/Sidebar.tsx
🧬 Code graph analysis (2)
apps/client/src/shared/apis/queries.ts (1)
apps/client/src/shared/apis/axios.ts (1)
deleteCategory(42-45)
apps/client/src/shared/components/sidebar/Sidebar.tsx (2)
apps/client/src/shared/apis/axios.ts (1)
deleteCategory(42-45)apps/client/src/shared/apis/queries.ts (1)
useDeleteCategory(36-40)
🔇 Additional comments (5)
apps/client/src/shared/apis/axios.ts (2)
31-35: 인터페이스 세미콜론 보강 LGTM타입 선언 마무리 일관성 좋아졌습니다.
37-40: postSignUp 반환 구조 정돈 LGTM구조분해로 data만 반환하는 형태 일관성 유지되어 좋습니다.
apps/client/src/shared/apis/queries.ts (1)
3-9: deleteCategory import 추가 LGTMapps/client/src/shared/components/sidebar/Sidebar.tsx (2)
14-19: 훅 import 추가 LGTM삭제 흐름 연결을 위한 훅 노출 사용 적절합니다.
189-190: PopupPortal onDeleteConfirm 시그니처 변경 확인 필요onDeleteConfirm이 (id: number) => void로 변경된 것으로 보입니다. PopupPortal 선언(타입 정의 포함)과 모든 사용처가 이 시그니처로 일치하는지 확인하세요 — 참조: apps/client/src/shared/components/sidebar/Sidebar.tsx (약 189-190행). 자동 검색이 실패해 검증 불가; 변경된 선언 파일 경로 또는 검색 결과를 첨부하면 재검증합니다.
| const handleDeleteCategory = (id: number) => { | ||
| deleteCategory(id, { | ||
| onSuccess: () => { | ||
| queryClient.invalidateQueries({ queryKey: ['dashboardCategories'] }); | ||
| close(); | ||
| }, | ||
| onError: (error) => { | ||
| console.error('카테고리 삭제 실패:', error); | ||
| }, | ||
| }); | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
기본 카테고리 보호 및 선택 상태 정리 필요
장기 학습 노트에 따르면 "안 읽은 정보" 기본 카테고리는 삭제 금지입니다. 또한 삭제한 항목이 현재 선택되어 있으면 선택 해제 필요합니다.
- const handleDeleteCategory = (id: number) => {
- deleteCategory(id, {
+ const handleDeleteCategory = (id: number) => {
+ const name = getCategoryName(id);
+ if (name === '안 읽은 정보') {
+ console.warn('기본 카테고리는 삭제할 수 없습니다.');
+ return;
+ }
+ mutateDeleteCategory(id, {
onSuccess: () => {
+ if (selectedCategoryId === id) {
+ setSelectedCategoryId(null);
+ }
queryClient.invalidateQueries({ queryKey: ['dashboardCategories'] });
close();
},
onError: (error) => {
console.error('카테고리 삭제 실패:', error);
},
});
};옵션 메뉴에서 기본 카테고리에는 "삭제" 버튼 자체를 숨기는 UX 보완도 가능합니다. 원하시면 OptionsMenuPortal 조건 분기 패치 제안 드리겠습니다.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/client/src/shared/components/sidebar/Sidebar.tsx around lines 87–97,
prevent deletion of the default "안 읽은 정보" category and clear selection if the
deleted category was selected: before calling deleteCategory, check whether the
target category is the default (compare id to the known defaultCategoryId or
category.isDefault flag) and bail out (or show a user-facing message) instead of
invoking delete; after successful deletion, if the app's current
selectedCategoryId equals the deleted id, call the selection reset handler
(e.g., setSelectedCategory(null) or selectDefaultCategory()) before calling
close() and invalidating queries; optionally, also hide the "Delete" option in
the OptionsMenuPortal for default categories by adding the same conditional
around the button render.
📌 Related Issues
📄 Tasks
⭐ PR Point (To Reviewer)
📷 Screenshot
Summary by CodeRabbit
신규 기능
리팩터링
스타일