Быстрый старт
End-to-end: установка → Keycloak → провайдер → первый экран (чтение + форма + мутация + сага + realtime + RBAC).
1. Установка
pnpm add @mineflow/client-react @mineflow/client-core @mineflow/auth-web \
@mineflow/api-zod @mineflow/api-schemas
# peer-зависимости приложения:
pnpm add react @tanstack/react-query xstate zod keycloak-js
pnpm add @hookform/resolvers react-hook-form # если используешь формы
В монорепо MineFlow пакеты резолвятся как workspace:*. Извне — через приватный
registry (@mineflow:registry=https://npm.pkg.github.com), см.
Установка пакетов.
2. Keycloak + провайдер
import Keycloak from 'keycloak-js';
import { KeycloakTokenProvider } from '@mineflow/auth-web';
import { MineflowProvider } from '@mineflow/client-react';
// Keycloak — один раз на старте приложения
const keycloak = new Keycloak({
url: 'https://auth.mineflow.local',
realm: 'mineflow',
clientId: 'mineflow-web',
});
await keycloak.init({ onLoad: 'check-sso', pkceMethod: 'S256' });
const tokenProvider = new KeycloakTokenProvider({ keycloak });
function App() {
return (
<MineflowProvider
baseUrl={import.meta.env.VITE_API_BASE} // origin; пути включают /api/v1
tokenProvider={tokenProvider}
generateId={() => crypto.randomUUID()}
roles={tokenProvider.getRoles()}
>
<AssetsScreen />
</MineflowProvider>
);
}
baseUrl — это origin
https://api.mineflow.local, без пути. Пути из api-client уже содержат
/api/v1.
3. Первый экран
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { zCreateAssetDto } from '@mineflow/api-zod';
import { assetMachine } from '@mineflow/api-schemas';
import {
useAssets,
useRegisterAsset,
useApproveShiftReport,
useNotificationFeed,
useCan,
useAvailableActions,
} from '@mineflow/client-react';
function AssetsScreen() {
// чтение (cursor-пагинация, фильтры — типобезопасно)
const { data, isLoading } = useAssets({ status: 'operational', limit: 50 });
// форма с instant-валидацией Zod + мутация (авто Idempotency-Key + инвалидация)
const form = useForm({ resolver: zodResolver(zCreateAssetDto) });
const register = useRegisterAsset();
const onSubmit = form.handleSubmit((values) => register.mutate(values));
// async-сага: POST 202 → polling /sagas/{id}/status
const approve = useApproveShiftReport();
// live-уведомления (SSE) — новые префиксятся в кэш useNotifications
useNotificationFeed({ onNotification: (n) => toast(n.title) });
// FSM-кнопки + RBAC-гейт
const actions = useAvailableActions(assetMachine, 'operational');
const canApprove = useCan(['CEO', 'Engineer']);
return /* ... твой UI ... */;
}
Что дальше
- Пакеты — что делает каждый слой, со всеми экспортами.
- Рецепты — ошибки, саги, SSE, offline, RBAC, FSM, формы, RN.
- API-референс — точные сигнатуры из кода.