# Frontend Infrastructure Tooling — Tasks ## Phase 1: ky Migration - [ ] Доработать `shared/api/kyClient.ts`: добавить normalizeEnvelope в afterResponse hook - [ ] Экспортировать `kyApi` (create экземпляр) и `configureKyAuth` из kyClient - [ ] Перевести `entities/session/api/sessionApi.ts` на kyApi - [ ] Перевести `entities/stock/api/stockApi.ts` на kyApi - [ ] Перевести `entities/bond/api/bondApi.ts` на kyApi - [ ] Перевести `entities/search/api/searchApi.ts` на kyApi - [ ] Перевести `entities/portfolio/api/portfolioApi.ts` на kyApi - [ ] Перевести `entities/broker-account/api/brokerAccountApi.ts` на kyApi - [ ] Перевести `entities/broker-position/api/brokerPositionApi.ts` на kyApi - [ ] Перевести `entities/broker-operation/api/brokerOperationApi.ts` на kyApi - [ ] Перевести `entities/broker-event/api/brokerEventApi.ts` на kyApi - [ ] Перевести `features/screener/api/screenerApi.ts` на kyApi - [ ] Удалить `shared/api/client.ts` - [ ] Заменить `configureAuth()` на `configureKyAuth()` в точке входа (AppProviders) - [ ] `npm run test` — все тесты проходят - [ ] `npm run build` — сборка проходит ## Phase 2: Biome Migration - [ ] Research: проверить Biome plugin system на поддержку FSD/import-no-restricted-paths - [ ] Установить `@biomejs/biome` (devDependency) - [ ] Запустить `npx @biomejs/biome migrate eslint --write` - [ ] Создать `biome.json` с донастройкой под проект - [ ] Если FSD-правила не портируются — создать минимальный `.eslintrc.cjs` только для FSD - [ ] Удалить зависимости: eslint, prettier, @typescript-eslint/*, eslint-plugin-* - [ ] Удалить `.eslintrc.cjs` (если FSD не нужен) - [ ] Обновить `package.json`: `lint` → `biome check src/` - [ ] Обновить `.gitea/workflows/ci.yml`: заменить eslint на biome - [ ] Обновить pre-commit hook (lint-staged → biome) - [ ] Прогнать `biome check --write src/` - [ ] `npm run test` — все тесты проходят ## Phase 3: Unify API Types - [ ] Проверить все импорты в entity API — должны быть из `types.ts` (codegen), не из `responses.ts` - [ ] Если кто-то импортирует из `responses.ts` — переключить на `types.ts` - [ ] Удалить `shared/api/responses.ts` - [ ] Перенести normalizeEnvelope (ky-версия) в `shared/api/kyClient.ts` - [ ] `npm run build` — сборка проходит ## Phase 4: MSW Browser - [ ] Создать `shared/lib/test/browser.ts` (setupWorker из msw/browser) - [ ] Установить и прокинуть mockServiceWorker.js: `npx msw init public/` - [ ] Создать `shared/config/env.ts` с чтением и экспортом VITE_API_MOCK - [ ] В `main.tsx`: при `VITE_API_MOCK === 'true'` запускать `worker.start()` - [ ] Проверить: `VITE_API_MOCK=true npm run dev` без бэкенда — приложение работает - [ ] Проверить: `VITE_API_MOCK=false npm run dev` — запросы идут на бэкенд ## Phase 5: Env Validation - [ ] Разработать Zod-схему в `shared/config/env.ts` для всех VITE_* переменных - [ ] Вызвать `validateEnv()` в `main.tsx` до `ReactDOM.createRoot` - [ ] Проверить: при отсутствии обязательной переменной — понятная ошибка ## Phase 6: TanStack Router ### Setup - [ ] Установить `@tanstack/react-router`, `@tanstack/router-devtools`, `@tanstack/router-plugin` - [ ] Настроить Vite plugin для генерации RouteTree в `vite.config.ts` ### Route files - [ ] Создать `src/app/routes/__root.tsx` — AppLayout + ErrorBoundary - [ ] Создать `src/app/routes/index.tsx` — HomePage - [ ] Создать `src/app/routes/stocks.$secid.tsx` — StockPage - [ ] Создать `src/app/routes/bonds.$secid.tsx` — BondPage - [ ] Создать `src/app/routes/screener.tsx` — ScreenerPage + Zod search params - [ ] Создать `src/app/routes/login.tsx` — LoginPage - [ ] Создать `src/app/routes/register.tsx` — RegisterPage - [ ] Создать `src/app/routes/profile.tsx` — ProfilePage (guard: beforeLoad) - [ ] Создать `src/app/routes/portfolios.tsx` — PortfoliosListPage (guard) - [ ] Создать `src/app/routes/portfolios.$id.tsx` — PortfolioDetailPage (guard) - [ ] Создать `src/app/routes/broker/index.tsx` — BrokerAccountsPage (guard) - [ ] Создать `src/app/routes/broker.$accountId/index.tsx` — BrokerAccountOverviewPage (guard) - [ ] Создать `src/app/routes/broker.$accountId/shares.tsx` — BrokerPositionsPage (guard) - [ ] Создать `src/app/routes/broker.$accountId/bonds.tsx` — BrokerPositionsPage (guard) - [ ] Создать `src/app/routes/broker.$accountId/operations.tsx` — BrokerOperationsPage (guard) - [ ] Создать `src/app/routes/broker.$accountId/events.tsx` — BrokerEventsPage (guard) ### Router integration - [ ] Создать `app/routing/router.ts`: `createRouter()` с Route Tree - [ ] Настроить `beforeLoad` для guard'ов - [ ] Настроить loaders для предзагрузки (TanStack Query) - [ ] Заменить `` + `` → `` в `App.tsx` ### Replace imports - [ ] Заменить `Link` → `@tanstack/react-router` Link по всему проекту - [ ] Заменить `useNavigate` → `@tanstack/react-router` - [ ] Заменить `useParams` → `@tanstack/react-router` - [ ] Заменить `useSearchParams` → `useSearch` + `useNavigate` - [ ] Заменить `useLocation` → `@tanstack/react-router` ### Tests - [ ] Заменить `MemoryRouter` в тестах на `createMemoryRouter` из TanStack Router - [ ] Обновить тестовые утилиты (`test-utils.tsx`) - [ ] `npm run test` — все тесты проходят - [ ] `npm run build` — сборка проходит ### Devtools - [ ] Настроить `@tanstack/router-devtools` в dev-режиме - [ ] Проверить навигацию по всем страницам вручную