studio-queries

작성자: supabase

Supabase Studio에서 데이터 가져오기를 위한 React Query 규칙입니다. 다음 경우에 사용하세요.

npx skills add https://github.com/supabase/supabase --skill studio-queries

Studio Queries & Mutations (React Query)

Follow the patterns in apps/studio/data/. Reference examples:

  • Query options: apps/studio/data/table-editor/table-editor-query.ts
  • Mutation hook: apps/studio/data/edge-functions/edge-functions-update-mutation.ts
  • Keys: apps/studio/data/edge-functions/keys.ts

Query Keys

Define a keys.ts per domain. Export *Keys helpers using array keys with as const. Never inline query keys in components.

export const edgeFunctionsKeys = {
  list: (projectRef: string | undefined) => ['projects', projectRef, 'edge-functions'] as const,
  detail: (projectRef: string | undefined, slug: string | undefined) =>
    ['projects', projectRef, 'edge-function', slug, 'detail'] as const,
}

Query Options (preferred pattern)

Use queryOptions from @tanstack/react-query. This gives type safety and works with both useQuery() and queryClient.fetchQuery().

Rules:

  • Export XVariables, XData, and XError types (prefixed with the domain name)
  • Implement a private getX(variables, signal?) function:
    • Throws if required variables are missing
    • Passes signal for cancellation
    • Calls handleError(error) on failure (which throws); returns data on success
    • Not exported — use queryClient.fetchQuery(xQueryOptions(...)) for imperative fetching
  • Export xQueryOptions() using queryOptions
  • Gate with enabled so the query doesn't run until required variables exist
  • Platform-only queries: include IS_PLATFORM from lib/constants in enabled
  • Don't add extra params to xQueryOptions — callers override by destructuring: { ...xQueryOptions(vars), enabled: true }
import { queryOptions } from '@tanstack/react-query'

import { xKeys } from './keys'
import { get, handleError } from '@/data/fetchers'
import { IS_PLATFORM } from '@/lib/constants'
import { ResponseError } from '@/types'

export type XVariables = { projectRef?: string }
export type XError = ResponseError

async function getX({ projectRef }: XVariables, signal?: AbortSignal) {
  if (!projectRef) throw new Error('projectRef is required')
  const { data, error } = await get('/v1/projects/{ref}/x', {
    params: { path: { ref: projectRef } },
    signal,
  })
  if (error) handleError(error)
  return data
}

export type XData = Awaited<ReturnType<typeof getX>>

export const xQueryOptions = ({ projectRef }: XVariables) =>
  queryOptions({
    queryKey: xKeys.list(projectRef),
    queryFn: ({ signal }) => getX({ projectRef }, signal),
    enabled: IS_PLATFORM && typeof projectRef !== 'undefined',
  })

Using Query Options in Components

import { useQuery } from '@tanstack/react-query'

import { xQueryOptions } from '@/data/x/x-query'

const { data, isPending, isError } = useQuery(xQueryOptions({ projectRef: project?.ref }))

Imperative Fetching (outside React or in callbacks)

const queryClient = useQueryClient()
const { data: project } = useSelectedProjectQuery()

const handleClick = useCallback(
  async (id: number) => {
    const data = await queryClient.fetchQuery(xQueryOptions({ id, projectRef: project?.ref }))
    // use data...
  },
  [project?.ref, queryClient]
)

Mutation Hook

  • Export a Variables type with projectRef, identifiers, and payload
  • Implement a private updateX(vars) function with required variable validation and handleError
  • Wrap in useXMutation():
    • Accepts UseMutationOptions (omit mutationFn)
    • Invalidates list() + detail() keys in onSuccess with await Promise.all([...])
    • Defaults to toast.error(...) when onError isn't provided
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
import toast from 'react-hot-toast'

import { xKeys } from './keys'

type XUpdateVariables = { projectRef: string; slug: string; payload: XPayload }

export const useXUpdateMutation = ({
  onSuccess,
  onError,
  ...options
}: UseMutationOptions<XData, XError, XUpdateVariables> = {}) => {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: updateX,
    async onSuccess(data, variables, context) {
      await Promise.all([
        queryClient.invalidateQueries({
          queryKey: xKeys.detail(variables.projectRef, variables.slug),
        }),
        queryClient.invalidateQueries({ queryKey: xKeys.list(variables.projectRef) }),
      ])
      await onSuccess?.(data, variables, context)
    },
    async onError(error, variables, context) {
      if (onError === undefined) toast.error(`Failed to update: ${error.message}`)
      else onError(error, variables, context)
    },
    ...options,
  })
}

Component Usage

  • Use React Query v5 flags: isPending for initial load, isFetching for background refetches
  • Render states explicitly in order: pending → error → success

supabase의 다른 스킬

studio-e2e-tests
supabase
Supabase Studio용 Playwright E2E 테스트를 작성하고 실행합니다. 요청 시 사용하세요.
official
vitest
supabase
Vite 기반의 Jest 호환 API를 갖춘 빠른 단위 테스트 프레임워크입니다. 테스트 작성, 모킹, 커버리지 구성 또는 테스트 작업 시 사용하세요.
official
skill-creator
supabase
모듈형 스킬을 생성하기 위한 종합 가이드로, 전문 지식과 워크플로우를 통해 Claude의 기능을 확장합니다. 스킬은 YAML 프론트매터와 마크다운 지침이 포함된 필수 SKILL.md 파일과, 목적별로 구성되고 컨텍스트를 절약하기 위해 점진적으로 로드되는 선택적 번들 리소스(스크립트, 참조 자료, 에셋)로 구성됩니다. 구체적인 사용 예시를 중심으로 스킬을 설계하고, 결정적 작업을 위한 재사용 가능한 스크립트, 도메인 지식을 위한 참조 파일, 에셋을 식별합니다...
official
supabase
supabase
Supabase와 관련된 모든 작업을 수행할 때 사용합니다. 트리거: Supabase 제품(데이터베이스, 인증, 엣지 함수, 실시간, 스토리지, 벡터, 크론, 큐); 클라이언트…
official
supabase-server
supabase
Supabase를 사용한 서버 측 코드 작성 시 — Edge Functions, Hono 앱, 웹훅 핸들러, 또는 Supabase 인증 및 클라이언트 생성이 필요한 모든 백엔드에서 사용합니다.
official
clickhouse-logs-queries
supabase
Write, review, and migrate Supabase logs queries against the ClickHouse-backed `logs` table (the `logs.all.otel` analytics endpoint). Use this whenever a task…
official
dev-toolbar-review
supabase
PR을 검토할 때 사용하세요. packages/dev-tools/, packages/common/posthog-client.ts 파일을 다루는 경우에 해당합니다.
official
e2e-studio-tests
supabase
Studio 앱에서 e2e 테스트를 실행합니다. e2e 테스트 실행, 스튜디오 테스트 실행, Playwright 테스트 실행, 또는 기능 테스트를 요청받았을 때 사용하세요.
official