-
Notifications
You must be signed in to change notification settings - Fork 2
✨ feat: 컬럼 관리 기능 (생성/수정/삭제) #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
""" Walkthrough이 변경 사항은 대시보드의 컬럼(열) 관리 기능을 모달 기반 UI로 구현합니다. 컬럼 생성, 수정, 삭제를 위한 모달 컴포넌트, API 함수, 커스텀 훅, 상태 관리(store) 등이 추가되었으며, 기존 컬럼 관련 컴포넌트와 API 호출부는 인증된 HTTP 클라이언트로 일원화되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DashboardPage
participant ColumnModalRenderer
participant useColumnModalStore
participant API
User->>DashboardPage: "새 컬럼 추가" 버튼 클릭
DashboardPage->>useColumnModalStore: openModal('create', {dashboardId})
DashboardPage->>ColumnModalRenderer: 렌더링 트리거
ColumnModalRenderer->>CreateColumnModal: 모달 표시
User->>CreateColumnModal: 컬럼명 입력 후 제출
CreateColumnModal->>API: postColumn API 호출
API-->>CreateColumnModal: 생성 결과 반환
CreateColumnModal->>useColumnModalStore: closeModal()
CreateColumnModal-->>DashboardPage: 컬럼 목록 갱신
sequenceDiagram
participant User
participant Column
participant useColumnModalStore
participant ColumnModalRenderer
participant EditColumnModal
participant API
User->>Column: 설정 아이콘 클릭
Column->>useColumnModalStore: openModal('edit', {dashboardId, columnId, columnTitle})
Column->>ColumnModalRenderer: 렌더링 트리거
ColumnModalRenderer->>EditColumnModal: 모달 표시
User->>EditColumnModal: 컬럼명 수정 후 제출
EditColumnModal->>API: updateColumn API 호출
API-->>EditColumnModal: 수정 결과 반환
EditColumnModal->>useColumnModalStore: closeModal()
EditColumnModal-->>Column: 컬럼 목록 갱신
sequenceDiagram
participant User
participant EditColumnModal
participant useColumnModalStore
participant ColumnModalRenderer
participant DeleteColumnConfirmModal
participant API
User->>EditColumnModal: "삭제" 버튼 클릭
EditColumnModal->>useColumnModalStore: openModal('deleteConfirm', {dashboardId, columnId})
ColumnModalRenderer->>DeleteColumnConfirmModal: 모달 표시
User->>DeleteColumnConfirmModal: "삭제" 버튼 클릭
DeleteColumnConfirmModal->>API: deleteColumn API 호출
API-->>DeleteColumnConfirmModal: 삭제 결과 반환
DeleteColumnConfirmModal->>useColumnModalStore: closeModal()
DeleteColumnConfirmModal-->>EditColumnModal: 컬럼 목록 갱신
Possibly related issues
Suggested reviewers
Poem
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
npm error Exit handler never called! 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
src/app/features/dashboard_Id/components/EditColumnModal.tsx (1)
16-17: API 호출 최적화 고려사항CreateColumnModal과 동일한 이슈가 있습니다.
modalData가 없을 때 불필요한 API 호출이 발생할 수 있습니다.
🧹 Nitpick comments (9)
src/app/features/dashboard_Id/api/postColumn.ts (1)
5-13: API 함수의 에러 처리 방식 확인현재 API 함수에서는 에러 처리를 하지 않고 상위 레이어(hook)에서 처리하고 있습니다. 이는 일관된 패턴이라면 괜찮지만, 네트워크 오류나 HTTP 응답 검증 등 공통적인 에러 처리가 필요할 수 있습니다.
src/app/features/dashboard_Id/components/ColumnModalRenderer.tsx (1)
8-16: 깔끔한 모달 관리 패턴조건부 렌더링을 활용한 중앙집중식 모달 관리 방식이 깔끔합니다. early return 패턴으로 가독성도 좋고, 모달 상태 관리가 Zustand 스토어로 잘 분리되어 있습니다.
성능 최적화를 위해 동적 import를 고려해볼 수 있습니다:
+import { lazy, Suspense } from 'react' + +const CreateColumnModal = lazy(() => import('./CreateColumnModal')) +const EditColumnModal = lazy(() => import('./EditColumnModal')) +const DeleteColumnConfirmModal = lazy(() => import('./DeleteColumnConfirmModal')) export default function ColumnModalRenderer() { const { modalType } = useColumnModalStore() - if (modalType === 'create') return <CreateColumnModal /> - if (modalType === 'edit') return <EditColumnModal /> - if (modalType === 'deleteConfirm') return <DeleteColumnConfirmModal /> + if (modalType === 'create') return <Suspense fallback={<div>Loading...</div>}><CreateColumnModal /></Suspense> + if (modalType === 'edit') return <Suspense fallback={<div>Loading...</div>}><EditColumnModal /></Suspense> + if (modalType === 'deleteConfirm') return <Suspense fallback={<div>Loading...</div>}><DeleteColumnConfirmModal /></Suspense> return null }src/app/features/dashboard_Id/hooks/useUpdateColumn.ts (1)
30-33: 다국어 대응을 고려해보세요중복 검사에서 '중복'과 'duplicate' 두 가지 키워드를 확인하고 있는데, 서버 응답의 일관성을 보장하거나 더 견고한 에러 코드 기반 검사를 고려해보세요.
- if ( - serverMessage?.includes('중복') || - serverMessage?.includes('duplicate') - ) { + // 서버에서 특정 에러 코드를 반환하는 경우 + if (error.response?.status === 409) { toast.error('중복된 컬럼 이름입니다')src/app/features/dashboard_Id/store/useColumnModalStore.ts (1)
5-9: 인터페이스 중복을 확인해보세요ColumnModalData 인터페이스가 Column.type.ts에도 동일하게 정의되어 있는 것으로 보입니다. 타입 정의의 일관성을 위해 하나의 파일에서 export하여 재사용하는 것을 고려해보세요.
다음 스크립트로 중복된 인터페이스 정의를 확인하겠습니다:
#!/bin/bash # Description: Check for duplicate ColumnModalData interface definitions # Search for ColumnModalData interface definitions rg -A 5 "interface ColumnModalData"src/app/features/dashboard_Id/Column/Column.tsx (1)
30-31: 사용하지 않는 상태 변수를 정리해보세요openCreateColumn과 oepnConfigColumn 상태 변수들이 사용되지 않는 것 같습니다. 코드 정리를 위해 제거를 고려해보세요.
- const [openCreateColumn, setOpenCreateColumn] = useState(false) //page.tsx - const [oepnConfigColumn, setConfigColumn] = useState(false)또한 oepnConfigColumn에 오타가 있는 것 같습니다 (open이 oepn으로 표기됨).
src/app/features/dashboard_Id/components/CreateColumnModal.tsx (2)
16-17: API 호출 최적화 고려사항
useColumns훅이modalData?.dashboardId || 0로 호출되고 있는데,modalData가 없을 때dashboardId가 0으로 설정되어 불필요한 API 호출이 발생할 수 있습니다.조건부 쿼리 사용을 고려해보세요:
- const { data: columns } = useColumns(modalData?.dashboardId || 0) + const { data: columns } = useColumns(modalData?.dashboardId || 0, { + enabled: !!modalData?.dashboardId + })
41-41: 동적 높이 클래스명 개선하드코딩된 높이 클래스명
h-286,h-266은 유지보수성이 떨어집니다.CSS 변수나 상수로 관리하는 것을 고려해보세요:
- const modalHeight = hasError ? 'h-286' : 'h-266' + const MODAL_HEIGHT = { + default: 'h-266', + withError: 'h-286' + } as const + const modalHeight = hasError ? MODAL_HEIGHT.withError : MODAL_HEIGHT.defaultsrc/app/features/dashboard_Id/components/DeleteColumnConfirmModal.tsx (1)
63-70: 버튼 접근성 개선 필요취소 버튼에
disabled속성은 있지만 시각적 피드백이 없습니다.취소 버튼도 제출 중일 때 시각적 피드백을 제공하세요:
<button type="button" onClick={closeModal} disabled={isSubmitting} - className="BG-white Border-btn Text-gray h-54 w-256 rounded-8 px-16 py-10 text-16 font-medium" + className={`BG-white Border-btn Text-gray h-54 w-256 rounded-8 px-16 py-10 text-16 font-medium ${ + isSubmitting ? 'cursor-not-allowed opacity-50' : '' + }`} >src/app/features/dashboard_Id/components/EditColumnModal.tsx (1)
98-98: 모달 컨테이너 스타일링 일관성다른 모달들과 달리
rounded-16을 사용하고 있습니다. 일관성을 위해 확인이 필요합니다.다른 모달들과 동일한
rounded-8을 사용하는 것이 일관성에 도움이 될 수 있습니다:- <div className={`BG-white ${modalHeight} w-568 rounded-16 p-24`}> + <div className={`BG-white ${modalHeight} w-568 rounded-8 p-24`}>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
src/app/dashboard/[id]/page.tsx(5 hunks)src/app/features/dashboard_Id/Column/Column.tsx(4 hunks)src/app/features/dashboard_Id/api/deleteColumn.ts(1 hunks)src/app/features/dashboard_Id/api/fetchMembers.ts(1 hunks)src/app/features/dashboard_Id/api/postCard.ts(1 hunks)src/app/features/dashboard_Id/api/postCardImage.ts(2 hunks)src/app/features/dashboard_Id/api/postColumn.ts(1 hunks)src/app/features/dashboard_Id/api/putCard.ts(2 hunks)src/app/features/dashboard_Id/api/updateCardColumn.ts(1 hunks)src/app/features/dashboard_Id/api/updateColumn.ts(1 hunks)src/app/features/dashboard_Id/components/ColumnModalRenderer.tsx(1 hunks)src/app/features/dashboard_Id/components/CreateColumnModal.tsx(1 hunks)src/app/features/dashboard_Id/components/DeleteColumnConfirmModal.tsx(1 hunks)src/app/features/dashboard_Id/components/EditColumnModal.tsx(1 hunks)src/app/features/dashboard_Id/hooks/useCreateColumn.ts(1 hunks)src/app/features/dashboard_Id/hooks/useDeleteColumn.ts(1 hunks)src/app/features/dashboard_Id/hooks/useUpdateColumn.ts(1 hunks)src/app/features/dashboard_Id/store/useColumnModalStore.ts(1 hunks)src/app/features/dashboard_Id/type/Column.type.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (11)
src/app/features/dashboard_Id/api/postCard.ts (1)
src/app/features/dashboard_Id/type/CardFormData.type.ts (1)
CardFormData(11-13)
src/app/features/dashboard_Id/api/fetchMembers.ts (1)
src/app/features/dashboard_Id/type/Member.type.ts (2)
Member(1-10)MembersResponse(11-14)
src/app/features/dashboard_Id/api/postColumn.ts (1)
src/app/features/dashboard_Id/type/Column.type.ts (2)
CreateColumnRequest(15-18)CreateColumnResponse(21-27)
src/app/features/dashboard_Id/api/updateColumn.ts (1)
src/app/features/dashboard_Id/type/Column.type.ts (2)
UpdateColumnRequest(30-32)UpdateColumnResponse(35-41)
src/app/features/dashboard_Id/hooks/useDeleteColumn.ts (2)
src/app/features/dashboard_Id/type/Column.type.ts (1)
DeleteColumnVariables(50-53)src/app/features/dashboard_Id/api/deleteColumn.ts (1)
deleteColumn(3-7)
src/app/features/dashboard_Id/hooks/useCreateColumn.ts (2)
src/app/features/dashboard_Id/type/Column.type.ts (2)
CreateColumnResponse(21-27)CreateColumnRequest(15-18)src/app/features/dashboard_Id/api/postColumn.ts (1)
postColumn(5-13)
src/app/features/dashboard_Id/hooks/useUpdateColumn.ts (2)
src/app/features/dashboard_Id/type/Column.type.ts (2)
UpdateColumnResponse(35-41)UpdateColumnVariables(44-48)src/app/features/dashboard_Id/api/updateColumn.ts (1)
updateColumn(5-14)
src/app/features/dashboard_Id/Column/Column.tsx (3)
src/app/features/dashboard_Id/type/Column.type.ts (1)
Column(1-8)src/app/features/dashboard_Id/api/useCards.ts (1)
useCards(7-12)src/app/features/dashboard_Id/store/useColumnModalStore.ts (1)
useColumnModalStore(18-23)
src/app/features/dashboard_Id/components/EditColumnModal.tsx (3)
src/app/features/dashboard_Id/store/useColumnModalStore.ts (1)
useColumnModalStore(18-23)src/app/features/dashboard_Id/api/useColumns.ts (1)
useColumns(6-11)src/app/features/dashboard_Id/hooks/useUpdateColumn.ts (1)
useUpdateColumn(11-40)
src/app/features/dashboard_Id/type/Column.type.ts (1)
src/app/features/dashboard_Id/Column/Column.tsx (1)
Column(15-124)
src/app/features/dashboard_Id/store/useColumnModalStore.ts (1)
src/app/features/dashboard_Id/type/Column.type.ts (1)
ColumnModalData(56-60)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: eslint-check
🔇 Additional comments (39)
src/app/features/dashboard_Id/api/postCard.ts (1)
1-1: 인증된 HTTP 클라이언트 사용으로 개선되었습니다.테스트용 클라이언트에서 인증된 HTTP 클라이언트로 변경한 것은 프로덕션 환경에서의 보안과 적절한 접근 제어를 위한 올바른 접근입니다.
Also applies to: 10-10
src/app/features/dashboard_Id/api/putCard.ts (1)
1-1: 일관된 인증 클라이언트 사용으로 개선되었습니다.카드 수정 API도 인증된 HTTP 클라이언트를 사용하도록 변경되어 다른 API 함수들과 일관성을 유지하고 있습니다.
Also applies to: 13-13
src/app/features/dashboard_Id/api/fetchMembers.ts (1)
1-1: 멤버 데이터 조회에 적절한 인증 처리가 적용되었습니다.멤버 정보는 민감한 데이터이므로 인증된 HTTP 클라이언트를 사용하는 것이 적절하며, TypeScript 제네릭도 올바르게 적용되어 있습니다.
Also applies to: 6-6
src/app/features/dashboard_Id/api/postCardImage.ts (1)
1-1: 파일 업로드에 인증 처리가 적절히 적용되었습니다.카드 이미지 업로드는 서버 리소스를 생성하는 작업이므로 인증된 HTTP 클라이언트 사용이 필수적입니다. 기존의 multipart/form-data 헤더 설정도 올바르게 유지되고 있습니다.
Also applies to: 10-18
src/app/features/dashboard_Id/api/updateCardColumn.ts (1)
1-1: 카드 이동 기능에 인증 처리가 적절히 구현되었습니다.카드의 컬럼 간 이동은 중요한 데이터 조작 작업이므로 인증된 HTTP 클라이언트 사용이 필수적입니다. TypeScript 타입 지정도 정확하게 유지되고 있습니다.
Also applies to: 8-13
src/app/features/dashboard_Id/api/postColumn.ts (1)
8-12: 환경 변수를 통한 URL 구성 시 보안 고려사항 검토 필요
process.env.NEXT_PUBLIC_TEAM_ID를 직접 URL에 사용하고 있습니다.NEXT_PUBLIC_접두사가 붙은 환경 변수는 클라이언트 측에서 노출되므로 민감한 정보가 포함되지 않았는지 확인이 필요합니다.다음 스크립트로 환경 변수 사용 패턴을 검증해보세요:
#!/bin/bash # 다른 API 함수들에서 동일한 패턴을 사용하는지 확인 rg -A 3 "process\.env\.NEXT_PUBLIC_TEAM_ID" --type tssrc/app/features/dashboard_Id/api/deleteColumn.ts (1)
3-7: 일관된 API 패턴으로 구현됨다른 API 함수들과 동일한 패턴으로 구현되어 일관성이 좋습니다. HTTP 클라이언트와 URL 구성 방식이 통일되어 있어 유지보수에 도움이 될 것 같습니다.
src/app/features/dashboard_Id/api/updateColumn.ts (1)
5-14: 타입 안전성과 일관성 확보
UpdateColumnRequest와UpdateColumnResponse인터페이스를 활용하여 타입 안전성을 확보했고, 다른 API 함수들과 일관된 패턴으로 구현되어 있습니다. REST API 컨벤션에 맞게 PUT 메서드를 사용한 점도 좋습니다.src/app/features/dashboard_Id/hooks/useCreateColumn.ts (1)
11-22: React Query 패턴의 올바른 활용
useMutation의 제네릭 타입 정의가 정확하고, 성공 시 캐시 무효화를 통해 UI가 즉시 업데이트되도록 구현한 점이 훌륭합니다. 변수의dashboardId를 사용한 쿼리 키 무효화도 적절합니다.src/app/dashboard/[id]/page.tsx (5)
10-11: 모달 관리 시스템이 잘 구성되었습니다ColumnModalRenderer와 useColumnModalStore의 import가 적절하며, 중앙화된 모달 상태 관리 패턴을 따르고 있습니다.
30-32: 컬럼 생성 핸들러 구현이 깔끔합니다handleCreateColumn 함수가 적절한 컨텍스트(dashboardId)와 함께 create 모달을 여는 로직이 명확합니다.
155-157: dashboardId prop 전달이 적절합니다Column 컴포넌트에 dashboardId를 전달하여 모달 작업을 가능하게 하는 변경사항이 잘 구현되었습니다.
159-162: 사용자 인터랙션 개선이 좋습니다"새로운 컬럼 추가하기" 버튼에 onClick 핸들러를 추가하여 모달 기반 워크플로우를 시작하는 구현이 직관적입니다.
176-176: 모달 렌더러 배치가 적절합니다ColumnModalRenderer를 JSX 트리 끝에 배치하여 모달이 다른 UI 요소들 위에 렌더링되도록 한 것이 좋습니다.
src/app/features/dashboard_Id/hooks/useDeleteColumn.ts (4)
11-15: 타입 정의가 정확합니다useMutation의 제네릭 타입 정의가 적절하며, AxiosError 타입에 서버 메시지 구조를 포함한 것이 좋습니다.
16-16: mutation 함수 구현이 간결합니다destructuring을 사용하여 columnId만 추출해 deleteColumn API를 호출하는 방식이 깔끔합니다.
17-26: 캐시 무효화 전략이 포괄적입니다컬럼 목록과 해당 컬럼의 카드 데이터 모두 무효화하여 UI 일관성을 보장하는 전략이 훌륭합니다.
30-33: 에러 처리가 사용자 친화적입니다서버 메시지를 우선적으로 사용하고, 없을 경우 기본 메시지를 제공하는 에러 처리 로직이 적절합니다.
src/app/features/dashboard_Id/hooks/useUpdateColumn.ts (3)
14-18: 타입 정의가 명확합니다UpdateColumnResponse와 UpdateColumnVariables를 사용한 제네릭 타입 정의가 정확하며, 타입 안전성을 보장합니다.
19-19: mutation 함수 구조가 일관성 있습니다columnId와 title을 destructuring하여 updateColumn API에 전달하는 방식이 명확합니다.
30-37: 중복 검사 로직이 사용자 경험을 향상시킵니다서버 메시지에서 중복 키워드를 검사하여 특별한 에러 메시지를 제공하는 로직이 사용자 친화적입니다.
src/app/features/dashboard_Id/store/useColumnModalStore.ts (2)
3-3: 모달 타입 정의가 명확합니다ColumnModalType의 유니온 타입 정의가 명확하며, null을 포함하여 모달이 닫힌 상태를 표현하는 것이 적절합니다.
18-23: Zustand 구현이 간결하고 효율적입니다openModal과 closeModal 액션이 명확하며, 상태 업데이트 로직이 직관적입니다. 모달 상태 관리에 적합한 구조입니다.
src/app/features/dashboard_Id/Column/Column.tsx (3)
15-21: 컴포넌트 인터페이스 확장이 적절합니다dashboardId prop을 추가하여 모달 작업을 지원하는 인터페이스 변경이 깔끔하게 구현되었습니다.
33-39: 모달 열기 로직이 명확합니다handleConfigColumn 함수가 필요한 모든 컨텍스트(dashboardId, columnId, columnTitle)를 전달하며 edit 모달을 여는 구현이 정확합니다.
91-92: 사용자 경험 개선이 좋습니다설정 아이콘에 cursor-pointer 클래스를 추가하여 클릭 가능함을 시각적으로 나타내는 것이 좋은 UX 개선입니다.
src/app/features/dashboard_Id/components/CreateColumnModal.tsx (2)
105-107: 입력 필드 스타일링 일관성에러 상태에 따른 테두리 색상 변경 로직이 올바르게 구현되어 있습니다.
114-123: 에러 메시지 표시 로직중복 컬럼명과 최대 개수 제한에 대한 에러 메시지가 적절히 구현되어 있습니다.
src/app/features/dashboard_Id/components/DeleteColumnConfirmModal.tsx (2)
19-20: null 체크 로직
modalData?.columnId체크가 올바르게 구현되어 있어 안전합니다.
73-83: 삭제 버튼 구현삭제 버튼의 비활성화 상태와 시각적 피드백이 적절히 구현되어 있습니다.
src/app/features/dashboard_Id/components/EditColumnModal.tsx (4)
33-38: 중복 체크 로직 검증현재 컬럼을 제외한 중복 체크 로직이 올바르게 구현되어 있습니다.
column.id !== modalData?.columnId조건으로 현재 편집 중인 컬럼을 제외하고 있습니다.
41-45: 버튼 활성화 조건 로직수정 버튼의 비활성화 조건이 적절히 구현되어 있습니다. 특히
title.trim() === modalData?.columnTitle조건으로 기존과 동일한 값일 때를 처리한 것이 좋습니다.
80-82: 모달 전환 로직삭제 확인 모달로 전환하는 로직이 적절히 구현되어 있습니다.
modalData!를 그대로 전달하는 것이 합리적입니다.
132-137: 에러 메시지 스타일링에러 메시지에
Text-error클래스를 사용하고 있어 다른 모달들과 일관성이 있습니다.src/app/features/dashboard_Id/type/Column.type.ts (5)
14-27: CreateColumn 인터페이스생성 요청과 응답 인터페이스가 적절히 정의되어 있습니다. 요청에는 필요한 필드만, 응답에는 서버에서 생성되는 필드들이 포함되어 있습니다.
29-41: UpdateColumn 인터페이스수정 요청은
title만 필요하고, 응답은 전체 엔티티를 반환하는 구조가 합리적입니다.
43-53: Hook 변수 타입 정의
UpdateColumnVariables와DeleteColumnVariables에서dashboardId가 캐시 무효화용으로 사용되는 것이 명확히 주석으로 표시되어 있어 좋습니다.
55-60: ColumnModalData 인터페이스모달에서 사용할 데이터 구조가 적절히 정의되어 있습니다.
columnId와columnTitle이 선택적 필드로 설정된 것이 create/edit 모달 모두에서 사용 가능하도록 한 좋은 설계입니다.
9-12: ColumnsResponse 인터페이스 수정
result필드가 추가되었습니다. API 응답 구조와 일치하는지 확인이 필요합니다.API 응답 구조를 확인하여
result필드가 실제로 필요한지 검증해보세요:#!/bin/bash # Description: API 응답 구조에서 result 필드 사용 확인 # ColumnsResponse를 사용하는 곳에서 result 필드 사용 여부 확인 rg -A 5 -B 5 "ColumnsResponse|result.*string"
| onError: (error) => { | ||
| const serverMessage = error.response?.data?.message | ||
|
|
||
| // 서버에서 오는 에러 메시지에 따라 분기 | ||
| if ( | ||
| serverMessage?.includes('중복') || | ||
| serverMessage?.includes('duplicate') | ||
| ) { | ||
| toast.error('중복된 컬럼 이름입니다') | ||
| } else if ( | ||
| serverMessage?.includes('최대') || | ||
| serverMessage?.includes('maximum') | ||
| ) { | ||
| toast.error('컬럼은 최대 10개까지 생성 가능합니다') | ||
| } else { | ||
| toast.error(serverMessage || '컬럼 생성 중 오류가 발생했습니다') | ||
| } | ||
| }, | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
에러 처리 로직의 견고성 개선 검토
서버 메시지 문자열 매칭을 통한 에러 분기 처리가 구현되어 있지만, 문자열 기반 판단은 서버 메시지 변경 시 취약할 수 있습니다.
더 견고한 에러 처리를 위해 다음과 같은 개선을 고려해보세요:
onError: (error) => {
- const serverMessage = error.response?.data?.message
+ const serverMessage = error.response?.data?.message
+ const errorCode = error.response?.data?.code
// 에러 코드 우선, 메시지는 fallback으로 사용
- if (
- serverMessage?.includes('중복') ||
- serverMessage?.includes('duplicate')
- ) {
+ if (errorCode === 'DUPLICATE_COLUMN_NAME' ||
+ serverMessage?.includes('중복') ||
+ serverMessage?.includes('duplicate')) {
toast.error('중복된 컬럼 이름입니다')
- } else if (
- serverMessage?.includes('최대') ||
- serverMessage?.includes('maximum')
- ) {
+ } else if (errorCode === 'MAX_COLUMNS_EXCEEDED' ||
+ serverMessage?.includes('최대') ||
+ serverMessage?.includes('maximum')) {
toast.error('컬럼은 최대 10개까지 생성 가능합니다')
} else {
toast.error(serverMessage || '컬럼 생성 중 오류가 발생했습니다')
}
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onError: (error) => { | |
| const serverMessage = error.response?.data?.message | |
| // 서버에서 오는 에러 메시지에 따라 분기 | |
| if ( | |
| serverMessage?.includes('중복') || | |
| serverMessage?.includes('duplicate') | |
| ) { | |
| toast.error('중복된 컬럼 이름입니다') | |
| } else if ( | |
| serverMessage?.includes('최대') || | |
| serverMessage?.includes('maximum') | |
| ) { | |
| toast.error('컬럼은 최대 10개까지 생성 가능합니다') | |
| } else { | |
| toast.error(serverMessage || '컬럼 생성 중 오류가 발생했습니다') | |
| } | |
| }, | |
| }) | |
| onError: (error) => { | |
| const serverMessage = error.response?.data?.message | |
| const errorCode = error.response?.data?.code | |
| // 서버에서 오는 에러 메시지에 따라 분기 | |
| // 에러 코드 우선, 메시지는 fallback으로 사용 | |
| if (errorCode === 'DUPLICATE_COLUMN_NAME' || | |
| serverMessage?.includes('중복') || | |
| serverMessage?.includes('duplicate')) { | |
| toast.error('중복된 컬럼 이름입니다') | |
| } else if (errorCode === 'MAX_COLUMNS_EXCEEDED' || | |
| serverMessage?.includes('최대') || | |
| serverMessage?.includes('maximum')) { | |
| toast.error('컬럼은 최대 10개까지 생성 가능합니다') | |
| } else { | |
| toast.error(serverMessage || '컬럼 생성 중 오류가 발생했습니다') | |
| } | |
| }, |
🤖 Prompt for AI Agents
In src/app/features/dashboard_Id/hooks/useCreateColumn.ts between lines 24 and
42, the error handling relies on matching substrings in server error messages,
which is fragile if server messages change. To improve robustness, refactor the
error handling to use standardized error codes or error types returned from the
server instead of string matching. Update the server API or error response
parsing to extract these codes and use them in the onError logic to determine
the appropriate toast error message.
Insung-Jo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다!
📌 변경 사항 개요
대시보드 상세 페이지의 대시보드 컬럼의 생성, 수정, 삭제할 수 있는 관리 기능 구현
✨ 요약
📝 상세 내용
컬럼 관리
API 및 데이터 관리
사용자 경험
🔗 관련 이슈
#97
🖼️ 스크린샷
✅ 체크리스트
💡 참고 사항
API 엔드포인트:
POST /{teamId}/columns(컬럼 생성)PUT /{teamId}/columns/{columnId}(컬럼 수정)DELETE /{teamId}/columns/{columnId}(컬럼 삭제)추후 개선사항:
Summary by CodeRabbit