diff --git a/docs/features/frontend-fsd-shared-layer/spec.md b/docs/features/frontend-fsd-shared-layer/spec.md new file mode 100644 index 0000000..d85ff07 --- /dev/null +++ b/docs/features/frontend-fsd-shared-layer/spec.md @@ -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