88 lines
5.0 KiB
Markdown
88 lines
5.0 KiB
Markdown
# Frontend FSD Shared Layer
|
||
|
||
Дата: 2026-06-20
|
||
Статус: спецификация
|
||
|
||
## Контекст
|
||
|
||
Broker FSD pilot завершён: broker-домен работает в FSD-слоях entities/widgets/pages. Следующий шаг
|
||
миграции — нормализация shared-инфраструктуры. Сейчас общий код размазан по техническим каталогам
|
||
(`api/`, `components/`, `context/`, `hooks/`), и FSD-сущности вынуждены импортировать из них через
|
||
длинные относительные пути (`../../../api/client`). Это мешает введению import boundaries и
|
||
усложняет дальнейшую миграцию доменов.
|
||
|
||
## Цель
|
||
|
||
Создать FSD-слой `shared/` с явным public API, в который переносится truly shared
|
||
инфраструктурный код: базовый HTTP-клиент, типы ответов API, переиспользуемые UI-примитивы без
|
||
доменной логики.
|
||
|
||
## Область изменений
|
||
|
||
### Входит
|
||
|
||
- Перенос `api/client.ts`, `api/responses.ts`, `api/types.ts` в `shared/api/`
|
||
- Перенос компонентов без доменных зависимостей (`SkeletonBlock`, `TableSkeleton`) в `shared/ui/`
|
||
- Превращение исходных файлов в re-export shims (стратегия coexistence, как в broker pilot)
|
||
- Переключение импортов в FSD-сущностях и legacy hooks на `@/shared/api/...`
|
||
|
||
### Не входит
|
||
|
||
- Layout и ProtectedRoute — остаются в `components/` (зависят от доменного кода SearchBar, useAuth)
|
||
- SearchBar, StockDetails, BondDetails, PriceChart — доменные компоненты, остаются на месте
|
||
- AuthContext — остаётся в `context/` (будет перенесён при миграции auth-домена или app-слоя)
|
||
- Все доменные API-функции (`getShare`, `getBond`, `searchSecurities` и т.д.) — остаются в
|
||
`api/client.ts` как есть, будут вынесены при миграции соответствующих доменов
|
||
- Все доменные типы (`ShareResponse`, `Portfolio`, `ScreenerItem` и т.д.) — остаются в
|
||
`api/responses.ts` как есть
|
||
- Import guards, ESLint boundaries — отложены до стабилизации слоёв
|
||
|
||
## Требования
|
||
|
||
### 1. shared/api/ содержит базовую HTTP-инфраструктуру
|
||
|
||
`shared/api/client.ts` включает:
|
||
- Базовый HTTP-клиент (`request`, `setAccessToken`, `getAccessToken`, `setOnUnauthorized`)
|
||
- Все доменные API-функции (как временная мера до миграции доменов)
|
||
|
||
`shared/api/responses.ts` включает все типы ответов API (как временная мера).
|
||
|
||
`shared/api/types.ts` — generated OpenAPI types.
|
||
|
||
### 2. shared/ui/ содержит только truly generic UI-компоненты
|
||
|
||
В `shared/ui/` попадают только компоненты без импортов доменного кода:
|
||
- `SkeletonBlock` — примитивный скелетон (нет зависимостей)
|
||
- `TableSkeleton` — табличный скелетон (зависит только от SkeletonBlock)
|
||
|
||
Layout и ProtectedRoute остаются в legacy `components/`, так как импортируют SearchBar и useAuth.
|
||
|
||
### 3. Coexistence через shims
|
||
|
||
Исходные файлы в `api/` и `components/` превращаются в re-export shims.
|
||
|
||
### 4. FSD-сущности импортируют через @/shared/
|
||
|
||
Импорты в entities/widgets/pages меняются с относительных на `@/shared/api/...`.
|
||
|
||
## Acceptance Criteria
|
||
|
||
- `src/shared/api/client.ts`, `responses.ts`, `types.ts` существуют и экспортируют всё,
|
||
что экспортировали исходные файлы
|
||
- `src/shared/ui/SkeletonBlock.tsx` и `src/shared/ui/TableSkeleton.tsx` существуют
|
||
- Исходные файлы `api/client.ts`, `api/responses.ts`, `api/types.ts` стали re-export shims
|
||
- Исходные файлы `components/SkeletonBlock.tsx`, `components/TableSkeleton.tsx` стали
|
||
re-export shims
|
||
- Все FSD entity импорты `../../../api/...` заменены на `@/shared/api/...`
|
||
- Все legacy hooks используют `@/shared/api/...` вместо `../api/...`
|
||
- `npm test -w apps/frontend` — PASS
|
||
- `npm run lint -w apps/frontend` — PASS
|
||
- `npm run build -w apps/frontend` — PASS
|
||
|
||
## Ограничения
|
||
|
||
- Никаких изменений поведения UI
|
||
- Не меняется структура ответов API
|
||
- Layout, ProtectedRoute, AuthContext остаются на месте
|
||
- Не затрагиваются backend, docs, CI
|