# Frontend FSD Screener — Implementation Plan > **For agentic workers:** Implement task-by-task using the tasks.md checklist. Steps use checkbox (`- [ ]`) syntax. **Goal:** Перевести скринер в FSD-структуру с созданием первого feature-slice (`features/screener/`). **Architecture:** Скринер — пользовательский сценарий (фильтрация + сортировка + пагинация), а не бизнес-сущность, поэтому размещается в `features/` слое. `features/screener/` содержит API, модель (URLSearchParams + TanStack Query) и UI. `pages/screener/` — тонкая композиция. Legacy-файлы удаляются без shim-совместимости. **Tech Stack:** React 18, TypeScript, React Router v6, TanStack Query v5, Vitest, ESLint, Vite. ## Карта файлов ### Create - `docs/features/frontend-fsd-screener/spec.md` - `docs/features/frontend-fsd-screener/plan.md` - `docs/features/frontend-fsd-screener/tasks.md` - `apps/frontend/src/features/screener/api/screenerApi.ts` — ScreenerQuery, getScreenerResults - `apps/frontend/src/features/screener/model/useScreener.ts` — URLSearchParams + TanStack Query - `apps/frontend/src/features/screener/model/index.ts` — barrel - `apps/frontend/src/features/screener/ui/FilterPanel.tsx` — фильтры - `apps/frontend/src/features/screener/ui/FilterPanelShare.tsx` — share-фильтры - `apps/frontend/src/features/screener/ui/FilterPanelBond.tsx` — bond-фильтры - `apps/frontend/src/features/screener/ui/ScreenerTable.tsx` — таблица - `apps/frontend/src/features/screener/ui/index.ts` — barrel - `apps/frontend/src/features/screener/index.ts` — public API - `apps/frontend/src/pages/screener/ui/ScreenerPage.tsx` — page entrypoint - `apps/frontend/src/pages/screener/index.ts` — public API ### Modify - `apps/frontend/src/app/routing/AppRoutes.tsx` — import from `@/pages/screener` ### Delete - `apps/frontend/src/api/screener.ts` - `apps/frontend/src/hooks/useScreener.ts` - `apps/frontend/src/components/screener/FilterPanel.tsx` - `apps/frontend/src/components/screener/FilterPanelShare.tsx` - `apps/frontend/src/components/screener/FilterPanelBond.tsx` - `apps/frontend/src/components/screener/ScreenerTable.tsx` - `apps/frontend/src/pages/screener/ScreenerPage.tsx` ## Порядок реализации 1. Создать `features/screener/api/screenerApi.ts` — перенести `ScreenerQuery` + `getScreenerResults` из `api/screener.ts`, обновить импорты на `@/shared/api/client` 2. Создать `features/screener/model/useScreener.ts` — перенести хук из `hooks/useScreener.ts`, обновить импорты 3. Создать `features/screener/ui/` — перенести 4 компонента из `components/screener/`, обновить импорты 4. Создать barrel-файлы (`model/index.ts`, `ui/index.ts`, `features/screener/index.ts`) 5. Создать `pages/screener/ui/ScreenerPage.tsx` — обновить импорты на `@/features/screener` 6. Создать `pages/screener/index.ts` — barrel export 7. Обновить `AppRoutes.tsx` — `import { ScreenerPage } from '@/pages/screener'` 8. Удалить legacy-файлы 9. Verification: `test`, `lint`, `build` ## Verification ```bash npm test -w apps/frontend npm run lint -w apps/frontend npm run build -w apps/frontend # Проверка отсутствия deep imports в новые model/ и ui/ rg -n "@features/screener/(model|ui)" apps/frontend/src --type ts --type tsx || echo "OK: no deep imports from outside" # Проверка импорта pages/screener только через barrel rg -n "@/pages/screener/(ui|ScreenerPage)" apps/frontend/src --type ts --type tsx || echo "OK: no deep page imports" # Проверка, что legacy удалены ! test -f apps/frontend/src/api/screener.ts || echo "FAIL" ! test -f apps/frontend/src/hooks/useScreener.ts || echo "FAIL" ! test -d apps/frontend/src/components/screener || echo "FAIL" ```