Skip to content

[Feature/#118] 멤버 권한 변경 및 삭제 API 연동 - #138

Merged
jjjsun merged 2 commits into
developfrom
feature/#118
Mar 26, 2026
Merged

jjjsun merged 2 commits into
developfrom
feature/#118

Conversation

@jjjsun

@jjjsun jjjsun commented Mar 25, 2026

Copy link
Copy Markdown
Collaborator

🚨 관련 이슈

Closed #118

✨ 변경사항

  • 🐞 BugFix Something isn't working
  • 💻 CrossBrowsing Browser compatibility
  • 🌏 Deploy Deploy
  • 🎨 Design Markup & styling
  • 📃 Docs Documentation writing and editing (README.md, etc.)
  • ✨ Feature Feature
  • 🔨 Refactor Code refactoring
  • ⚙️ Setting Development environment setup
  • ✅ Test Test related (storybook, jest, etc.)

✏️ 작업 내용

  • 멤버 권한 변경 API PATCH /api/org/members/${orgId}/${memberId} 연동 진행
  • 멤버 삭제 API DELETE /api/org/${orgId}/members/${memberId} 연동 진행

😅 미완성 작업

팀원 초대 API 연동

📢 논의 사항 및 참고 사항

현재 UI상에서는 관리자 변경 (소유권 이전) 기능이 있지만, 관련 API는 따로 없어서 미연동상태입니다.
현재 멤버 권한이 ADMIN/MEMBER 구조로 진행되기 때문에, 관리자가 여러명이 존재할 수 있는 구조입니다.
그래서 지금 상태로면 소유권 이전이라는 개념이 존재할수 없기 때문에 기능 정의가 필요할 것으로 보입니다.

현재 MemberList에서 마지막 관리자 한명만 있을때, 마지막 관리자는 삭제할수없게 만들어둔 상태이기에, 현재 구조대로 여러명의 관리자가 있는 상태를 유지하고, 소유권 관련 UI와 기능을 삭제하는게 가장 적절해보입니다.
의견 부탁드립니다.

현재로써는 마지막 관리자가 삭제하고 싶을때는 다른 멤버에게 관리자 역할을 넘겨주고 멤버로 역할이 변경이 된 후 삭제되는 개념이기에 관리자는 무조건 1명이상이 있는 구조 입니다.

💬 리뷰어 가이드 (P-Rules)
P1: 필수 반영 (Critical) - 버그 가능성, 컨벤션 위반. 해결 전 머지 불가.
P2: 적극 권장 (Recommended) - 더 나은 대안 제시. 가급적 반영 권장.
P3: 제안 (Suggestion) - 아이디어 공유. 반영 여부는 드라이버 자율.
P4: 단순 확인/칭찬 (Nit) - 사소한 오타, 칭찬 등 피드백.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • 워크스페이스 멤버 권한 변경 기능 추가
    • 워크스페이스 멤버 삭제 기능 추가
    • 멤버 관리 작업 중 개선된 오류 및 성공 알림

@jjjsun
jjjsun requested review from Seojegyeong and YermIm March 25, 2026 18:58
@jjjsun jjjsun self-assigned this Mar 25, 2026
@jjjsun jjjsun added ✨ Feature 기능 개발 📬 API 서버 API 통신 labels Mar 25, 2026
@coderabbitai

coderabbitai Bot commented Mar 25, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

API 계층에 멤버 권한 변경 및 삭제 엔드포인트 함수를 추가하고, MemberManagement 페이지에서 React Query 뮤테이션으로 이를 연동하여 서버 상태 업데이트와 캐시 무효화를 처리합니다.

Changes

Cohort / File(s) Summary
API 엔드포인트 추가
src/api/workspace/org.ts
updateWorkspaceMemberPermission, deleteWorkspaceMember 함수 추가. 각각 PATCH, DELETE 요청을 통해 멤버 권한 변경과 삭제를 처리하며, 관련 타입 임포트 추가.
멤버 관리 페이지 뮤테이션 연동
src/pages/workspace/MemberManagement.tsx
useMutationuseQueryClient 도입. 권한 변경 및 삭제 뮤테이션을 구성하고, 각각 캐시 무효화 (workspaceMembers, workspaceMemberCount) 처리. 기존 TODO 로직을 실제 API 호출과 에러 토스트로 대체.

Sequence Diagram

sequenceDiagram
    actor User as 관리자 사용자
    participant UI as MemberManagement
    participant Mutation as React Query<br/>Mutation
    participant API as API Client
    participant Server as 서버
    participant Cache as Query Cache

    User->>UI: 권한 변경/삭제 요청
    UI->>Mutation: mutateAsync 호출
    Mutation->>API: updateWorkspaceMemberPermission<br/>또는 deleteWorkspaceMember
    API->>Server: PATCH/DELETE 요청
    Server->>Server: 멤버 권한 변경/삭제 처리
    Server-->>API: 성공 응답
    API-->>Mutation: 응답 데이터 반환
    Mutation->>Cache: invalidateQueries<br/>['workspaceMembers', orgId]
    Cache-->>UI: 쿼리 자동 재실행
    Mutation->>UI: onSuccess 콜백<br/>(토스트 표시)
    UI-->>User: UI 업데이트 완료
    
    Note over Mutation: 에러 발생 시<br/>onError → 토스트 표시
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 분

Possibly related PRs

Suggested reviewers

  • Seojegyeong
  • YermIm

추가 리뷰 포인트

상태 관리 및 로딩 처리

  • deleteMemberMutation.isPending으로 로딩 상태를 관리하는 것은 명확합니다. 다만 updateMemberRoleMutation도 로딩 상태를 UI에 반영하고 있는지 확인이 필요합니다. (예: 버튼 비활성화)

에러 처리 전략

  • getAxiosMessage(...)를 통한 에러 토스트는 일관성 있습니다. 다만 뮤테이션의 onError 콜백에서만 처리되므로, 사용자가 에러를 알 수 있도록 충분히 명확한지 검토 부탁드립니다.

캐시 무효화 범위

  • 삭제 시 workspaceMemberCount를 함께 무효화하는 것은 좋은 결정입니다. 권한 변경 시에는 카운트가 변하지 않으므로 현재 구성이 맞습니다.

타입 안전성

  • 새로운 타입(TUpdateMemberRoleRequest, 응답 타입들)이 제대로 import되어 있는지, 그리고 요청 body가 타입과 일치하는지 확인 부탁드립니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 이슈 #118과 변경사항(멤버 권한 변경 및 삭제 API 연동)을 명확하게 반영하고 있습니다.
Linked Issues check ✅ Passed PR의 코드 변경이 이슈 #118의 모든 주요 체크리스트 항목(API 타입 정의, 권한 변경/삭제 요청 구현, API 연동, 데이터 갱신, 로딩/에러 처리)을 충족합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항(org.ts API 함수 추가, MemberManagement.tsx 뮤테이션 연동)이 이슈 #118의 범위 내에 있으며, 범위를 벗어나는 변경은 없습니다.
Description check ✅ Passed PR 설명이 템플릿의 필수 항목들을 충실히 포함하고 있으며, 작업 내용과 논의 사항이 구체적으로 작성되어 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#118

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

📚 Storybook 배포 완료

항목 링크
📖 Storybook https://69a147b60a56365d9e2185ef-haxjolyges.chromatic.com/
🔍 Chromatic https://www.chromatic.com/build?appId=69a147b60a56365d9e2185ef&number=150

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/pages/workspace/MemberManagement.tsx (2)

238-247: 동일하게 useCallback 적용을 권장합니다.

handleDeleteMemberDeleteMemberModal에 전달되므로, useCallback으로 감싸서 메모이제이션하는 것이 좋습니다.

♻️ useCallback 적용 예시
- const handleDeleteMember = async (member: TWorkspaceMember) => {
+ const handleDeleteMember = useCallback(async (member: TWorkspaceMember) => {
    try {
      await deleteMemberMutation.mutateAsync(member.memberId);
      toast.success(`${member.name}님이 삭제되었습니다`);
      setIsDeleteModalOpen(false);
      setSelectedDeleteMember(null);
    } catch (error) {
      console.error("팀원 삭제 실패", error);
    }
-  };
+  }, [deleteMemberMutation]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/workspace/MemberManagement.tsx` around lines 238 - 247, The
handleDeleteMember function is passed into DeleteMemberModal but isn't memoized;
wrap it with React's useCallback to avoid unnecessary re-renders and recreate
only when its dependencies change. Update the function reference
(handleDeleteMember) to be created via useCallback and include
deleteMemberMutation.mutateAsync, toast, setIsDeleteModalOpen,
setSelectedDeleteMember (and any other state/props used) in the dependency array
so the callback stays stable and correct when those values change.

152-186: useCallback으로 감싸서 불필요한 리렌더링을 방지하는 것을 권장합니다.

handleRoleChange가 매 렌더마다 새로 생성되어 MemberList 컴포넌트에 전달됩니다. 자식 컴포넌트의 불필요한 리렌더링을 방지하려면 useCallback으로 감싸는 것이 좋습니다.

♻️ useCallback 적용 예시
- const handleRoleChange = async (
-   targetMemberId: number,
-   newRole: TMemberRole,
- ) => {
+ const handleRoleChange = useCallback(async (
+   targetMemberId: number,
+   newRole: TMemberRole,
+ ) => {
    const targetMember = members.find(
      (member) => member.memberId === targetMemberId,
    );
    // ... 기존 로직 유지
-  };
+  }, [members, adminCount, updateMemberRoleMutation]);

useCallback import도 추가해주세요:

- import { useEffect, useMemo, useRef, useState } from "react";
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";

코딩 가이드라인에 따르면 src/** 파일에서 성능과 불필요한 리렌더링을 확인해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/workspace/MemberManagement.tsx` around lines 152 - 186, The
handleRoleChange function is recreated on every render and causes unnecessary
re-renders in child components (e.g., MemberList); wrap handleRoleChange with
React.useCallback and add the correct dependency array (include members or
better derive targetMember lookup from members state/props, adminCount,
updateMemberRoleMutation, and toast) so it only changes when its dependencies
change, and add the useCallback import to the file; ensure the function
signature and behavior remain identical while using the memoized callback where
MemberList receives it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/pages/workspace/MemberManagement.tsx`:
- Around line 238-247: The handleDeleteMember function is passed into
DeleteMemberModal but isn't memoized; wrap it with React's useCallback to avoid
unnecessary re-renders and recreate only when its dependencies change. Update
the function reference (handleDeleteMember) to be created via useCallback and
include deleteMemberMutation.mutateAsync, toast, setIsDeleteModalOpen,
setSelectedDeleteMember (and any other state/props used) in the dependency array
so the callback stays stable and correct when those values change.
- Around line 152-186: The handleRoleChange function is recreated on every
render and causes unnecessary re-renders in child components (e.g., MemberList);
wrap handleRoleChange with React.useCallback and add the correct dependency
array (include members or better derive targetMember lookup from members
state/props, adminCount, updateMemberRoleMutation, and toast) so it only changes
when its dependencies change, and add the useCallback import to the file; ensure
the function signature and behavior remain identical while using the memoized
callback where MemberList receives it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9fd0ee0f-0e6f-4fe9-b362-fe1733ca8a16

📥 Commits

Reviewing files that changed from the base of the PR and between 3e90ee3 and 57be300.

📒 Files selected for processing (2)
  • src/api/workspace/org.ts
  • src/pages/workspace/MemberManagement.tsx

@Seojegyeong Seojegyeong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P4: 확인했습니다!
저도 소유권 이전 UI 제거하는게 좋을 것 같다고 생각합니다!
추가로 마지막 관리자가 자신을 삭제하려고 할 때 안내 메시지를 더 명확하게 명시하면 좋을 것 같습니다.
(ex. 관리자가 최소 1명 이상이어야 합니다. 다른 멤버를 관리자로 먼저 지정해주세요.)

@YermIm

YermIm commented Mar 26, 2026

Copy link
Copy Markdown
Collaborator

P4: 저도 소유권 관련 UI는 삭제하는 게 좋을 것 같습니다! 수고하셨습니다!

@jjjsun
jjjsun merged commit 57be300 into develop Mar 26, 2026
3 checks passed
@jjjsun
jjjsun deleted the feature/#118 branch March 26, 2026 04:23
@jjjsun

jjjsun commented Mar 26, 2026

Copy link
Copy Markdown
Collaborator Author

네~ 좋습니다! 그러면 소유권 UI는 제거하고 마지막 관리자 삭제할시에 메세지를 더 보강하겠습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📬 API 서버 API 통신 ✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [Feature] 멤버 권한 변경 / 삭제 API 연동

3 participants