AgentSkillsCN

Centralized API Client Standards

遵循 TanStack Query 的最佳实践,打造单一、类型安全的 API 客户端,并统一数据获取模式。

SKILL.md
--- frontmatter
name: Centralized API Client Standards
description: Guidelines for maintaining a single, type-safe API client and centralized data fetching patterns using TanStack Query.

Centralized API Client Standards

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.

Core Principles

  1. Single Source of Truth: All API calls (internal and external) MUST be registered in lib/api/client.ts.
  2. No Direct Fetch: Components should NEVER use the native fetch() API or direct supabase client calls for data fetching.
  3. Type Safety: Every API method must have clearly defined Request and Response interfaces.
  4. TanStack Hooks: UI components should interact with the API through centralized TanStack Query hooks in lib/hooks/queries.ts.

Structure of the API Client (lib/api/client.ts)

The client is organized into namespaces/modules. Each module represents a logical domain.

typescript
// 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(),
    }
}

Data Fetching Workflow

1. Define the API Method

Add the endpoint or database query to lib/api/client.ts.

2. Create the Query Hook

Wrap the API method in a TanStack Query hook in lib/hooks/queries.ts.

typescript
export function useApplication(id: string) {
    return useQuery({
        queryKey: ['application', id],
        queryFn: () => api.applications.get(id),
    });
}

3. Use in Component

Call the hook in your component.

typescript
const { data, isLoading } = useApplication(id);

Forbidden Patterns

  • const res = await fetch('/api/data') inside a component.
  • const { data } = await supabase.from('...') inside a useEffect.
  • ❌ Ad-hoc useQuery definitions inside components (unless highly specific and non-reusable).

Handling Authentication

  • Client-side: Use the unified browser client. Session cookies are handled automatically by the browser.
  • Server/API side: Always verify the user using lib/auth/server.ts before processing requests.

Real-time Integration

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.