-
Notifications
You must be signed in to change notification settings - Fork 0
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
[Fix] api 스키마 수정 사항 반영 #134
Conversation
Walkthrough이번 PR은 다양한 프론트엔드 컴포넌트에 대한 업데이트를 포함합니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User as 사용자
participant CI as ContentItem
participant Browser as 브라우저
User->>CI: 항목 선택 (isSelected=true)
CI->>CI: useEffect 실행하여 itemRef 확인
CI->>Browser: scrollIntoView (smooth, center)
sequenceDiagram
participant User as 사용자
participant EP as EditPost 컴포넌트
participant Modal as 모달 컴포넌트
participant API as API 서버
User->>EP: 삭제 버튼 클릭
EP->>Modal: useModal 호출하여 확인 모달 표시
User->>Modal: 삭제 확인 응답
Modal->>EP: 사용자 확인 전달
EP->>API: handleDeletePost 실행, POST 삭제 요청 전송
API-->>EP: 삭제 성공 응답
Possibly related PRs
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
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/EditDetail.tsxOops! Something went wrong! :( ESLint: 9.17.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@repo/eslint-config' imported from /eslint.config.mjs apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/_components/ContentItem/ContentItem.tsxOops! Something went wrong! :( ESLint: 9.17.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@repo/eslint-config' imported from /eslint.config.mjs apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.tsxOops! Something went wrong! :( ESLint: 9.17.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@repo/eslint-config' imported from /eslint.config.mjs
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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
🧹 Nitpick comments (28)
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/page.tsx (1)
9-13
: 서버 fetch 옵션 구성이 개선되었습니다.객체 형태로 파라미터를 전달하는 방식으로 변경되어 코드의 가독성과 유지보수성이 향상되었습니다.
다만, 타입 안정성을 위해 다음과 같은 개선을 제안드립니다:
const serverFetchOptions = getAllPostsQueryOptions({ - agentId: params.agentId, - postGroupId: params.postGroupId, + agentId: Number(params.agentId), + postGroupId: Number(params.postGroupId), tokens, });apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/page.css.ts (2)
3-8
: 스타일 속성이 적절하게 추가되었습니다.
overflow: 'hidden'
속성 추가로 컨테이너 영역을 벗어나는 콘텐츠를 제어할 수 있게 되었습니다. 이는 스크롤 관련 문제를 해결하는데 도움이 될 것으로 보입니다.하지만 반응형 디자인을 고려하여 다음과 같은 개선을 제안드립니다:
export const editDetailPage = style({ display: 'flex', - height: '100vh', + minHeight: '100vh', flexShrink: 0, overflow: 'hidden', });이렇게 수정하면 모바일 환경에서 키보드가 올라올 때 발생할 수 있는 레이아웃 이슈를 방지할 수 있습니다.
10-14
: flexColumn 스타일의 용도를 명확히 해주세요.현재
flexColumn
이라는 이름은 스타일의 목적보다는 구현 방식을 설명하고 있습니다. 이 스타일의 실제 사용 목적을 반영하는 더 명확한 이름을 사용하면 좋을 것 같습니다.-export const flexColumn = style({ +export const contentContainer = style({ display: 'flex', width: '100%', justifyContent: 'center', });apps/web/src/store/mutation/useUpdatePostMutation.ts (1)
36-40
: 에러 처리 개선이 필요합니다.현재 구현은
Error
인스턴스만 처리하고 있어, 네트워크 오류나 다른 타입의 오류는 적절히 처리되지 않을 수 있습니다.다음과 같이 에러 처리를 개선하는 것을 제안드립니다:
onError: (error) => { - if (error instanceof Error) { - toast.error(error.message); - } + const errorMessage = error instanceof Error + ? error.message + : '게시물 업데이트 중 오류가 발생했습니다.'; + toast.error(errorMessage); },apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/_components/ContentItem/ContentItem.tsx (1)
68-74
: 스크롤 동작이 잘 구현되었으나, 성능 최적화를 고려해보세요.스크롤 동작이 매끄럽게 구현되었습니다. 다만, 성능 최적화를 위해 다음과 같은 개선을 고려해보시면 좋겠습니다:
useEffect(() => { if (isSelected && itemRef.current) { - itemRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' }); + // requestAnimationFrame을 사용하여 렌더링 성능 최적화 + requestAnimationFrame(() => { + itemRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }); + }); } }, [isSelected]);apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.css.ts (2)
37-47
: 드롭다운 트리거 스타일에 접근성 개선이 필요합니다.스타일이 잘 구성되어 있으나, 접근성 향상을 위한 개선사항이 있습니다:
export const chipDropdownTrigger = style({ display: 'flex', alignItems: 'center', gap: '0.8rem', padding: '1.2rem 0.8rem', borderRadius: vars.borderRadius[12], + cursor: 'pointer', + outline: 'none', ':hover': { backgroundColor: vars.colors.grey25, }, + ':focus-visible': { + boxShadow: `0 0 0 2px ${vars.colors.grey100}`, + }, });
49-53
: 드롭다운 아이템의 상호작용 상태를 추가해주세요.사용자 경험 향상을 위해 hover와 focus 상태를 추가하는 것이 좋습니다:
export const dropdownItem = style({ display: 'flex', alignItems: 'center', gap: '1rem', + padding: '0.8rem 1.2rem', + cursor: 'pointer', + borderRadius: vars.borderRadius[8], + + ':hover': { + backgroundColor: vars.colors.grey25, + }, + ':focus-visible': { + outline: 'none', + backgroundColor: vars.colors.grey25, + }, });apps/web/src/store/mutation/useUpdatePromptMutation.ts (2)
13-17
: 타입 정의를 더 명확하게 개선할 수 있습니다.현재 구현도 잘 되어있지만, 타입 안전성을 더 높이기 위해 다음과 같은 개선을 제안합니다:
-export type MutationUpdatePrompt = { - agentId: IdParams['agentId']; - postGroupId: IdParams['postGroupId']; - postId?: IdParams['postId']; -}; +export type MutationUpdatePrompt = Pick<IdParams, 'agentId' | 'postGroupId'> & { + postId?: IdParams['postId']; +};이렇게 하면:
Pick
유틸리티 타입을 사용하여 더 간결하고 유지보수하기 쉬운 코드가 됩니다IdParams
타입이 변경되어도 자동으로 반영됩니다
32-41
: API 엔드포인트 구성의 타입 안전성을 개선할 수 있습니다.현재 구현은 잘 작동하지만, 다음과 같은 개선 사항을 제안합니다:
- API 엔드포인트를 상수로 정의하여 타입 안전성을 높이고 재사용성을 개선:
const API_ENDPOINTS = { updateEntirePrompt: (params: Pick<MutationUpdatePrompt, 'agentId' | 'postGroupId'>) => `agents/${params.agentId}/post-groups/${params.postGroupId}/posts/prompt`, updateSinglePrompt: (params: Required<MutationUpdatePrompt>) => `agents/${params.agentId}/post-groups/${params.postGroupId}/posts/${params.postId}/prompt` } as const;
- 이를 활용한 리팩토링:
- const endpoint = isEntire - ? `agents/${agentId}/post-groups/${postGroupId}/posts/prompt` - : `agents/${agentId}/post-groups/${postGroupId}/posts/${postId}/prompt`; + const endpoint = isEntire + ? API_ENDPOINTS.updateEntirePrompt({ agentId, postGroupId }) + : API_ENDPOINTS.updateSinglePrompt({ agentId, postGroupId, postId: postId! });이렇게 하면:
- 엔드포인트 문자열의 타입 안전성이 향상됩니다
- 재사용이 용이해집니다
- IDE의 자동완성 지원이 개선됩니다
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_hooks/useAdjacentPosts.tsx (4)
18-20
: 성능 최적화를 위한 제안
Object.values(posts).flat()
는 매번 새로운 배열을 생성합니다. 데이터가 큰 경우 성능에 영향을 줄 수 있습니다.다음과 같이 캐시를 활용하는 방법을 고려해보세요:
const allPosts = useMemo(() => { - return Object.values(posts).flat(); + const cache = new Map(); + const key = Object.keys(posts).join(','); + if (!cache.has(key)) { + cache.set(key, Object.values(posts).flat()); + } + return cache.get(key); }, [posts]);
8-16
: TODO 주석 처리 필요
PostStatusType
에 대한 TODO 주석이 있습니다. 이 부분을 구현하여 타입 안정성을 개선할 필요가 있습니다.이 부분의 구현을 도와드릴까요?
22-54
: 코드 가독성 개선 제안포스트 정렬 및 필터링 로직이 복잡합니다. 이를 별도의 유틸리티 함수로 분리하면 가독성과 유지보수성이 향상될 것 같습니다.
다음과 같은 구조를 제안드립니다:
const sortByStatusAndOrder = (a: Post, b: Post, statusPriority: Record<Post['status'], number>) => { if (a.status !== b.status) { return statusPriority[a.status] - statusPriority[b.status]; } return b.displayOrder - a.displayOrder; }; const filterPreviousPosts = (post: Post, currentPost: Post, statusPriority: Record<Post['status'], number>) => { if (post.status === currentPost.status) { return post.displayOrder < currentPost.displayOrder; } return statusPriority[post.status] > statusPriority[currentPost.status]; };
59-69
: URL 처리 개선 제안현재 URL 생성이 문자열 연결로 이루어지고 있습니다. 더 안전한 URL 처리를 위해 개선이 필요합니다.
다음과 같은 방식을 고려해보세요:
const routePreviousPost = () => { if (previousPost) { - router.push(`?postId=${previousPost.id}`); + const url = new URL(window.location.href); + url.searchParams.set('postId', previousPost.id); + router.push(url.search); } };packages/ui/src/components/Dropdown/DropdownIcon.tsx (1)
13-19
: 클래스명 결합 로직을 개선할 수 있습니다.템플릿 리터럴 내의 불필요한 공백을 제거하고, 조건부 클래스 결합을 위해 clsx나 classnames 같은 유틸리티 사용을 고려해보세요.
- className={`${props.className} ${dropdownIcon({ open: isOpen })}`} + className={clsx(props.className, dropdownIcon({ open: isOpen }))}packages/ui/src/components/Dropdown/Dropdown.css.ts (1)
59-72
: 아이콘 회전 애니메이션이 잘 구현되어 있습니다.transition과 transform을 사용한 아이콘 회전 구현이 적절합니다. 다만 다음과 같은 개선사항을 고려해보세요:
- 성능 최적화를 위해 transform 속성에 대해서만 transition을 적용
- 하드코딩된 시간 값을 변수로 추출하여 재사용성 향상
base: { - transition: 'transform 0.3s ease', + transition: 'transform var(--transition-duration, 0.3s) ease', },packages/ui/src/components/Dropdown/DropdownContent.tsx (2)
30-32
: 클래스명 결합 로직을 개선할 수 있습니다.템플릿 리터럴을 사용한 클래스명 결합이 복잡해 보입니다. clsx나 classnames 같은 유틸리티를 사용하여 가독성을 개선할 수 있습니다.
- const contentClassName = `${dropdownContent} ${positionAbove ? dropdownContentAbove : ''} ${ - align === 'right' ? dropdownContentRight : dropdownContentLeft - } ${className}`; + const contentClassName = clsx( + dropdownContent, + positionAbove && dropdownContentAbove, + align === 'right' ? dropdownContentRight : dropdownContentLeft, + className + );
64-64
: 불필요한 템플릿 리터럴 사용을 제거하세요.단일 변수를 템플릿 리터럴로 감싸는 것은 불필요합니다.
- className={`${contentClassName}`} + className={contentClassName}apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPromptField/EditPromptField.tsx (3)
37-40
: 상태 관리 최적화가 필요합니다.posts 배열을 매번 flat()하고 filter()하는 것은 성능에 영향을 줄 수 있습니다. 다음과 같은 최적화를 제안합니다:
- const editingPosts = Object.values(posts) - .flat() - .filter((post) => post.status === 'EDITING') - .map((post) => post.id); + const editingPosts = posts.EDITING?.map(post => post.id) ?? [];
49-67
: TODO 주석 처리가 필요합니다."제거 예정"이라고 표시된 TODO 주석이 있는 코드의 처리 계획을 명확히 해주시기 바랍니다.
이 부분의 리팩토링이 필요하시다면 도움을 드릴 수 있습니다.
69-77
: 뮤테이션 로직 단순화가 필요합니다.뮤테이션 호출 로직을 더 간단하게 리팩토링할 수 있습니다:
- if (isEntire) { - updatePrompt({ ...data, postsId: editingPostIds }); - } else { - updatePrompt({ ...data }); - } + updatePrompt({ + ...data, + ...(isEntire && { postsId: editingPostIds }) + });apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/PostEditor/PostEditor.tsx (2)
52-52
: 사용되지 않는 컨텍스트 변수 확인 요청
setLoadingPosts
가 선언되었지만, 현재 코드에는 사용되는 부분이 보이지 않습니다. 불필요한 코드라면 삭제를 검토하시고, 추후 사용 예정이다면 관련 로직이나 주석을 추가해 관리하면 좋습니다.
134-148
: 파일 업로드 유효성 검증 및 제한 로직
최대 업로드 개수, 파일 크기 제한 등을 명시적으로 처리해 사용자 오류를 예방하는 점이 좋습니다. 다만, 서버에서도 같은 제한을 처리하지 않으면 클라이언트 단에서만 통제가 이뤄질 수 있으니, 필요하다면 서버 검증 로직도 확인해 보세요.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditSidebar/EditSidebar.tsx (3)
38-38
: Context 사용 시 성능 영향 검토
DetailPageContext
의loadingPosts
사용으로 화면 갱신이 자주 발생할 수 있으므로, 큰 규모의 데이터나 잦은 업데이트가 있는지 검토하세요. 현재 코드 상에서는 큰 문제 없어 보입니다.
43-46
: 에러/로딩 상태 처리 누락 가능성
useGetAllPostsQuery
로부터 받은posts
가 아직 로딩 중이거나 에러일 때 화면 처리가 누락될 수 있습니다.isLoading
,error
등을 활용해 안전하게 분기 처리하는 것을 권장합니다.
279-279
: 쿼리 중복 호출 시 성능 고려
이미 상단에서useGetAllPostsQuery
를 사용 중인데 다시 호출하여 동일한 데이터에 접근하므로, 중복 호출이 성능에 영향을 주지 않는지 검토하십시오. 혹은 상위에서 한 번만 가져온 뒤 props로 전달하는 방식을 고려해볼 수 있습니다.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.tsx (3)
98-108
: 상태 변경 후 처리 로직 제안
handleChipClick
함수에서 상태만 업데이트하고 있는데, 성공/실패에 따른 추가 로직(알림, 롤백 등)도 고려해 보시면 좋겠습니다.
127-143
: Dropdown 내 단일 항목 value
Dropdown.Item
의value
가 동일한 "option1"로 설정되어 있어 추후 확장 시 충돌이 발생할 수 있으니, 구분이 필요한 경우 서로 다른 value를 부여해 주세요.
160-189
: Chip 상태 드롭다운 내 value 처리
각 항목이 모두 "option1"이라는 같은 값을 사용하고 있어, 선택 구분이 필요한 경우 다른 value를 사용하면 좋겠습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/_components/ContentItem/ContentItem.tsx
(3 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/EditDetail.css.ts
(0 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/EditDetail.tsx
(1 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.css.ts
(2 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.tsx
(3 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPromptField/EditPromptField.tsx
(3 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditSidebar/EditSidebar.css.ts
(2 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditSidebar/EditSidebar.tsx
(8 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/PostEditor/PostEditor.tsx
(3 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_hooks/useAdjacentPosts.tsx
(4 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/page.css.ts
(1 hunks)apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/page.tsx
(1 hunks)apps/web/src/app/globals.css
(3 hunks)apps/web/src/components/common/DNDController/context/DndContext.tsx
(0 hunks)apps/web/src/store/mutation/useModifyPostsMutation.ts
(0 hunks)apps/web/src/store/mutation/usePatchPromptMutation.ts
(0 hunks)apps/web/src/store/mutation/useUpdatePostMutation.ts
(1 hunks)apps/web/src/store/mutation/useUpdatePromptMutation.ts
(2 hunks)apps/web/src/store/query/useGroupPostsQuery.ts
(0 hunks)packages/ui/src/components/Dropdown/Dropdown.css.ts
(2 hunks)packages/ui/src/components/Dropdown/Dropdown.tsx
(2 hunks)packages/ui/src/components/Dropdown/DropdownContent.tsx
(2 hunks)packages/ui/src/components/Dropdown/DropdownIcon.tsx
(1 hunks)
💤 Files with no reviewable changes (5)
- apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/EditDetail.css.ts
- apps/web/src/components/common/DNDController/context/DndContext.tsx
- apps/web/src/store/mutation/useModifyPostsMutation.ts
- apps/web/src/store/mutation/usePatchPromptMutation.ts
- apps/web/src/store/query/useGroupPostsQuery.ts
✅ Files skipped from review due to trivial changes (1)
- apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/EditDetail.tsx
🔇 Additional comments (42)
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/page.tsx (1)
5-5
: 새로운 쿼리 옵션 import 변경이 적절합니다.
groupPostsQueryQueryOptions
에서getAllPostsQueryOptions
로의 마이그레이션이 잘 이루어졌습니다.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditSidebar/EditSidebar.css.ts (2)
5-7
: 사이드바 래퍼의 스타일 개선이 적절합니다!높이를
fit-content
로 변경하고overflow: hidden
을 추가한 것은 불필요한 스크롤을 방지하고 컨텐츠를 더 잘 제어할 수 있게 해줍니다.
21-21
: 뷰포트 높이가 작을 때를 고려해 주세요.
calc(100vh - 8rem)
는 브레드크럼의 높이를 고려한 적절한 계산이지만, 작은 화면에서 컨텐츠가 잘릴 수 있습니다.다음과 같은 개선을 고려해보세요:
- height: 'calc(100vh - 8rem)', + minHeight: 'calc(100vh - 8rem)', + height: 'fit-content',apps/web/src/store/mutation/useUpdatePostMutation.ts (1)
6-18
: 인터페이스 정의가 잘 구성되어 있습니다!타입 정의가 명확하고, 옵셔널 필드 처리가 적절하게 되어있습니다.
updateType
의 유니온 타입 사용으로 타입 안정성이 잘 보장되어 있습니다.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/_components/ContentItem/ContentItem.tsx (2)
1-16
: 클라이언트 사이드 기능 추가에 필요한 적절한 설정이 이루어졌습니다!'use client' 지시어와 필요한 훅들의 import가 올바르게 추가되었습니다.
77-77
: ref 병합이 적절하게 구현되었습니다!mergeRefs를 사용하여 외부 ref와 내부 ref를 효과적으로 결합했습니다.
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.css.ts (1)
1-2
: 테마 변수와 스타일 유틸리티 임포트가 적절히 추가되었습니다!새로 추가된 스타일에 필요한
vars
와globalStyle
임포트가 잘 구성되어 있습니다.apps/web/src/app/globals.css (3)
18-19
: 리셋된 마진 및 패딩 값 적용 확인
html, body
요소에 대해margin: 0;
과padding: 0;
을 명시적으로 설정하여 브라우저 기본 스타일로 인한 불필요한 간격 문제를 해결한 점이 좋습니다.
39-40
: 스크롤바 기본 스타일 지정
전체 선택자*
에 추가한scrollbar-width: thin;
과scrollbar-color: var(--color-grey-200, #c1ceda) transparent;
설정은 Firefox와 같이 해당 속성을 지원하는 브라우저에서 일관된 스크롤바 디자인을 제공할 수 있게 합니다.
53-76
: 웹킷 기반 브라우저용 스크롤바 커스터마이징
::-webkit-scrollbar
및 관련 선택자들을 활용하여 스크롤바의 너비, 트랙, thumb 그리고 hover 상태를 세밀하게 조정한 점이 인상적입니다. 각 섹션에 대한 주석도 상세하여 유지보수 및 향후 수정 시 가독성을 높여줍니다.apps/web/src/store/mutation/useUpdatePromptMutation.ts (1)
7-11
: 인터페이스 변경이 잘 구현되었습니다!
isEntire
와postsId
를 선택적 프로퍼티로 만든 것은 API의 유연성을 높이는 좋은 접근입니다.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_hooks/useAdjacentPosts.tsx (1)
1-1
: 타입 변경이 적절하게 이루어졌습니다!
Post[]
에서PostsByStatus
로의 타입 변경은 포스트를 상태별로 그룹화하는 새로운 API 스키마와 잘 부합합니다.Also applies to: 5-5
packages/ui/src/components/Dropdown/DropdownIcon.tsx (3)
1-7
: 클라이언트 컴포넌트 선언과 타입 정의가 적절합니다.'use client' 지시어와 필요한 의존성들이 올바르게 가져와졌습니다.
9-21
: forwardRef 구현이 잘 되어있습니다.SVG 요소에 대한 ref 전달과 컨텍스트 사용이 적절하게 구현되었습니다.
23-24
: displayName 설정이 적절합니다.디버깅을 위한 컴포넌트 이름 지정이 잘 되어있습니다.
packages/ui/src/components/Dropdown/Dropdown.tsx (3)
7-7
: 새로운 DropdownIcon 컴포넌트 import가 적절합니다.컴포넌트 구조에 맞게 import가 추가되었습니다.
44-44
: Icon 서브컴포넌트 추가가 잘 되었습니다.Dropdown 복합 컴포넌트에 Icon이 적절하게 통합되었습니다.
51-51
: 타입 익스포트가 적절합니다.DropdownIconProps 타입이 올바르게 익스포트되었습니다.
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPromptField/EditPromptField.tsx (2)
5-5
: 임포트 변경사항이 적절합니다!폼 핸들링과 API 통합 방식의 변경이 일관성 있게 반영되었습니다.
Also applies to: 12-13
32-35
:❓ Verification inconclusive
API 통합 검증이 필요합니다.
쿼리와 뮤테이션 훅의 변경사항이 새로운 API 스키마와 일치하는지 확인이 필요합니다.
Also applies to: 42-47
🏁 Script executed:
#!/bin/bash # API 스키마 변경사항 검증 rg -A 5 "useGetAllPostsQuery|useUpdatePromptMutation" --type typescriptLength of output: 108
API 통합 검증 필요
현재 PR에서 EditPromptField.tsx 파일(32-35, 그리고 42-47 라인) 내에 있는 쿼리와 뮤테이션 훅(
useGetAllPostsQuery
,useUpdatePromptMutation
)이 새로운 API 스키마와 일치하는지 확인해야 합니다. 기존에 실행한 검증 스크립트가 파일 유형 인식 문제(typescript → 인식되지 않음)로 인해 올바른 결과를 제공하지 못했습니다.아래와 같이 새 스크립트를 사용하여
.tsx
파일에 대해 검색해주시기 바랍니다:스크립트 실행 결과를 바탕으로 API 통합 변경 사항이 올바르게 반영되었는지 최종적으로 매뉴얼 검증 부탁드립니다.
🏁 Script executed:
[run_scripts] #!/bin/bash # API 스키마 변경사항 검증: tsx 파일에서 검색 rg -A 5 "useGetAllPostsQuery|useUpdatePromptMutation" -g "*.tsx"Length of output: 15340
API 통합 검증 재요청
- 파일
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPromptField/EditPromptField.tsx
에서는useGetAllPostsQuery
와useUpdatePromptMutation
이 새로운 API 스키마에 맞게 사용되고 있는 것으로 보입니다.- 다만, 다른 관련 파일(예:
/Edit.tsx
에서는useUpdatePostsMutation
이 사용됨)과의 차이가 있으므로, 전체 API 스키마와 비교 및 일관성 검증이 필요합니다.- 향후 API 문서와 비교하여 모든 변경사항이 올바르게 반영되었는지 추가 검증 부탁드립니다.
apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/PostEditor/PostEditor.tsx (6)
23-23
: 유틸 함수 임포트 확인
validateFiles
를 활용한 파일 검증 로직 강화가 이뤄지고 있어, 파일 업로드 시 에러 처리를 좀 더 체계적으로 관리할 수 있게 되었습니다.
25-25
:useUpdatePostMutation
임포트 추가
기존useModifyPostMutation
대신 새 뮤테이션 훅을 가져와 사용하는 방식으로 보입니다. 변경된 API 스펙에 맞춰 적절히 수정된 것 같습니다.
28-28
:useGetAllPostsQuery
사용으로 쿼리 교체
이전useGroupPostsQuery
사용을 대체하는 로직으로 추측됩니다. 다른 파일들과의 연동을 고려할 때, 새로운 쿼리 훅으로 일관성 있게 교체된 점이 좋습니다.
29-29
: 토스트 훅 도입
에러 메시지나 안내를toast
로 노출해 사용자 경험을 향상시키는 접근이 좋습니다.
32-32
:useToast
초기화 확인
toast
객체를 통해 업로드 제한, 파일 형식 에러 등 다양한 상황에서 유연하게 알림을 띄우고 있어 유용해 보입니다.
56-56
: 새 뮤테이션 훅 사용
이전 뮤테이션 훅을 대체해useUpdatePostMutation
에 맞춘 호출 로직이 적용되었습니다. API 측과 정상 동작 여부만 다시 한번 확인해 주세요.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditSidebar/EditSidebar.tsx (6)
32-34
: 새로운 훅 임포트 확인 및 불필요 코드 제거 검토 권장
useGetAllPostsQuery
,useUpdatePostsMutation
,PostId
를 새롭게 가져오는 점은 변경 의도에 잘 맞게 보입니다. 다만 기존useGroupPostsQuery
등 사용되지 않는 관련 코드를 프로젝트 전체에서 모두 제거했는지 확인해보시길 권장합니다.
48-48
: DndController로부터 가져오는 훅 사용
getItemsByStatus
를 통해 항목을 상태별로 구분하는 로직은 가독성과 유지보수성을 높여주어 적절해 보입니다.
73-78
: 인자 타입 명확화 및 예외 처리 고려
handleClick
의id
를PostId
로 한정해 명시적인 의도가 드러납니다. 다만 유효하지 않은id
에 대한 예외 처리가 필요한지 검토가 필요합니다.
172-172
: 수정 로직 콜백 깔끔한 재사용
onModify
콜백에서 동일한handleClick
함수를 활용해 수정 로직을 일관성 있게 유지한 점이 좋습니다.Also applies to: 211-211, 252-252
274-277
: 새로운 뮤테이션 훅 전환
useUpdatePostsMutation
으로 교체하여 최신 API 스펙에 맞춘 점이 확인됩니다. 뮤테이션 호출 시 에러 처리와 로딩 상태 표시도 함께 고려하면 좋겠습니다.
286-303
: 드래그 종료 시점 로직의 예외/성능 처리 점검
DndController
에initialItems
와key
를 설정할 때posts.data.posts
가undefined
인 경우를 대비한 방어 로직이 필요해 보입니다. 또한onDragEnd
에서 바로updatePosts
를 호출하면 서버 부하가 증가할 수 있으니, 배치 업데이트 등 최적화 방안을 고려해보시길 권장합니다.apps/web/src/app/(prompt)/edit/[agentId]/[postGroupId]/detail/_components/EditPost/EditPost.tsx (10)
4-11
: 스타일 import 확인
해당 스타일 클래스들을 모두 적절하게 활용하고 있어 문제 없어 보입니다.
19-19
: 새로운 쿼리 훅 사용
이전useGroupPostsQuery
를 대체하여useGetAllPostsQuery
를 사용하고 있으니, 마이그레이션이 전부 완료되었는지 확인해 주세요.
21-23
: Dropdown, Icon, useDeletePostMutation import
새로 import된 항목들이 이후 로직에서 정상적으로 사용되고 있어 특별한 문제는 없어 보입니다.
24-29
: 추가된 훅 및 컴포넌트 import
useModal
,Modal
,Chip
,PostStatus
,ReactNode
,useUpdatePostsMutation
등이 적절하게 도입되었으며, 정상적으로 활용되고 있습니다.
31-53
: CHIP_DROPDOWN 상태 매핑
PostStatus
열거형에 매핑된 상태가 3가지인데, 추가 상태가 필요하거나 누락된 상태가 없는지 확인해 보세요. 현재 구성은 문제 없어 보입니다.
57-57
: 모달 훅 사용
useModal
훅을 통해 모달 제어 로직을 도입한 점이 좋습니다.
70-71
: useAdjacentPosts 인자 확인
posts?.data?.posts
가 없는 상황에서 훅 내부에 예외 처리가 필요한지 검토해 주세요.
73-76
: useDeletePostMutation 사용
삭제 뮤테이션이 잘 연결되었으며, 에러 처리나 성공 후 UI 갱신 등의 추가 로직이 필요한지 고려해 보세요.
78-91
: 삭제 확인 모달 로직
삭제 전에 모달을 통해 사용자에게 재확인을 받는 로직이 적절합니다. 삭제 완료 후 페이지 이동이나 목록 재로드가 필요한지 검토해 주세요.
93-96
: useUpdatePostsMutation 사용
포스트 수정 뮤테이션이 잘 연결되었습니다. 에러 처리나 성공 시 UI 반영이 필요한지 고려해 보세요.
const { data: posts } = useGetAllPostsQuery({ | ||
agentId: Number(agentId), | ||
postGroupId: Number(postGroupId), | ||
}); | ||
const post = Object.values(posts?.data?.posts) | ||
.flat() | ||
.find((post) => post.id === Number(postId)); |
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.
Object.values(...)
사용 시 안전성 문제
posts?.data?.posts
가 undefined
일 경우 Object.values(undefined)
에서 런타임 에러가 발생할 수 있습니다.
아래와 같이 ?? {}
를 사용해 undefined
방지 로직을 추가해주세요:
- const post = Object.values(posts?.data?.posts)
- .flat()
- .find((post) => post.id === Number(postId));
+ const post = Object.values(posts?.data?.posts ?? {})
+ .flat()
+ .find((p) => p.id === Number(postId));
📝 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.
const { data: posts } = useGetAllPostsQuery({ | |
agentId: Number(agentId), | |
postGroupId: Number(postGroupId), | |
}); | |
const post = Object.values(posts?.data?.posts) | |
.flat() | |
.find((post) => post.id === Number(postId)); | |
const { data: posts } = useGetAllPostsQuery({ | |
agentId: Number(agentId), | |
postGroupId: Number(postGroupId), | |
}); | |
const post = Object.values(posts?.data?.posts ?? {}) | |
.flat() | |
.find((p) => p.id === Number(postId)); |
const defaultValue = Object.values(posts?.data.posts) | ||
.flat() | ||
.find((post) => post.id === Number(postParam))?.status; |
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.
posts?.data.posts
접근 시 안전성 보강 필요
posts?.data.posts
가 undefined
일 경우 Object.values(posts?.data.posts)
호출 시 런타임 에러가 발생할 수 있습니다. 옵셔널 체이닝 이후에도 안전하게 처리할 로직을 추가하시길 권장합니다.
예시 수정안:
- const defaultValue = Object.values(posts?.data.posts)
- .flat()
- .find((post) => post.id === Number(postParam))?.status;
+ const defaultValue = posts?.data?.posts
+ ? Object.values(posts.data.posts)
+ .flat()
+ .find((p) => p.id === Number(postParam))?.status
+ : undefined;
📝 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.
const defaultValue = Object.values(posts?.data.posts) | |
.flat() | |
.find((post) => post.id === Number(postParam))?.status; | |
const defaultValue = posts?.data?.posts | |
? Object.values(posts.data.posts) | |
.flat() | |
.find((p) => p.id === Number(postParam))?.status | |
: undefined; |
const postId = searchParams.get('postId'); | ||
const { data } = useGroupPostsQuery(Number(agentId), Number(postGroupId)); | ||
const post = data?.data?.posts.find((post) => String(post.id) === postId); | ||
|
||
console.log('dfddf', data, post); | ||
console.log('postId:', postId, 'Converted:', Number(postId)); | ||
const { data: posts } = useGetAllPostsQuery({ | ||
agentId: Number(agentId), | ||
postGroupId: Number(postGroupId), | ||
}); | ||
const post = Object.values(posts?.data?.posts) | ||
.flat() | ||
.find((post) => String(post.id) === postId); |
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.
posts?.data?.posts가 undefined일 수 있는 경우
Object.values(posts?.data?.posts)
에서 posts?.data?.posts
가 undefined
이면 런타임 오류가 발생합니다. 안전한 처리가 필요합니다.
다음과 같이 수정하여 예외를 방지할 수 있습니다:
- const post = Object.values(posts?.data?.posts)
- .flat()
- .find((post) => String(post.id) === postId);
+ const post = Object.values(posts?.data?.posts ?? {})
+ .flat()
+ .find((post) => String(post.id) === postId);
📝 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.
const postId = searchParams.get('postId'); | |
const { data } = useGroupPostsQuery(Number(agentId), Number(postGroupId)); | |
const post = data?.data?.posts.find((post) => String(post.id) === postId); | |
console.log('dfddf', data, post); | |
console.log('postId:', postId, 'Converted:', Number(postId)); | |
const { data: posts } = useGetAllPostsQuery({ | |
agentId: Number(agentId), | |
postGroupId: Number(postGroupId), | |
}); | |
const post = Object.values(posts?.data?.posts) | |
.flat() | |
.find((post) => String(post.id) === postId); | |
const postId = searchParams.get('postId'); | |
const { data: posts } = useGetAllPostsQuery({ | |
agentId: Number(agentId), | |
postGroupId: Number(postGroupId), | |
}); | |
const post = Object.values(posts?.data?.posts ?? {}) | |
.flat() | |
.find((post) => String(post.id) === postId); |
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.
고생하셨습니다!
관련 이슈
#133
변경 사항
레퍼런스
Summary by CodeRabbit
신규 기능
스타일
리팩토링