# Frontend FSD — Portfolio Pages Дата: 2026-06-20 Статус: выполнено ## Контекст FSD-миграция фронтенда выполнена для большинства доменов. Остались 3 домена, намеренно не затронутые финальной cleanup-фазой: screener, portfolios, auth pages. Домен портфелей — второй по величине: entities/portfolio уже мигрирован в FSD, но UI-компоненты остаются в плоской `components/portfolios/`, а страницы — в `pages/portfolios/` с импортами из плоской структуры. ## Цель Мигрировать portfolio pages и сопутствующие UI-компоненты в FSD, следуя тому же паттерну, что и broker domain (entities → widgets → pages). ## Требования 1. Все UI-компоненты из `components/portfolios/` размещаются в `widgets/` по принципу «один виджет — одна композиционная единица» 2. Страницы в `pages/portfolios/` переключаются на импорты из виджетов 3. Никакие внутренние компоненты виджетов не импортируются напрямую из других слоёв — только через barrel-файл виджета 4. API-хуки и бизнес-логика остаются в `entities/portfolio/` — не дублируются 5. `components/portfolios/` удаляется после миграции всех потребителей ## Область изменений ### Мигрируемые файлы Из `components/portfolios/` в `widgets/`: - `AllocationChart.tsx` → внутренний компонент `widgets/portfolio-summary/ui/` - `AnalyticsSummary.tsx` → `widgets/portfolio-analytics/ui/AnalyticsSummary.tsx` - `BondPositionRow.tsx` → внутренний компонент `widgets/bond-positions-table/ui/` - `BondPositionTable.tsx` → `widgets/bond-positions-table/ui/BondPositionTable.tsx` - `PortfolioCard.tsx` → `widgets/portfolio-card/ui/PortfolioCard.tsx` - `PortfolioForm.tsx` → `widgets/portfolio-form/ui/PortfolioForm.tsx` - `PortfolioSummary.tsx` → `widgets/portfolio-summary/ui/PortfolioSummary.tsx` - `SharePositionRow.tsx` → внутренний компонент `widgets/share-positions-table/ui/` - `SharePositionTable.tsx` → `widgets/share-positions-table/ui/SharePositionTable.tsx` Обновляемые страницы: - `pages/portfolios/PortfoliosListPage.tsx` — импорты из `../../components/portfolios/*` → `@/widgets/portfolio-*` - `pages/portfolios/PortfolioDetailPage.tsx` — импорты из `../../components/portfolios/*` → `@/widgets/portfolio-*` ### Удаляемые файлы - `components/portfolios/` — весь каталог (9 файлов) ## Ограничения - Изменения ограничены frontend-пакетом. - `entities/portfolio/` не изменяется (уже FSD). - Не мигрируется screener и auth pages. - Не меняется поведение UI, API-контракты, роутинг. - Не вводятся ESLint import boundaries. ## Список виджетов | Виджет | Компоненты | Назначение | |--------|-----------|------------| | `portfolio-card` | PortfolioCard | Карточка портфеля для списка | | `portfolio-form` | PortfolioForm | Форма создания/редактирования | | `portfolio-summary` | PortfolioSummary, AllocationChart | Сводка: график + общая стоимость | | `portfolio-analytics` | AnalyticsSummary | Метрики: инвестировано, P&L, доходность | | `share-positions-table` | SharePositionTable, SharePositionRow | Таблица позиций-акций | | `bond-positions-table` | BondPositionTable, BondPositionRow | Таблица позиций-облигаций | ## Acceptance Criteria - Все 6 виджетов созданы в `widgets/` по FSD-структуре (index.ts + ui/) - `components/portfolios/` удалён - `pages/portfolios/` импортируют только из `@/widgets/*` и `@/entities/portfolio` - `npm test -w apps/frontend` — PASS - `npm run lint -w apps/frontend` — PASS - `npm run build -w apps/frontend` — PASS - Deep import check: `rg "components/portfolios" apps/frontend/src` — no matches