docs: add FSD screener feature spec, plan, and tasks
This commit is contained in:
parent
2619a27b80
commit
2fc98341a6
69
docs/features/frontend-fsd-screener/plan.md
Normal file
69
docs/features/frontend-fsd-screener/plan.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# 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"
|
||||||
|
```
|
||||||
49
docs/features/frontend-fsd-screener/spec.md
Normal file
49
docs/features/frontend-fsd-screener/spec.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Frontend FSD Screener
|
||||||
|
|
||||||
|
Дата: 2026-06-20
|
||||||
|
Статус: спецификация
|
||||||
|
|
||||||
|
## Контекст
|
||||||
|
|
||||||
|
Предыдущие FSD-итерации мигрировали broker-домен, shared-слой, entities, app-слой c auth, market pages и portfolios.
|
||||||
|
|
||||||
|
Скринер остаётся единственным крупным блоком кода вне FSD-структуры: `api/screener.ts`, `hooks/useScreener.ts`, `components/screener/` (4 файла), плоская `pages/screener/ScreenerPage.tsx`. Также это первая возможность создать слой `features/` — первый feature-slice в проекте.
|
||||||
|
|
||||||
|
## Цель
|
||||||
|
|
||||||
|
Перевести скринер в FSD, создав `features/screener/` — первый feature-slice, и мигрировав `pages/screener/` в FSD-структуру.
|
||||||
|
|
||||||
|
## Область изменений
|
||||||
|
|
||||||
|
- `features/screener/` — новый слой; включает API-функцию, хук с URLSearchParams + TanStack Query, UI-компоненты (FilterPanel, FilterPanelShare, FilterPanelBond, ScreenerTable)
|
||||||
|
- `pages/screener/` — миграция из плоской страницы в FSD с barrel export
|
||||||
|
- `app/routing/AppRoutes.tsx` — обновление импорта
|
||||||
|
- Удаление legacy: `api/screener.ts`, `hooks/useScreener.ts`, `components/screener/` (4 файла), `pages/screener/ScreenerPage.tsx`
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
### 1. Features слой
|
||||||
|
|
||||||
|
- `features/screener/` содержит полную реализацию скринера: API, модель (URLSearchParams + TanStack Query), UI (фильтры, таблица)
|
||||||
|
- Public API (`index.ts`) экспортирует: `useScreener`, `FilterPanel`, `FilterPanelShare`, `FilterPanelBond`, `ScreenerTable`
|
||||||
|
- Запрещены глубокие импорты в `model/` или `ui/` извне `features/screener/`
|
||||||
|
|
||||||
|
### 2. Pages слой
|
||||||
|
|
||||||
|
- `pages/screener/` — тонкая композиция, только импортирует из `features/screener`
|
||||||
|
- Public API (`index.ts`) экспортирует `ScreenerPage`
|
||||||
|
|
||||||
|
### 3. Совместимость
|
||||||
|
|
||||||
|
- Никаких shim-файлов не требуется — скринер не имеет внешних потребителей кроме `AppRoutes`
|
||||||
|
- Поведение страницы скринера не меняется
|
||||||
|
|
||||||
|
## Критерии приемки (Acceptance Criteria)
|
||||||
|
|
||||||
|
- [ ] `npm test -w apps/frontend` — PASS
|
||||||
|
- [ ] `npm run lint -w apps/frontend` — PASS
|
||||||
|
- [ ] `npm run build -w apps/frontend` — PASS
|
||||||
|
- [ ] Нет deep imports в `features/screener/model/` или `features/screener/ui/` извне
|
||||||
|
- [ ] `pages/screener/` импортируется только через barrel (`@/pages/screener`)
|
||||||
|
- [ ] `features/screener/` импортируется только через barrel (`@/features/screener`)
|
||||||
|
- [ ] Все legacy-файлы удалены
|
||||||
47
docs/features/frontend-fsd-screener/tasks.md
Normal file
47
docs/features/frontend-fsd-screener/tasks.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Frontend FSD Screener — задачи
|
||||||
|
|
||||||
|
Статус: в работе
|
||||||
|
|
||||||
|
Подробные шаги, карта файлов и verification-команды находятся в [plan.md](plan.md).
|
||||||
|
|
||||||
|
## 1. API слой
|
||||||
|
|
||||||
|
- [ ] Создать `features/screener/api/screenerApi.ts` — перенос `ScreenerQuery` + `getScreenerResults`
|
||||||
|
- [ ] Обновить импорты: `@/shared/api/client`, `@/shared/api/responses`
|
||||||
|
|
||||||
|
## 2. Модель
|
||||||
|
|
||||||
|
- [ ] Создать `features/screener/model/useScreener.ts` — перенос хука
|
||||||
|
- [ ] Создать `features/screener/model/index.ts`
|
||||||
|
|
||||||
|
## 3. UI компоненты
|
||||||
|
|
||||||
|
- [ ] Перенести `FilterPanel.tsx` в `features/screener/ui/`
|
||||||
|
- [ ] Перенести `FilterPanelShare.tsx` в `features/screener/ui/`
|
||||||
|
- [ ] Перенести `FilterPanelBond.tsx` в `features/screener/ui/`
|
||||||
|
- [ ] Перенести `ScreenerTable.tsx` в `features/screener/ui/`
|
||||||
|
- [ ] Создать `features/screener/ui/index.ts`
|
||||||
|
- [ ] Создать `features/screener/index.ts`
|
||||||
|
|
||||||
|
## 4. Pages
|
||||||
|
|
||||||
|
- [ ] Создать `pages/screener/ui/ScreenerPage.tsx` — обновить импорты на `@/features/screener`
|
||||||
|
- [ ] Создать `pages/screener/index.ts`
|
||||||
|
|
||||||
|
## 5. Роутинг
|
||||||
|
|
||||||
|
- [ ] Обновить `app/routing/AppRoutes.tsx` — import from `@/pages/screener`
|
||||||
|
|
||||||
|
## 6. Удаление legacy
|
||||||
|
|
||||||
|
- [ ] Удалить `api/screener.ts`
|
||||||
|
- [ ] Удалить `hooks/useScreener.ts`
|
||||||
|
- [ ] Удалить `components/screener/` (директория)
|
||||||
|
|
||||||
|
## 7. Verification
|
||||||
|
|
||||||
|
- [ ] `npm test -w apps/frontend` — PASS
|
||||||
|
- [ ] `npm run lint -w apps/frontend` — PASS
|
||||||
|
- [ ] `npm run build -w apps/frontend` — PASS
|
||||||
|
- [ ] Нет deep imports в `features/screener/` извне
|
||||||
|
- [ ] `pages/screener/` импортируется только через barrel
|
||||||
Loading…
x
Reference in New Issue
Block a user