Sergey Krylov 1b6fd39be3
Some checks failed
CI / ci (pull_request) Failing after 2m55s
CI / ci (push) Failing after 2m53s
feat: add frontend infrastructure libraries (ky, Zustand, MUI, dayjs, clsx, tanstack-table, rhf, zod)
- 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
2026-06-21 08:26:27 +03:00

153 lines
17 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.

# 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 в локальной обработке). Начнем!