feat: 내 워크스페이스 목록·생성 Supabase 백엔드 연동 (#34) - #36
Merged
Conversation
📝 WalkthroughWalkthroughSupabase RPC와 환경/타입 유틸이 추가되고, 워크스페이스 목록 조회는 React Query 훅으로, 생성은 server action으로 전환됩니다. 관련 UI는 클라이언트 컴포넌트로 바뀌고, 앱 전역 Provider/Toaster와 문서 규칙이 함께 갱신됩니다. Changes워크스페이스 백엔드 연동
Estimated code review effort: 4 (Complex) | ~55 minutes Sequence Diagram(s)sequenceDiagram
participant WorkspacesPage as WorkspacesPage
participant useMyWorkspaces as useMyWorkspaces
participant SupabaseBrowserClient as SupabaseBrowserClient
participant get_my_workspaces as get_my_workspaces
WorkspacesPage->>useMyWorkspaces: 렌더
useMyWorkspaces->>SupabaseBrowserClient: rpc('get_my_workspaces', p_user_id)
SupabaseBrowserClient->>get_my_workspaces: 실행
get_my_workspaces-->>SupabaseBrowserClient: 목록 반환
SupabaseBrowserClient-->>useMyWorkspaces: data/error
useMyWorkspaces-->>WorkspacesPage: workspaces / 상태
sequenceDiagram
participant CreateWorkspaceDialog as CreateWorkspaceDialog
participant createWorkspace as createWorkspace
participant SupabaseServerClient as SupabaseServerClient
participant create_workspace as create_workspace
participant queryClient as queryClient
CreateWorkspaceDialog->>createWorkspace: submit(name, purpose, description)
createWorkspace->>createWorkspace: safeParse 입력 검증
createWorkspace->>SupabaseServerClient: rpc('create_workspace', args)
SupabaseServerClient->>create_workspace: 실행
create_workspace-->>SupabaseServerClient: workspace id
SupabaseServerClient-->>createWorkspace: { id }
createWorkspace-->>CreateWorkspaceDialog: 성공
CreateWorkspaceDialog->>queryClient: invalidateQueries(['workspaces'])
CreateWorkspaceDialog->>CreateWorkspaceDialog: /workspaces 이동
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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/entities/workspace/api/create-workspace.ts`:
- Around line 28-30: The createWorkspace flow is exposing raw Supabase error
details to the client via the thrown Error message. Update the error handling in
create-workspace.ts so the internal `error.message` is not included in the
thrown response; instead, log the detailed Supabase error server-side in the
workspace creation action and throw a generic user-facing message from
`createWorkspace` to keep internal constraint or column info out of the browser
console.
In `@src/entities/workspace/api/get-my-workspaces.ts`:
- Around line 7-9: `getMyWorkspaces` is passing `DEV_USER_ID` into the
`supabase.rpc('get_my_workspaces', ...)` call, which lets the browser control
the user identity; remove the client-supplied `p_user_id` from this flow. Update
`getMyWorkspaces` to use the authenticated user context only, either by moving
the call to a server-only path or by changing the `get_my_workspaces` RPC to
derive the user from `auth.uid()` in the database, so no client input can
influence which workspaces are returned.
In `@src/features/create-workspace/ui/CreateWorkspaceDialog.tsx`:
- Around line 63-67: The CreateWorkspaceDialog submission failure path only logs
to console and leaves users without feedback. Update the catch block in
CreateWorkspaceDialog to surface an in-UI error notification, such as a toast or
inline alert, instead of relying on console.error alone. Use the existing submit
flow around setIsSubmitting and the try/catch in CreateWorkspaceDialog to show a
clear failure message and keep the UI consistent when workspace creation fails.
In `@supabase/migrations/20260709054147_create_workspace_rpcs.sql`:
- Around line 92-99: The CASE expression in the workspace module generation
logic has no fallback, so an added workspace_purpose value could silently
produce no modules. Update the p_purpose handling in the RPC that builds the
module list to include an ELSE branch that explicitly raises an exception with a
clear message, so unexpected enum values fail fast instead of flowing into
unnest(null).
- Around line 1-105: The RPCs are currently trust-basing identity on the
client-supplied p_user_id, which allows privilege escalation through public
access. Update public.get_my_workspaces and public.create_workspace to derive
the user from auth.uid() (or otherwise restrict them to a server-only path) so
callers cannot read or create data for arbitrary users, and keep the
membership/workspace inserts bound to the authenticated identity rather than the
input parameter.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: c0fb5634-595f-48b4-b3ff-e34e8557662b
📒 Files selected for processing (22)
.env.example.gitignoredocs/conventions/supabase-convention.mdsrc/app/layout.tsxsrc/app/providers.tsxsrc/entities/workspace/api/create-workspace.tssrc/entities/workspace/api/get-my-workspaces.tssrc/entities/workspace/api/use-my-workspaces.tssrc/entities/workspace/index.tssrc/entities/workspace/model/create-workspace.schema.tssrc/entities/workspace/model/purpose.mapper.tssrc/entities/workspace/model/workspace.db.types.tssrc/features/create-workspace/model/schema.tssrc/features/create-workspace/ui/CreateWorkspaceDialog.tsxsrc/shared/api/supabase/client.tssrc/shared/api/supabase/env.tssrc/shared/api/supabase/server.tssrc/shared/config/dev-user.tssrc/shared/model/database.types.tssrc/shared/model/supabase.types.tssrc/views/workspaces/ui/WorkspacesPage.tsxsupabase/migrations/20260709054147_create_workspace_rpcs.sql
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
작업 내용
get_my_workspaces/create_workspaceRPC 함수 생성 (마이그레이션)작업 결과
/workspaces— DB 시드 3개 워크스페이스를 실데이터로 렌더 (멤버 수·업무 수·진행률 전부 DB 집계값)/workspaces/new— 템플릿 선택 → Dialog 입력 → DB에 실제 생성 (owner 멤버십 + purpose별 기본 모듈 + invite_code까지 트랜잭션 생성) → 목록에 즉시 반영설계 포인트
성능 (N+1 방지)
get_my_workspaces는 lateral 조인으로 멤버 수·업무 집계를 워크스페이스 수와 무관하게 쿼리 1회로 반환동시성
create_workspace는 plpgsql 단일 트랜잭션 (workspaces + owner 멤버십 + 모듈 생성이 전부 성공하거나 전부 롤백)invite_code(unique) 충돌 시 재시도 루프 — 랜덤 hex 16자 재생성검증 (이중 방어)
entities/workspace/model이 소유하고 feature가 공유임시 유저 규칙
shared/config/dev-user.ts의DEV_USER_ID(시드 테스트유저1) 단일 상수만 사용 — auth 연동 시 이 파일만 교체변경 사항
Added
supabase/migrations/20260709054147_create_workspace_rpcs.sql— RPC 2종 (원격 적용 완료, 버전 동기화)supabase/migrations/20260709065317_create_workspace_purpose_guard.sql— purpose 모듈 매핑 누락 시 즉시 실패 가드 (리뷰 반영)shared/ui/sonner.tsx— shadcn(sonner) 토스트, 루트 레이아웃에<Toaster />마운트 (리뷰 반영)shared/api/supabase/— browser/server 클라이언트 (@supabase/ssr) + env 검증. 배럴로 묶지 않음 (server 클라이언트의next/headers가 클라이언트 번들에 섞이면 빌드가 깨짐 — 컨벤션 문서에 명시)shared/config/dev-user.ts—DEV_USER_ID상수app/providers.tsx— tanstack-queryQueryClientProvider(루트 레이아웃에 연결)entities/workspace—use-my-workspaces쿼리 훅,create-workspace.schema(zod),purpose.mapper(DB snake ↔ 프론트 hyphen, snake 통일 리팩터링 시 제거 예정), RPC 타입(MyWorkspaceRpcRow등).env.example— 환경 변수 양식 (.env.local은 팀 Discord 참고)Changed
entities/workspace/api/get-my-workspaces.ts— mock → RPC 호출entities/workspace/api/create-workspace.ts— mock → server action ('use server') + 서버 재검증 + 에러 응답 일반화(상세는 서버 로그에만)views/workspaces/WorkspacesPage— RSC → 클라이언트 컴포넌트 +useQuery(로딩/에러 상태 포함)features/create-workspace— 생성 성공 시 목록 쿼리 캐시 무효화, 실패 시 sonner 토스트 안내(리뷰 반영), 폼 스키마는 entity 재노출로 전환docs/conventions/supabase-convention.md— "5. 데이터 페칭 규칙" 섹션 추가shared/model/database.types.ts— RPC 타입 + 복합 FK 관계 반영 (gen:types재생성)Fixed
실행화면
테스트
lint/typecheck통과)리뷰 체크리스트
feature/*->develop, 배포 시develop또는release/*->main)Type/#issue-number/description형식을 따릅니다.console.log, 주석, 임시 코드를 제거했습니다.리뷰 요청사항
use-my-workspaces.ts, 쓰기는create-workspace.ts(서버액션) 패턴. 규칙 전체는docs/conventions/supabase-convention.md5절.env.local필요합니다 (.env.example양식, 값은 Discord 공유)purpose.mapper(snake↔hyphen)는 임시입니다 — 프론트 purpose 표기 snake_case 통일 리팩터링 때 제거 예정p_user_id파라미터는 auth 연동 시auth.uid()로 일괄 교체 예정관련 이슈
Closes #34
Summary by CodeRabbit
Summary by CodeRabbit
새 기능
버그 수정
문서
Chores