88 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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