83 lines
4.5 KiB
Markdown
83 lines
4.5 KiB
Markdown
# 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
|