본문 바로가기
AI · 영상 제작

Cursor AI 리뷰: 워크스페이스 선택 및 데이터 연동 (Next.js 서버 액션 기반)

by 플라퉁 2025. 9. 17.
반응형

 

IT 썸네일 이미지
IT 썸네일 이미지

 

안녕하세요.
이번 글은 Cursor AI를 사용하면서 개발자로 도태되지 않기 위해 기록하는 리뷰입니다.

현재 제작 중인 웹 프로젝트는 bizmind-ai라는 개인 프로젝트이며, Next.js 서버 액션(Server Actions)을 적극적으로 활용하고 있습니다.
오늘은 워크스페이스 전환(선택) 기능을 어떻게 설계하고 구현했는지를 정리해보겠습니다.


🔑 문제 정의

사용자가 여러 워크스페이스를 가지고 있을 때, 특정 워크스페이스를 선택하면:

  • 선택 표시 (UI 반영)
  • 해당 워크스페이스에 맞는 데이터 불러오기

이 두 가지를 깔끔하게 처리하는 방법이 필요했습니다.


🛠️ 고려한 방법들

방법 1: URL 쿼리 파라미터 사용 ✅ (채택)

  • 장점
    • URL 공유 가능 (북마크/링크)
    • 브라우저 뒤로가기/앞으로가기 지원
    • 서버 컴포넌트에서 쉽게 접근
  • 단점
    • URL이 길어질 수 있음

방법 2: 쿠키 사용

  • 장점: 서버에서 쉽게 접근, URL 깔끔
  • 단점: 쿠키 크기 제한, 클라이언트에서 쿠키 설정 필요

방법 3: 세션 저장

  • 장점: 서버에서 직접 접근 가능
  • 단점: NextAuth 세션 구조 수정 필요

👉 Cursor가 추천한 방식 = URL 쿼리 파라미터 방식
저 역시 이게 가장 실용적이라고 판단했습니다.


⚙️ 구현 과정

1. 서버 액션: 워크스페이스 전환 함수

// app/actions/switchWorkspace.ts
"use server";

import { auth } from "@/lib/auth";
import prisma from "@/lib/prisma";

export async function switchWorkspace(workspaceId: string) {
  const session = await auth();

  // 사용자 소유 여부 확인
  const workspace = await prisma.workspace.findFirst({
    where: { id: workspaceId, userId: session.user.id }
  });

  if (!workspace) {
    throw new Error("잘못된 워크스페이스 접근입니다.");
  }

  return workspace.id;
}
 

 

2. 드롭다운 업데이트

  • URL에서 현재 선택된 워크스페이스 ID 가져오기
  • WorkspaceDropdown 컴포넌트에서 체크 표시

처음에는 서버 컴포넌트에서 searchParams 읽기 방식으로 시도했지만,
서버 → 클라이언트 간 props 전달 복잡성 때문에 단순화했습니다.

👉 middleware에서 pathname을 헤더에 추가하고,
👉 클라이언트 컴포넌트에서 useSearchParams, usePathname을 활용하도록 수정.

// components/WorkspaceDropdown.tsx
"use client";

import { useSearchParams } from "next/navigation";

export default function WorkspaceDropdown({ workspaces }) {
  const params = useSearchParams();
  const currentId = params.get("workspaceId");

  return (
    <select defaultValue={currentId || ""}>
      {workspaces.map(ws => (
        <option key={ws.id} value={ws.id}>
          {ws.name}
        </option>
      ))}
    </select>
  );
}
 

 

3. 각 페이지 데이터 연동

  • 헤더에서 workspaceId를 props로 전달
  • 각 페이지에서 searchParams 기반으로 쿼리 실행
// app/page.tsx
export default async function Page({ searchParams }) {
  const { workspaceId } = searchParams;

  const data = await getDataByWorkspace(workspaceId);

  return (
    <div>
      <h1>워크스페이스: {workspaceId}</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}
 

 


📝 회고

  • URL 쿼리 파라미터 방식은 확장성과 협업 측면에서 가장 실용적이었습니다.
  • 서버/클라이언트 컴포넌트 혼합 사용 시 props 전달이 복잡해질 수 있는데, next/navigation 훅으로 단순화가 가능했습니다.
  • 앞으로도 워크스페이스 기반 멀티 테넌시 구조를 발전시켜 나갈 예정입니다.

✅ 실무 팁

  • URL 파라미터로 상태 관리 → 북마크/공유/SEO 모두 이득
  • middleware 적극 활용 → 서버와 클라이언트의 경계 정리
  • 쿼리 기반 멀티 테넌시 구조는 SaaS 기본 패턴

 

 

 

반응형

댓글