97 lines
5.7 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.

# 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-кита — отдельная задача.