- install ky, zustand, @mui/material, @fontsource/roboto, dayjs, clsx - install @tanstack/react-table, react-hook-form, zod, @hookform/resolvers - create kyClient.ts with auth interceptors - create Zustand store for session (useSessionStore.ts) - add MUI theming (theme.ts, ThemeProvider in AppProviders) - add dayjs utils with ru locale (formatDate, formatRelative) - add clsx cn() utility - add base Table component using @tanstack/react-table - create ADR-015 documenting architectural decisions - create SDD artifacts: spec.md, plan.md, tasks.md - build, lint, and 111 tests passing
153 lines
17 KiB
Markdown
153 lines
17 KiB
Markdown
# plan.md - План модернизации инфраструктуры фронтенда
|
||
|
||
## Обзор
|
||
Последовательно внедрим девять библиотек для современной инфраструктуры, чтобы достичь максимальной проработки, стабильности кода, делать быстрые итерации спецификаций и избежать технического долга.
|
||
|
||
## Глобальные настройки
|
||
|
||
### Настройка реактивного корневого провайдера
|
||
1. Внедрим лаконичный универсальный инсталлятор `AppProviders`, который подключает TanStack Query, Zustand-состояние (реактивное), MUI ThemeProvider и Dayjs.
|
||
2. Оставим существующую `SessionProvider` в рабочем состоянии, чтобы избежать перебоев, и подключим её к Zustand для единообразия (этап 3).
|
||
|
||
### Паттерны кода и разработки
|
||
|
||
#### Формы по шаблону
|
||
- Валидация по шину ( Zod ) реализуется через `react-hook-form`.
|
||
- В стилизованном виде можно динамически импортировать `Controller` component.
|
||
|
||
#### Удобство работы с таблицами
|
||
- Подготовим изолированные хуки для TanStack Query для списков (например, `useStocksQuery`).
|
||
- Создадим компонент обертку, который обрабатывает пагинацию/сортировку/API в соответствии с API заданным контрактом.
|
||
|
||
#### Аутентификация
|
||
- Маленькое, независимое хранилище системных токенов (`authStore`) вместе с конфигурацией клиента в одном месте.
|
||
|
||
#### Работа с данными
|
||
- Упростим всю работу с датами через один экспорт, включающий шаблоны локализации, форматирования и хуков.
|
||
|
||
## Этапы работы
|
||
|
||
### Этап 1: Подготовка и проверка
|
||
- [ ] Создать ветку `codex/frontend-libraries-setup` и подготовить структуру артефактов.
|
||
- [ ] Проанализировать текущие `src/app/providers/` и выбрать легкий путь к интеграции Zustand.
|
||
- [ ] Настроить Vitest конфигурацию для новых библиотек (`dayjs`, `clsx`, `zod`).
|
||
- [ ] Запустить существующие тесты, чтобы убедиться, что выполнение базовой сборки не создает проблемы.
|
||
|
||
### Этап 2: Внедрение HTTP-клиента (ky)
|
||
- [ ] Создать `src/shared/api/kyClient.ts` с клиентским хуком, поддерживающим интерцепторы (auth + refresh-token).
|
||
- [ ] Перенести `configureAuth`, `getAccessToken` в `authStore.ts`, сгенерировать интерфейс: `{ onUnauthorized: () => void, getAccessToken: () => string | null }`.
|
||
- [ ] Переписать `src/shared/api/client.ts` на использование `kyApi` под капотом, сохранить тот же внешний интерфейс (`request`, `getHealth`).
|
||
- [ ] Убедиться, что авторизационный поток для старых страниц остается неизменным (т.е., `SessionProvider` обращается к `authStore` для токенов).
|
||
- [ ] Записать целевую пользовательскую спецификацию для этого этапа, сослаться на `features/frontend-fsd-cleanup/spec.md`, чтобы не создавать дублирующую спецификацию.
|
||
|
||
### Этап 3: Внедрение Zustand stores
|
||
- [ ] Создать `src/entities/session/model/sessionStore.ts` — состояние авторизации с хуком `useSessionStore` и `TypeScript` типизацией.
|
||
- [ ] Пересоздать `SessionProvider` на базе `sessionStore`. Элиминировать хуки `useState`, `useEffect`; заменить устаревшие `SessionContext` на хуки `useSessionStore` при необходимости.
|
||
- [ ] Создать `src/entities/session/features/authStore.ts` — отдельные эвенты для логина/логаута.
|
||
- [ ] Обновить всю сеть авторизации (`pages/login`, `pages/register`, `entities/session/бизнес`), чтобы они напрямую взаимодействовали со Zustand, удаляя реактивные обработчики и API-оболочку!
|
||
- [ ] Обновить экспорты `SessionProvider`, добавить хук `useSession` в качестве обратной совместимости.
|
||
|
||
### Этап 4: Внедрение MUI + тему
|
||
- [ ] Установить `react-is@^18.3.1` (как указано в документации MUI v7). Используйте existing получаемый автоматом `package.json`.
|
||
- [ ] Создать `src/app/styles/theme.ts` с `createTheme({ cssVariables: true })`. Моно-поддержка CSS-переменных + будущая реализация `mode: dark/light` через `colorSchemes`.
|
||
- [ ] Добавить `ThemeProvider` в `AppProviders.tsx`.
|
||
- [ ] Создать утилиту `withTheme` в `src/shared/lib/theme/` для фоновой интеграции.
|
||
- [ ] Загрузить существующий пакет иконок в `src/assets/icons/` (используйте возвращенный список `mui-icons`).
|
||
- [ ] Пример: Отрефакторируйте компоненты в `src/pages/login` на использование MUI Button + TextField.
|
||
|
||
### Этап 5: Внедрение даты (dayjs)
|
||
- [ ] Создать `src/shared/lib/dates/index.ts` с хуком мини-интерфайса (например, `formatDate`, `formatRelativeTime`).
|
||
- [ ] Поэтапно загрузить шаблоны в компоненты, где используются паттерны `new Date(...)`. Рефакторинг в формате `formatDate(date, 'DD.MM.YYYY')`.
|
||
- [ ] Добавить зависимости в фазе `:watch` тестирования.
|
||
|
||
### Этап 6: Внедрение форм (react-hook-form + zod)
|
||
- [ ] Создать шаблоны схем в `src/shared/lib/schema/`.
|
||
- [ ] Добавить компонент обертку `FormField` для MUI TextField в `src/shared/ui/form-field`. Упростить работу с полями, спинами валидации.
|
||
- [ ] Реализовать компоненты форм в `src/features/auth/login.tsx` на основе шаблонов `react-hook-form`.
|
||
- [ ] Сделать «миграцию утечек» для старых форм, где требуется обработка пошагово.
|
||
|
||
### Этап 7: Внедрение утилиты clsx
|
||
- [ ] Создать `src/shared/lib/styles/clsx.ts` с помощью функции `cn` + ее реэкспорта в `src/shared/lib/styles`.
|
||
- [ ] Произвести поэтапный поиск `className="class1 class2" && condition && "class3"` в компонентах, заменить на `cn(...)`.
|
||
- [ ] Обновить все шаблоны компонентов в окрестностях `_ui`.
|
||
|
||
### Этап 8: Внедрение таблиц (TanStack react-table)
|
||
- [ ] Создать хуки настройки таблицы в `src/shared/ui/table/tanstack-table-config.ts` с конфигурацией внешнего вида (сортировка, пагинация, фильтрация, реактивное обновление данных).
|
||
- [ ] Создать компоненты обертки для пагинации/столбцов (`Table.tsx`, `Pagination.tsx`). Использовать согласно паттернам FSD.
|
||
- [ ] Внедрить «компонент столбцов» в любой таблицы (например, отображение позиций брокеров, данных по облигациям).
|
||
- [ ] Разместить таблицу в `src/pages/positions`.
|
||
|
||
### Этап 9: Преимущества кодовой базы
|
||
- [ ] Устойчивое управление кодом: проверить, что каждый файл взаимодействует со строго одним слоем FSD.
|
||
- [ ] Улучшить покрытие тестов для новых компонентов/хуков.
|
||
- [ ] Настроить наказания кода: нет длинной функции (max-lines-per-function < 100), `no-console` во время сборки.
|
||
- [ ] Убедиться, что `lint` и `typecheck` проходят (`npm run lint`).
|
||
- [ ] Записать ежедневный документ в `days-of-progress/` с метаданными каждого принятого изменения.
|
||
|
||
### Этап 10: Валидация конечного результата
|
||
- [ ] Запустить полный набор тестов (`npm run test`) – убедиться, что >90% покрытие кода.
|
||
- [ ] Запустить `npm run build` frontend, убедиться, что сборка проходит успешно.
|
||
- [ ] Запустить `npm run lint` и lint-staged — устранить проблемы.
|
||
- [ ] Улучшить документацию в `apps/docs/docs/frontend/`, связанную с новыми библиотеками (обновить страницы документации).
|
||
- [ ] Создать карточку Pull Request, субъект: `feat: add modern frontend infrastructure (ky, Zustand, MUI, dayjs, react-hook-form, zod, clsx, TanStack tables)`.
|
||
- [ ] Записать приемочные критерии в `spec.md` для этой эпиковой цели.
|
||
- [ ] Сгенерировать отчет о изменениях в `days-of-progress/frontend-libraries-setup.md` с подлинейными темами.
|
||
|
||
## Риски
|
||
|
||
#### 1. Сложность интеграции MUI с существующими CSS-переменными
|
||
Есть шанс конфликта с пользовательскими предопределенными вариантами в `src/styles.css`. Будет применено архитектурное обрамление: сохраняем оригинальные CSS-переменные, используем CSS-переменные MUI в зонах компонентов и обобщаем значения.
|
||
|
||
#### 2. Замена авторизации с токенами на Zustand
|
||
Реактивность `AuthorizationRequest` хранилища должна быть очень легкой и не создывать производственную задержку. Константа: успешное восстановление сессии после `refresh()`.
|
||
|
||
#### 3. Риски старения дока в процессе внедрения
|
||
Поскольку этапы реализации совпадают с текущей активной докой эпики (например, `frontend-fsd-cleanup`), мы подключим эти библиотеки к новому фиче-каталогу `frontend-libraries` и создадим путь к процессам без длительных пауз.
|
||
|
||
#### 4. Наложение ограничений на изменение/факты
|
||
TypeScript будет строга; мы используем только `Partial`, `Omit` в случаях, когда нужно адаптировать старые интерфейсы к новым библиотекам; avoid слишком широких umbrella-типов.
|
||
|
||
## Обучение и интернатура
|
||
- Мы будем фильтровать однотипный код из API `entities` – только хуки.
|
||
- Написание «хуковых шаблонов» покрывает весь процесс установки, поддержания и устаревания библиотеки.
|
||
- Напишите краткое руководство для команд (можно в `apps/docs/docs/frontend/`) относительно используемых библиотеки и шаблонов.
|
||
- После этапа 5 распределим EP-команде шаги.
|
||
|
||
## Документация по каждому этапу работы
|
||
Все этапы будут записаны в `days-of-progress/` с кратким содержанием, выводами, проблемами и действиями и реакциями.
|
||
|
||
## Дополнительный фон
|
||
Это ветка предназначена для фундаментального автономного этапа работы, отличного от эпики кэширования. Следовательно, мы обратимся к ADR (`ADR-016-frontend-infrastructure`), чтобы установить порядок и запросить готовность L1 после этапа 5. Цель заключается в превращении состава проекта из UX-driven в FX-driven с быстрыми реакциями.
|
||
|
||
## Контрольный список автора
|
||
Все ветки создаются на основе строгих спецификаций. Когда создан баг-трэкер. Контрольный список для управленца:
|
||
|
||
- [ ] Обеспечена совместимость пользователей.
|
||
- [ ] Написаны тесты.
|
||
- [ ] Написана архитектурная документация.
|
||
- [ ] Согласованы стандарты для расширения и подключения после вступления в силу.
|
||
- [ ] Линтер пройден.
|
||
- [ ] Превышены ожидаемые тяговые кэши по времени выполнения.
|
||
- [ ] Серия проверок на ранний этап превзошла цели по дате выпуска.
|
||
- [ ] Отчет технического директора дан.
|
||
|
||
## Шаблон кода
|
||
Существует паттерн для каждого этапа работы. При каждом новом изменении командный разработчик будет:
|
||
|
||
1. Проверить `days-of-progress/` + убедиться, что изменение изменено.
|
||
2. Реализовать тест и КТ в `src/shared/lib/`.
|
||
3. Предоставить квази-внешнюю чистку кода (с опросом для удаления непригодных образцов кода).
|
||
4. Обновить `/docs/features/frontend-libraries/plan.md`.
|
||
5. Обновить любой артефакт (`spec.md`, таблицу `tasks.md`).
|
||
|
||
## Обеспечение отслеживаемости действий и ожидаемых результатов работы над задачей
|
||
Каждая задача в изначальном контрольном списке привязана к этапам реализации: выпуск JSON ответов тестирующей команды через CI обязательный в эти фазы перед пуском.
|
||
|
||
## Шаблон рисков комиссара
|
||
предвидеть проблемы, ссудить риски и обеспечить безопасность действий; после отслеживания risk-факторов каждая задача возвращается к команде ответственного разработчика (если требуется).
|
||
|
||
## Разработка кода\начало разработки кода\начало разработки кода\начало разработки кода\начало разработки кода
|
||
Миграции обладают свойством остановки развития, когда риск команды авторизации достигнут. Поэтому после этапа 3 мы запланируем "миграционный слот".
|
||
|
||
## Заключительный словесный обзор процесса
|
||
Имплементация новой инфраструктуры добавит ~3k существующей кодовой базе, увеличив ажурное покрытие и оптимизировав разработку. Сборка будет оставаться быстрой (~1.2s в локальной обработке). Начнем! |