[Feature/#232] 워크스페이스 역할 기반 접근 제어(RBAC) 도입#236
Conversation
|
Warning Review limit reached
More reviews will be available in 49 minutes and 48 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough워크스페이스 역할(myRole)을 중앙 상태로 추가하고, 사이드바 필터링, RoleGuard 라우트 보호, 워크스페이스 전환 시 역할 동기화, WorkspaceSetting UI 제어를 통해 ADMIN 전용 기능을 제한합니다. Changes워크스페이스 역할 기반 인가 시스템
Sequence DiagramsequenceDiagram
participant User
participant WS as WorkspaceSwitcher
participant Store as useWorkspaceStore
participant Nav as Sidebar
participant Guard as RoleGuard
participant Page as AdminPage
User->>WS: 워크스페이스 선택
WS->>Store: setSelectedOrgId(orgId)
WS->>Store: setMyRole(workspace.myRole)
Store->>Nav: myRole 변경 알림
Nav->>Nav: filterNavByRole 적용
Nav-->>User: 역할 기반 메뉴 렌더링
User->>Guard: 관리자 전용 경로 접근 시도
Guard->>Store: myRole 확인
alt myRole in allowedRoles
Guard->>Page: children 렌더
Page-->>User: 관리자 페이지 표시
else
Guard-->>User: /dashboard로 리다이렉트
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
간단 리뷰 포인트 (구조·안정성·성능·버그 중심)
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 배포 완료
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/routes/RoleGuard.tsx`:
- Around line 17-27: RoleGuard currently uses the global myRole from
useWorkspaceStore to decide access, which can be wrong when URL workspaceId
differs; change RoleGuard to read the current workspaceId via useParams() and
fetch the role for that workspace (e.g., lookup in useWorkspaceStore by
workspaceId or call a selector like getRoleByWorkspaceId(workspaceId)) and then
compare that workspace-scoped role against allowedRoles before rendering or
Navigate; keep the existing null-loading guard but base it on the
workspace-specific role or an explicit lookup result rather than the global
myRole.
In `@src/store/useWorkspaceStore.ts`:
- Around line 7-9: The store defines myRole as TMemberRole | null but setMyRole
only accepts TMemberRole, which prevents clearing the role and can leave stale
state; update the setMyRole signature to accept TMemberRole | null (e.g.,
setMyRole: (role: TMemberRole | null) => void), then update any callers of
setMyRole to pass null when clearing/resetting the role and adjust types where
the setter is used to handle null values accordingly.
🪄 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: 4844416a-6762-4069-b4dc-c24abb198f51
📒 Files selected for processing (10)
src/components/sidebar/Sidebar.tsxsrc/components/sidebar/WorkspaceSwitcher.tsxsrc/constants/sidebarNav.tssrc/hooks/auth/useIsAdmin.tssrc/layout/main/MainLayout.tsxsrc/pages/workspace/WorkspaceSetting.tsxsrc/routes/MainRoutes.tsxsrc/routes/RoleGuard.tsxsrc/store/useWorkspaceStore.tssrc/types/navigation/navItem.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/routes/RoleGuard.tsx`:
- Around line 22-29: The current guard returns null whenever workspaces is falsy
which hides the UI on API failures; update the RoleGuard logic that calls
useCoreQuery(["my-workspaces"], getMyWorkspaces) to inspect the query status
flags (e.g., isPending / isError) in addition to the data (workspaces) — when
isPending show a loading state, when isError perform an explicit redirect or
render an error UI, and only defer rendering (return null) while loading but not
on error; adjust the branches around workspaceId and workspaces to use these
flags so failures are handled deterministically.
🪄 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: c24361eb-ab4f-4f65-ae76-7bf3ec420430
📒 Files selected for processing (2)
src/routes/RoleGuard.tsxsrc/store/useWorkspaceStore.ts
Seojegyeong
left a comment
There was a problem hiding this comment.
P4: 확인했습니다. 고생하셨습니다!
🚨 관련 이슈
Closed #232
✨ 변경사항
✏️ 작업 내용
워크스페이스 Role에 따라 접근 가능한 라우트/메뉴/UI를 제한하는 역할 기반 접근 제어를 도입했습니다. (ADMIN/MEMBER)
Role-Based Access Control
1. 전역 역할 상태 관리
useWorkspaceStore에myRole,setMyRole추가MainLayout초기 로드 시 및WorkspaceSwitcher전환 시 현재 워크스페이스의myRole자동 갱신2. RoleGuard 컴포넌트 구현
AuthGuard와 동일한 패턴으로 구현myRole === null(초기화 중) 이면 랜더링 보류, 허용되지 않은 역할이면/dashboard로 리다이렉트3. ADMIN 전용 라우트 접근 제한
RoleGuard적용4. 사이드바 메뉴 필터링
INavItem타입에requiredRole?: TMemberRole필드 추가requiredRole: "ADMIN"마킹Sidebar에서myRole기준으로 랜더링 전 필터링 처리 실행5. 페이지 내 UI 읽기전용 처리
useIsAdmin()훅 추가WorkspaceSetting페이지에서 Role이 MEMBER일 경우에는 입력 필드 비활성화처리하고, 저장/삭제 버튼은 숨기 처리 구현😅 미완성 작업
N/A
📢 논의 사항 및 참고 사항
멤버관리, 플랜 및 결제는 MEMBER에서 접근이 불가능 하게 처리하였고,
WorkspaceSetting(워크스페이스 정보)에서는 접근은 가능하지만, 읽기전용으로 보이도록 설정했습니다. 추후에 완전 차단이 필요하다면 라우트에
RoleGuard추가하면 됩니다.Summary by CodeRabbit