97 lines
5.7 KiB
Markdown
97 lines
5.7 KiB
Markdown
# FSD Frontend Refactor
|
||
|
||
## Цель
|
||
|
||
Довести фронтенд-архитектуру до эталонного Feature-Sliced Design (FSD) — устранить существующие нарушения, вынести жирные страницы в виджеты/фичи, внедрить автоматический контроль FSD-правил.
|
||
|
||
Текущее состояние: 4.2/5 по FSD-зрелости. Цель: 5/5.
|
||
|
||
## Задачи
|
||
|
||
### 1. Исправить нарушение слоёв в shared/lib/test
|
||
|
||
- `shared/lib/test/test-utils.tsx` импортирует `SessionProvider` из `@/app/providers`
|
||
- Это единственное нарушение FSD (shared → app)
|
||
- Решение: вынести `TestSessionProvider` в `shared/lib/test/` и переключить `test-utils.tsx` на него
|
||
- Тесты не должны сломаться: `TestSessionProvider` предоставляет те же значения контекста (замоканые)
|
||
|
||
### 2. Вынести BrokerPositionTable из страницы в виджет
|
||
|
||
- `pages/broker-positions/ui/BrokerPositionsPage.tsx` (310 строк) содержит внутренние компоненты:
|
||
- `BrokerPositionTable` (~190 строк) — таблица с пагинацией, skeleton, inline-стилями
|
||
- `PositionTicker` (~20 строк) — ссылка на инструмент
|
||
- `formatQuantity` — хелпер
|
||
- Решение: создать `widgets/broker-positions-table/` с:
|
||
- `ui/BrokerPositionTable.tsx`
|
||
- `ui/PositionTicker.tsx`
|
||
- `index.ts`
|
||
- Страница сокращается до ~100 строк (только cursor-логика + композиция)
|
||
|
||
### 3. Вынести BrokerSummary, BrokerAssetCards, BrokerOverviewSkeleton в виджет
|
||
|
||
- `pages/broker-account/ui/BrokerAccountOverviewPage.tsx` (160 строк) содержит:
|
||
- `BrokerSummary` — сводка портфеля (карточки стоимости и денег)
|
||
- `BrokerAssetCards` — карточки классов активов (акции/облигации)
|
||
- `BrokerOverviewSkeleton` — скелетон загрузки
|
||
- `allocationPercent`, `formatAllocationPercent` — хелперы
|
||
- Решение: создать `widgets/broker-overview/` с:
|
||
- `ui/BrokerSummary.tsx`
|
||
- `ui/BrokerAssetCards.tsx`
|
||
- `ui/BrokerOverviewSkeleton.tsx`
|
||
- `index.ts`
|
||
- Страница сокращается до ~40 строк (только loading/error guard + композиция)
|
||
|
||
### 4. Вынести AddPositionForm в фичу
|
||
|
||
- `pages/portfolios/ui/PortfolioDetailPage.tsx` (290 строк) содержит inline-форму добавления позиции:
|
||
- 4 state-переменные (newSecid, newQty, newPrice, newDate)
|
||
- 4 input-поля с inline-стилями
|
||
- Валидация и submit
|
||
- Это полноценная бизнес-фича, не место в странице
|
||
- Решение: создать `features/add-position/` с:
|
||
- `api/useAddPosition.ts` — мутация (обёртка над usePositionMutations)
|
||
- `model/useAddPositionForm.ts` — управление формой
|
||
- `ui/AddPositionForm.tsx` — UI формы
|
||
- `index.ts`
|
||
- Страница сокращается до ~140 строк (showAddForm toggle + `<AddPositionForm portfolioId={id} />`)
|
||
|
||
### 5. Вынести cursor-пагинацию в shared-хук
|
||
|
||
- 25 строк cursor-логики дублируются в:
|
||
- `pages/broker-positions/ui/BrokerPositionsPage.tsx`
|
||
- `pages/broker-operations/ui/BrokerOperationsPage.tsx`
|
||
- Решение: создать `shared/lib/useCursorPagination.ts`
|
||
|
||
```ts
|
||
function useCursorPagination() {
|
||
// cursor, pageNumber, handleNext(cursor), handlePrevious, reset
|
||
}
|
||
```
|
||
|
||
### 6. Добавить ESLint-плагин FSD
|
||
|
||
- Текущий `import/no-restricted-paths` проверяет только межслойные границы
|
||
- Плагин `@conarti/eslint-plugin-feature-sliced` добавит:
|
||
- Проверки public API (запрет импорта из внутренних модулей в обход index.ts)
|
||
- Проверки сегментов (api/ui/model не импортируют друг друга напрямую)
|
||
- Решение: установить плагин и включить recommended rules
|
||
|
||
## Критерии приёмки (Acceptance Criteria)
|
||
|
||
- [ ] AC1: `test-utils.tsx` не импортирует из `@/app/*`
|
||
- [ ] AC2: `widgets/broker-positions-table` создан, страница использует его
|
||
- [ ] AC3: `widgets/broker-overview` создан, страница использует его
|
||
- [ ] AC4: `features/add-position` создана, страница использует её
|
||
- [ ] AC5: `shared/lib/useCursorPagination.ts` создан, обе страницы используют его
|
||
- [ ] AC6: `@conarti/eslint-plugin-feature-sliced` установлен и настроен
|
||
- [ ] AC7: `npm run lint` проходит без ошибок
|
||
- [ ] AC8: `npm run build` проходит без ошибок
|
||
- [ ] AC9: Все существующие тесты проходят (включая тесты рефакторимых компонентов)
|
||
- [ ] AC10: Визуально поведение страниц не изменилось
|
||
|
||
## Ограничения
|
||
|
||
- Не менять API-контракты компонентов (пропсы, типы). Только перемещение кода.
|
||
- Не добавлять новую функциональность — только рефакторинг.
|
||
- inline-стили переносятся вместе с компонентами; централизация UI-кита — отдельная задача.
|