Refactor: expense/category mutation 정책을 queries 레이어로 일원화 - #203
Conversation
ExpenseEditBottomSheet/ExpenseRecordFunnel의 inline useMutation 선언과
중복 invalidateQueries 호출을 제거하고, expenseQueries 레이어에서
record/update/delete mutation과 캐시 무효화 정책을 일원화. UI는
mutate(vars, { onSuccess, onError }) 콜백으로 토스트/네비게이션 등
화면별 부수효과만 담당.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AddCategory/AddCategoryStep의 useMutation onSuccess override가 queries
레이어의 onSuccess를 가리면서 UI가 invalidateQueries를 다시 호출하던
중복 패턴을 제거. expense와 동일하게 useMutation(categoryQueries.xxx(qc))
형태로 단순화하고, 토스트·네비게이션·setSubmitSuccess 등 화면별 부수효과는
mutate(vars, { onSuccess, onError }) 콜백으로 이동.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
리팩토링 후 updateExpense/deleteExpense/getCategoryList는 expenseQueries 와 categoryQueries에서만 직접 경로로 import해 사용. api/index.ts와 이를 재내보내던 model/index.ts의 한 줄을 정리. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughExpense 관련 mutation 로직과 캐시 무효화 처리를 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
🎨 Storybook 배포 완료📚 Storybook: https://6960ec095e9394ddeaa0f9f3-safpodriho.chromatic.com/
|
|
🎉 구현한 기능 Preview: https://nitrogen-front-609n2i14l-ssilver01s-projects.vercel.app |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/features/expense/ui/ExpenseEditBottomSheet.tsx`:
- Around line 167-183: The delete dialog is closed immediately after calling
deleteMutation.mutate which hides the UI even if deletion fails; move the
setIsDeleteDialogOpen(false) call into the mutate onSuccess callback (inside
deleteMutation.mutate's onSuccess) so the dialog only closes when delete
succeeds, and ensure it is not called in onError (keep current handleApiError
behavior to leave the dialog open on failure); reference deleteMutation.mutate,
its onSuccess/onError callbacks, and setIsDeleteDialogOpen when making this
change.
🪄 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: 6b2d3521-2550-495e-b11e-ba28b7b552e6
📒 Files selected for processing (7)
apps/web/src/features/expense/api/index.tsapps/web/src/features/expense/model/expenseQueries.tsapps/web/src/features/expense/model/index.tsapps/web/src/features/expense/ui/ExpenseEditBottomSheet.tsxapps/web/src/features/expense/ui/steps/AddCategoryStep/AddCategoryStep.tsxapps/web/src/widgets/addCategory/ui/AddCategory.tsxapps/web/src/widgets/expenseRecordFunnel/ui/ExpenseRecordFunnel.tsx
💤 Files with no reviewable changes (2)
- apps/web/src/features/expense/api/index.ts
- apps/web/src/features/expense/model/index.ts
|
🎉 구현한 기능 Preview: https://nitrogen-front-oronclsln-ssilver01s-projects.vercel.app |
ssilver01
left a comment
There was a problem hiding this comment.
수고하셨어요 ~! 전체적으로 구조 개선 방향이 좋습니다 !!
mutation/invalidate를 queries 레이어로 일원화 + mutate 콜백으로 UI 사이드이팩트 분리 패턴 👍👍 덕분에 서버 상태 관리 책임이 명확해졌고, UI도 많이 가벼워졌네요 👍
invalidate 범위가 현재는 조금 넓어서 추후 최적화 여지 있어 보이고
onError 기본 처리만 하나 있으면 더 안전할 것 같습니다~!!
📝 PR 유형
🔨 리팩토링
🔔 관련된 이슈 넘버
✅ 작업 목록
1. expense mutation을 queries 레이어로 이동
expenseQueries로 일원화
expenseReportQueries.all을 공통 헬퍼(invalidateExpenseCaches)로 무효화
부수효과(토스트·네비게이션·onConfirm/onDelete 등)만 담당
2. category mutation의 중복 invalidateQueries 제거
override하면서 queries 레이어의 onSuccess를 가리고, UI가 직접 invalidateQueries를 다시 호출하던 중복
패턴을 제거
3. 미사용 api 배럴 정리
어디서도 직접 import하지 않아 파일 자체를 삭제
🍰 논의사항
컨벤션 결정 사항
다르고 카테고리 패턴과 일관됨.
그대로 받고 화면별 부수효과는 .mutate(vars, { onSuccess, onError })로 주입. 이렇게 하면 queries 레이어의
invalidate가 항상 먼저 실행되고 UI 콜백이 뒤따릅니다 (override 시에는 queries 레이어 onSuccess가 가려져서
실행되지 않음).
동작 변화 (의도된 trade-off)
setSubmitSuccess(true)는 동기적으로 navigate 전에 적용되므로 duplicate-name 플래시 방지는 그대로
동작합니다. navigate 후 페이지가 카테고리 list freshness에 의존하지 않아 UX 영향 없음.
무효화는 queries 레이어에 있으므로 항상 실행되며, submit 중 isPending으로 버튼이 disabled되어 정상
플로우에서 언마운트 트리거 가능성은 낮습니다.
후속 cleanup 후보 (이번 PR 범위 외)
site는 전달하므로 문제 없음. 안전망 필요 시 fallback 추가 검토.
차이로 의도된 부분.
📷 ETC
기대 효과:
Summary by CodeRabbit
릴리스 노트