Guidelines for maintaining a single, type-safe API client and centralized data fetching patterns using TanStack Query.
This skill defines the architectural standards for all API interactions within Arlis. Adhering to these rules prevents "fragmented fetching" and ensures consistency across the codebase.
lib/api/client.ts.fetch() API or direct supabase client calls for data fetching.lib/hooks/queries.ts.lib/api/client.ts)The client is organized into namespaces/modules. Each module represents a logical domain.
// Good Pattern
export const api = {
vault: {
process: (id: string) => fetcher<ProcessingResult>("/api/vault/process", { ... }),
},
applications: {
list: () => supabase.from("applications").select("*"),
get: (id: string) => supabase.from("applications").select("*").eq("id", id).single(),
}
}
Add the endpoint or database query to lib/api/client.ts.
Wrap the API method in a TanStack Query hook in lib/hooks/queries.ts.
export function useApplication(id: string) {
return useQuery({
queryKey: ['application', id],
queryFn: () => api.applications.get(id),
});
}
Call the hook in your component.
const { data, isLoading } = useApplication(id);
const res = await fetch('/api/data') inside a component.const { data } = await supabase.from('...') inside a useEffect.useQuery definitions inside components (unless highly specific and non-reusable).lib/auth/server.ts before processing requests.When using Supabase Realtime, subscribe within the centralized hooks or a dedicated state manager, ensuring the TanStack Query cache is invalidated or updated when a change occurs.