Перейти к основному содержимому

Быстрый старт

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:*. Извне — через приватный Verdaccio (@mineflow:registry=https://npm.57.129.115.249.nip.io), см. Установка пакетов.

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,
useRealtimeNotifications,
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-уведомления (Centrifugo) — новые префиксятся в кэш useNotifications
// (требует <RealtimeProvider> внутри <MineflowProvider>; см. рецепт Realtime)
useRealtimeNotifications({ onNotification: (n) => toast(n.title) });

// FSM-кнопки + RBAC-гейт
const actions = useAvailableActions(assetMachine, 'operational');
const canApprove = useCan(['CEO', 'Engineer']);

return /* ... твой UI ... */;
}

Что дальше​

  • Пакеты — что делает каждый слой, со всеми экспортами.
  • Рецепты — ошибки, саги, realtime, offline, RBAC, FSM, формы, RN.
  • API-референс — точные сигнатуры из кода.