126 lines
7.4 KiB
Markdown
126 lines
7.4 KiB
Markdown
# Frontend FSD Market Pages
|
||
|
||
Дата: 2026-06-20
|
||
Статус: спецификация
|
||
|
||
## Контекст
|
||
|
||
Предыдущие FSD-итерации мигрировали broker-домен (`frontend-fsd-broker-pilot`), shared-слой
|
||
(`frontend-fsd-shared-layer`), entities stock/bond/portfolio (`fsd-entities-migration`) и app-слой с
|
||
auth (`frontend-fsd-app-auth`).
|
||
|
||
Рыночные страницы (StockPage, BondPage, HomePage) и их компоненты (StockDetails, BondDetails,
|
||
PriceChart, SearchBar) остались в исторической технической структуре (`components/`, `hooks/`,
|
||
плоские `pages/`). Это единственный крупный блок кода вне FSD-структуры, который активно
|
||
используется пользователями.
|
||
|
||
## Иерархия источников
|
||
|
||
- Текущая задача пользователя: завершить FSD-миграцию рыночных страниц.
|
||
- `docs/inbox.md`: направление на постепенную FSD-миграцию.
|
||
- `docs/features/frontend-fsd-broker-pilot/spec.md`: эталонный FSD-шаблон.
|
||
|
||
## Цель
|
||
|
||
Перевести рыночные страницы (stock, bond, home) и связанные компоненты в FSD-структуру, следуя
|
||
паттерну, установленному broker-пилотом — через widgets, entities и page entrypoints с
|
||
совместимыми shim-файлами.
|
||
|
||
## Область изменений
|
||
|
||
Фича охватывает только frontend-код рыночных страниц:
|
||
|
||
- StockPage, BondPage, HomePage — миграция из плоских `pages/` в `pages/stock/`, `pages/bond/`,
|
||
`pages/home/` с FSD-структурой;
|
||
- StockDetails, BondDetails — миграция из `components/` в `widgets/stock-details/`,
|
||
`widgets/bond-details/`;
|
||
- PriceChart — миграция из `components/` в `widgets/price-chart/`;
|
||
- SearchBar + useSearch — миграция в `widgets/search-bar/` + новый entity `entities/search/`;
|
||
- таблица дивидендов — вынос из StockPage в новый виджет `widgets/dividends-table/`;
|
||
- shim-файлы для обратной совместимости;
|
||
- обновление роутинга и layout для импортов из новых FSD-точек входа.
|
||
|
||
## Требования
|
||
|
||
### 1. Все компоненты следуют FSD-слоям
|
||
|
||
- entities — data-слой (API + query hooks). Новый: `entities/search/`.
|
||
- widgets — бизнес-композиция UI. Новые: `widgets/stock-details/`, `widgets/bond-details/`,
|
||
`widgets/price-chart/`, `widgets/search-bar/`, `widgets/dividends-table/`.
|
||
- pages — тонкие entrypoints. Новые: `pages/stock/`, `pages/bond/`, `pages/home/`.
|
||
|
||
### 1.1 Ownership данных остаётся у pages и entities
|
||
|
||
- `pages/stock` и `pages/bond` владеют route params и orchestration загрузки данных через
|
||
существующие entity hooks (`useStock`, `useBond`, `useStockCandles`, `useBondCandles`,
|
||
`useStockDividends`).
|
||
- `widgets/stock-details`, `widgets/bond-details`, `widgets/price-chart`,
|
||
`widgets/dividends-table` остаются презентационно-композиционными и получают готовые данные
|
||
через props.
|
||
- `widgets/search-bar` владеет локальным UI-состоянием поиска (input, debounced query, dropdown),
|
||
а query-hook `useSearch` размещается в `entities/search/model/`.
|
||
- `pages/home` остаётся статическим page entrypoint без новой data-логики.
|
||
|
||
### 2. Границы срезов явные через public API
|
||
|
||
Каждый widget и entity имеет `index.ts` barrel с контролируемым экспортом.
|
||
|
||
Внешний код импортирует market pages/widgets/entities только через их public API
|
||
(`@/pages/stock`, `@/widgets/search-bar`, `@/entities/search` и т.д.). Deep imports во внутренние
|
||
`model/`, `api/`, `ui/` директории не считаются контрактом для внешних потребителей.
|
||
|
||
### 3. Поведение UI не меняется
|
||
|
||
Миграция не добавляет новую функциональность и не пересматривает UX.
|
||
|
||
### 4. Совместимость через shim-файлы
|
||
|
||
Старые пути (`components/StockDetails.tsx`, `hooks/useSearch.ts`, `pages/StockPage.tsx`) становятся
|
||
re-export shim-файлами, импортирующими из новых FSD-точек входа.
|
||
|
||
### 5. Тесты следуют новым границам
|
||
|
||
Тесты перемещаются вместе с компонентами в соответствующие widget/page/ui-директории.
|
||
|
||
### 6. Общая инфраструктура остаётся в shared
|
||
|
||
HTTP-клиент и типы остаются в `shared/api/`. PriceChart использует `lightweight-charts`
|
||
непосредственно, без дополнительных абстракций.
|
||
|
||
## Ограничения
|
||
|
||
- Изменения ограничены frontend-пакетом.
|
||
- Допускаются связанные обновления опубликованной frontend-документации и ADR, если они отражают
|
||
новую FSD-структуру market pages.
|
||
- Не вводятся ESLint import boundaries или import guards.
|
||
- Не мигрируются portfolio и screener страницы.
|
||
- Не удаляется мёртвый код (old `pages/broker/`, `api/broker.ts`).
|
||
- Не меняется backend API, Swagger, codegen.
|
||
|
||
## Acceptance Criteria
|
||
|
||
- StockDetails доступен через `widgets/stock-details`.
|
||
- BondDetails доступен через `widgets/bond-details`.
|
||
- PriceChart доступен через `widgets/price-chart`.
|
||
- SearchBar доступен через `widgets/search-bar` и использует query/public API из `entities/search`.
|
||
- DividendsTable вынесен из StockPage в `widgets/dividends-table`.
|
||
- StockPage доступен через `pages/stock`.
|
||
- BondPage доступен через `pages/bond`.
|
||
- HomePage доступен через `pages/home`.
|
||
- Все старые пути (components/*, hooks/useSearch, pages/StockPage/BondPage/HomePage) —
|
||
re-export shims, импортирующие из новых FSD-точек входа.
|
||
- `app/routing/AppRoutes.tsx` и `app/layouts/AppLayout.tsx` импортируют из новых FSD-точек входа.
|
||
- `pages/stock` и `pages/bond` сохраняют orchestration загрузки market data и передают widgets
|
||
готовые props без переноса route/query orchestration внутрь widgets.
|
||
- Frontend lint, tests и build проходят.
|
||
- Пользовательское поведение эквивалентно.
|
||
- ADR и документация обновлены.
|
||
|
||
## Не цели
|
||
|
||
- Миграция portfolio, screener и остальных доменов.
|
||
- Введение жёстких правил импортов.
|
||
- Удаление мёртвого кода (old `pages/broker/`, `api/broker.ts`).
|
||
- Переписывание стилей или визуального дизайна.
|
||
- Добавление новой функциональности.
|