docs: define frontend fsd shared layer spec

This commit is contained in:
Sergey Krylov 2026-06-20 13:25:19 +03:00
parent 4db95146a7
commit df4b778d95

View File

@ -0,0 +1,87 @@
# 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