133 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Frontend Infrastructure Tooling — Implementation Plan
## Architecture Decisions
### ADR references
- ADR-005: Biome вместо ESLint + Prettier
- ADR-006: TanStack Router вместо react-router-dom
- ADR-007: OpenAPI codegen как единый источник типов
### Non-ADR decisions
- ky как единый HTTP-клиент — выбор библиотеки, не меняющий архитектуры
- MSW browser mode — расширение существующей инфраструктуры тестов
- Zod для env validation — утилитарное улучшение
## Phases
Выполнять последовательно для минимизации конфликтов.
### Phase 1 — ky Migration
*Низкий риск, обратно совместим*
1. Доработать `kyClient.ts`:
- Добавить нормализацию конверта (normalizeEnvelope) в afterResponse hook
- Экспортировать `kyApi` и `configureKyAuth`
2. Поочерёдно перевести entity API на `kyApi`:
- session, stock, bond, search, portfolio, broker-*
3. Удалить `shared/api/client.ts`
4. Заменить `configureAuth``configureKyAuth` в точке входа
5. Прогнать тесты — поведение не должно измениться
### Phase 2 — Biome
*Средний риск — изменения в коде при авто-миграции*
1. Установить `@biomejs/biome`
2. `npx @biomejs/biome migrate eslint --write`
3. Создать `biome.json`, донастроить:
- Отключить несовместимые правила
- Настроить `files.ignore`, `linter.rules`
4. Проверить FSD-правила: @conarti/feature-sliced не портируются в Biome → оставить минимальный `.eslintrc.cjs` только для FSD
5. Удалить `eslint`, `prettier`, `.eslintrc.cjs` (если FSD не нужен)
6. Обновить `package.json`: `lint` скрипт → `biome check`
7. Обновить CI в `.gitea/workflows/ci.yml`
8. Обновить pre-commit hook (lint-staged → biome)
9. Прогнать `biome check --write`, закоммитить
10. Прогнать тесты
### Phase 3 — Unify API Types
*Низкий риск*
1. Убедиться, что все entity API импортируют из `types.ts` (codegen)
2. Удалить `shared/api/responses.ts`
3. Перенести normalizeEnvelope (ky-версию) в `shared/api/kyClient.ts`
4. Прогнать `npm run build`
### Phase 4 — MSW Browser
*Низкий риск, handlers готовы*
1. Создать `shared/lib/test/browser.ts` (setupWorker)
2. Прокинуть в `public/mockServiceWorker.js` через `npx msw init public/`
3. Создать `shared/config/env.ts` с чтением `VITE_API_MOCK`
4. Подключить MSW browser в `main.tsx` по условию
5. Проверить `npm run dev VITE_API_MOCK=true` без бэкенда
### Phase 5 — Env Validation
*Низкий риск*
1. Расширить `shared/config/env.ts` — Zod-схема для всех VITE_*
2. Вызвать валидацию в `main.tsx` до рендера
### Phase 6 — TanStack Router
*Крупный, высокий риск*
1. Установить зависимости:
- `@tanstack/react-router`
- `@tanstack/router-devtools` (devDependency)
- `@tanstack/router-plugin` (vite plugin)
2. Настроить Vite plugin в `vite.config.ts`
3. Создать файловую структуру роутов:
```
src/app/routes/
__root.tsx — AppLayout + ErrorBoundary
index.tsx — HomePage
stocks.$secid.tsx — StockPage
bonds.$secid.tsx — BondPage
screener.tsx — ScreenerPage + Zod search params
login.tsx — LoginPage
register.tsx — RegisterPage
profile.tsx — ProfilePage (guard: beforeLoad)
portfolios.tsx — PortfoliosListPage (guard)
portfolios.$id.tsx — PortfolioDetailPage (guard)
broker/
index.tsx — BrokerAccountsPage (guard)
$accountId/
index.tsx — BrokerAccountOverviewPage (guard)
shares.tsx — BrokerPositionsPage (guard)
bonds.tsx — BrokerPositionsPage (guard)
operations.tsx — BrokerOperationsPage + Zod search params (guard)
events.tsx — BrokerEventsPage (guard)
```
4. Перенести каждый роут из `AppRoutes.tsx` — каждый файл создаёт lazy route
5. Создать роутер в `app/routing/router.ts`:
- `createRouter()` с Route Tree
- `beforeLoad` для guard'ов
- Loaders для предзагрузки (TanStack Query integration)
6. Заменить `<BrowserRouter>` + `<Routes>` → `<RouterProvider>` в `App.tsx`
7. Заменить все импорты `react-router-dom` по всему проекту:
- `Link` → `Link` из `@tanstack/react-router`
- `useNavigate` → `useNavigate`
- `useParams` → `useParams`
- `useSearchParams` → `useSearch` + `useNavigate`
- `useLocation` → `useLocation`
8. Заменить `MemoryRouter` в тестах на `createMemoryRouter` из TanStack Router
9. Настроить router-devtools в dev-режиме
10. Прогнать тесты
## Dependencies
```
Phase 1 (ky) → независим
Phase 2 (Biome) → независим
Phase 3 (Types) → после Phase 1 (ky меняет нормализацию)
Phase 4 (MSW) → после Phase 5 (env нужен для VITE_API_MOCK)
Phase 5 (Env) → независим
Phase 6 (Router) → после Phase 3 (типы API стабильны)
```
## Rollback Strategy
- Каждый phase — отдельный коммит, можно revert по одному
- Biome: `.eslintrc.cjs` сохраняется как `.eslintrc.cjs.bak` до верификации
- Router: старый `AppRoutes.tsx` и `react-router-dom` не удаляются до полного прохождения тестов
- Каждый phase должен оставлять `npm run build` и `npm run test` зелёными