SECURITY REVIEW
Not yet assessed
Review the original instructions and requested permissions before installing.
No security review is available for this catalog entry yet.
Серверное состояние на TanStack Query поверх типобезопасного клиента из OpenAPI; кэш, мутации и инвалидация без production mocks.
Review the original instructions and requested permissions before installing.
No security review is available for this catalog entry yet.
How clearly the skill guides your agent, how complete its workflow is, and how you can check the outcome.
No quality assessment is available for this catalog entry yet.
Original instructions from the publisher’s SKILL.md
# Навык: Data fetching (TanStack Query + OpenAPI)
Серверное состояние — на **TanStack Query** поверх **реального API бэкенда**. Клиентское UI-состояние — в Zustand (`$state-management`).
## Правило №1: всегда реальный API, источник истины — OpenAPI-спека бэка
- Фронт **всегда** бьёт в реальные эндпоинты бэка. Моков в прод-пути нет (MSW — только в тестах, `$react-testing`).
- Источник правды контракта — **OpenAPI-спека бэка** (эндпоинт под стек: `/documentation/json` у Fastify, `/api-json` у NestJS, `/openapi.json` и т.п.); полнота спеки — забота бэка (`$swagger-coverage`).
- Типы клиента **генерируются из спеки**, не пишутся руками.
## Типизированный клиент (openapi-typescript + openapi-fetch)
- Генерация типов (скрипт `pnpm gen:api`, перегенерировать при изменении бэка): `npx openapi-typescript http://localhost:3000/documentation/json -o src/shared/api/schema.d.ts`.
- Один клиент в `src/shared/api/client.ts`:
```ts
import createClient from 'openapi-fetch'
import type { paths } from './schema'
export const api = createClient<paths>({ baseUrl: process.env.NEXT_PUBLIC_API_URL })
```
Пути/query/body/ответы проверяются на типах против спеки — рассинхрон ловит компилятор.
## Слой api фичи
- `queryFn`/`mutationFn` вызывают `api.GET/POST/...` по эндпоинту из спеки; валидацию ответа обеспечивает бэк (сериализация по response-схеме, напр. в Fastify).
- Фабрику ключей держи в `features/<feature>/api`.
## Ключи запросов
- Иерархические ключи-массивы: `['orders']`, `['orders', id]`, `['orders', { status }]`.
- **Локаль в ключах:** если ответ зависит от языка, включай локаль в `queryKey` (`['orders', { locale }]`) и шли `Accept-Language`, чтобы кэш не смешивал языки (`$i18n`).
## Запросы
- `useQuery({ queryKey, queryFn })`; состояния `isLoading/isError/data` обрабатывай явно.
- Осознанные `staleTime`/`gcTime`; `placeholderData`/`keepPreviousData` для пагинации.
## Мутации
- `useMutation`; после успеха — `invalidateQueries({ queryKey })`.
- Оптимистично: `onMutate` (снимок + set), `onError` (откат), `onSettled` (инвалидация).
## Интеграция с Next.js
- `prefetchQuery` → `dehydrate`/`HydrationBoundary` (тем же клиентом `api`).
- Мутации через Server Actions + инвалидация кэша Query.
- Один `QueryClient` на запрос на сервере; стабильный инстанс на клиенте в `src/lib`.
## Пример
```ts
import { api } from '@/shared/api/client'
export const ordersKeys = { all: ['orders'] as const, detail: (id: string) => ['orders', id] as const };
const fetchOrders = async () => {
const { data, error } = await api.GET('/orders');
if (error) throw error;
return data;
};
export function useOrders() {
return useQuery({ queryKey: ordersKeys.all, queryFn: fetchOrders });
}
```