supabase-query-systemlisted
Install: claude install-skill Bobi-Labs/bobi-stack-template
# Supabase Query System: Read Path
A type-safe, cached data fetching pattern for Next.js + Supabase. Query keys live in a centralized factory (`lib/query-keys.ts`) shared by both reads and mutations. A registry pairs each key with its query function. The hook enforces this pairing so you can't mismatch keys and functions or typo a key. RLS auto-filters results.
## Architecture
```
React Component
↓ useClientQuery("items") ← hooks/use-client-query.ts
↓ looks up registry → key + fn ← lib/queries/index.ts
↓ key factory builds query key ← lib/query-keys.ts
↓ fn creates browser Supabase ← lib/supabase/client.ts
↓ Supabase SDK .from().select() ← RLS auto-applies
↓ TanStack Query client cache ← staleTime + gcTime
↓ component re-renders with data
```
## Core files
### Query key factories: `lib/query-keys.ts`
Single source of truth for all cache keys. Shared by queries (pairing) and mutations (invalidation). Keys are functions so they can accept params.
```ts
export const queryKeys = {
items: () => ["items"] as const,
item: (id: string) => ["item", id] as const,
} as const;
```
### Query registry: `lib/queries/index.ts`
Pairs each key factory with its query function. The hook enforces this: you can only call `useClientQuery` with a registered name.
```ts
import { queryKeys } from "@/lib/query-keys";
import { getItems } from "./get-items";
export const queries = {
items: {
key: queryK