22 KiB
Frontend FSD Broker Pilot Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [x]) syntax for tracking.
Goal: Перевести broker-домен frontend на первый вертикальный FSD-срез без изменения пользовательского поведения и с сохранением текущих data contracts.
Architecture: Миграция идёт по вертикали: сначала создаётся FSD-каркас pages/widgets/entities/shared, затем broker-specific API/query/read-model логика переносится ближе к доменным срезам, а route entrypoints остаются тонкими оболочками. На время перехода допускаются совместимые re-export entrypoints, чтобы маршруты и тесты можно было переводить постепенно без big-bang переписывания.
Tech Stack: React 18, TypeScript, React Router v6, TanStack Query v5, Vitest, Testing Library, ESLint, Docusaurus.
Карта файлов
- Create
apps/frontend/src/pages/broker-accounts/index.ts— public entrypoint страницы списка счетов. - Create
apps/frontend/src/pages/broker-account/index.ts— public entrypoint layout/overview route shell. - Create
apps/frontend/src/pages/broker-positions/index.ts— public entrypoint страниц позиций. - Create
apps/frontend/src/pages/broker-operations/index.ts— public entrypoint страницы операций. - Create
apps/frontend/src/widgets/broker-account-card/index.ts— public API карточки счёта. - Create
apps/frontend/src/widgets/broker-account-card/ui/BrokerAccountCard.tsx— screen-level карточка счёта. - Create
apps/frontend/src/widgets/broker-accounts-summary/index.ts— public API общей сводки. - Create
apps/frontend/src/widgets/broker-accounts-summary/ui/BrokerAccountsSummary.tsx— summary widget. - Create
apps/frontend/src/widgets/broker-allocation-chart/index.ts— public API allocation chart widget. - Create
apps/frontend/src/widgets/broker-allocation-chart/ui/BrokerAllocationChart.tsx— account allocation widget. - Create
apps/frontend/src/widgets/broker-operations-table/index.ts— public API operations table widget. - Create
apps/frontend/src/widgets/broker-operations-table/ui/BrokerOperationsTable.tsx— reusable broker operations widget. - Create
apps/frontend/src/entities/broker-account/index.ts— public API account slice. - Create
apps/frontend/src/entities/broker-account/api/brokerAccountApi.ts— broker account endpoints и query parameter helpers. - Create
apps/frontend/src/entities/broker-account/model/useBrokerAccounts.ts— accounts query hook. - Create
apps/frontend/src/entities/broker-account/model/useBrokerAccountPortfolios.ts— list portfolio queries. - Create
apps/frontend/src/entities/broker-account/model/useBrokerPortfolio.ts— single account portfolio query. - Create
apps/frontend/src/entities/broker-account/model/brokerAccountsOverview.ts— aggregation/read-model helpers. - Create
apps/frontend/src/entities/broker-account/model/brokerAccountsOverview.test.ts— unit-тесты агрегатов. - Create
apps/frontend/src/entities/broker-account/ui/BrokerAccountLayout.tsx— nested account route shell и context. Create(покрывается интеграционными тестами вapps/frontend/src/entities/broker-account/ui/BrokerAccountLayout.test.tsx— тесты route shell.BrokerPages.test.tsx)- Create
apps/frontend/src/entities/broker-position/index.ts— public API position slice. - Create
apps/frontend/src/entities/broker-position/api/brokerPositionApi.ts— positions endpoint wrapper. - Create
apps/frontend/src/entities/broker-position/model/useBrokerPositions.ts— positions query hook. - Create
apps/frontend/src/entities/broker-position/model/brokerDisplay.ts— instrument path helpers for positions. - Create
apps/frontend/src/entities/broker-position/model/brokerAllocation.ts— allocation helpers for chart/table composition. - Create
apps/frontend/src/entities/broker-position/model/brokerAllocation.test.ts— allocation unit-тесты. - Create
apps/frontend/src/entities/broker-position/model/brokerDisplay.test.ts— unit-тесты instrument-path mapping. - Create
apps/frontend/src/entities/broker-operation/index.ts— public API operation slice. - Create
apps/frontend/src/entities/broker-operation/api/brokerOperationApi.ts— operations endpoint wrapper and query type. - Create
apps/frontend/src/entities/broker-operation/model/useBrokerOperations.ts— operations query hook. - Create
apps/frontend/src/entities/broker-operation/model/operationFilters.ts— filter options and guards. - Create
apps/frontend/src/entities/broker-operation/model/operationFilters.test.ts— unit-тесты фильтров/guards. - Create
apps/frontend/src/entities/broker-operation/model/useBrokerOperations.test.tsx— hook-тесты операций. - Create
apps/frontend/src/pages/broker-accounts/ui/BrokerAccountsPage.tsx— тонкий page entrypoint списка счетов. - Create
apps/frontend/src/pages/broker-account/ui/BrokerAccountOverviewPage.tsx— overview page composition. - Create
apps/frontend/src/pages/broker-positions/ui/BrokerPositionsPage.tsx— positions page composition. - Create
apps/frontend/src/pages/broker-operations/ui/BrokerOperationsPage.tsx— operations page composition. - Create
apps/frontend/src/pages/broker-accounts/ui/BrokerAccountsPage.test.tsx— component/page tests списка счетов. - Modify
apps/frontend/src/pages/broker/BrokerPages.test.tsx— integration coverage брокерских route entrypoints через новые public entrypoints. - Modify
apps/frontend/src/routes.tsx— переключить маршруты на новые FSD entrypoints. - Modify
apps/frontend/src/styles.css— скорректировать только импорто-независимые broker selectors, если это нужно после перемещения компонентов, без изменения UX. - Modify
apps/frontend/src/api/broker.test.ts— оставить покрытие общего request-контракта после выноса wrappers. - Modify
apps/docs/docs/frontend/overview.md— зафиксировать coexistence старой структуры и broker FSD pilot. - Modify
docs/features/frontend-fsd-broker-pilot/tasks.md— отмечать прогресс по фазам.
Task 1: Создать FSD entrypoints и безопасный маршрутный каркас
Files:
-
Create:
apps/frontend/src/pages/broker-accounts/index.ts -
Create:
apps/frontend/src/pages/broker-account/index.ts -
Create:
apps/frontend/src/pages/broker-positions/index.ts -
Create:
apps/frontend/src/pages/broker-operations/index.ts -
Create:
apps/frontend/src/pages/broker-accounts/ui/BrokerAccountsPage.tsx -
Create:
apps/frontend/src/pages/broker-account/ui/BrokerAccountOverviewPage.tsx -
Create:
apps/frontend/src/pages/broker-positions/ui/BrokerPositionsPage.tsx -
Create:
apps/frontend/src/pages/broker-operations/ui/BrokerOperationsPage.tsx -
Modify:
apps/frontend/src/routes.tsx -
Step 1: Написать smoke-тест на broker routes
import { MemoryRouter } from 'react-router-dom';
import { render, screen } from '@testing-library/react';
import { AppRoutes } from '../../routes';
it('renders broker routes through fsd entrypoints', () => {
render(
<MemoryRouter initialEntries={['/broker']}>
<AppRoutes />
</MemoryRouter>,
);
expect(screen.getByRole('heading', { name: /брокерские счета/i })).toBeInTheDocument();
});
- Step 2: Запустить route smoke-test и подтвердить RED
Run: npm test -w apps/frontend -- BrokerPages.test.tsx
Expected: FAIL, потому что новые page entrypoints ещё не существуют.
- Step 3: Создать public entrypoints страниц и временно реэкспортировать текущие реализации
// apps/frontend/src/pages/broker-accounts/index.ts
export { BrokerAccountsPage } from './ui/BrokerAccountsPage';
// apps/frontend/src/pages/broker-accounts/ui/BrokerAccountsPage.tsx
export { BrokerAccountsPage } from '../../broker/BrokerAccountsPage';
// apps/frontend/src/routes.tsx
import { BrokerAccountsPage } from './pages/broker-accounts';
import { BrokerAccountOverviewPage } from './pages/broker-account';
import { BrokerPositionsPage } from './pages/broker-positions';
import { BrokerOperationsPage } from './pages/broker-operations';
- Step 4: Запустить route smoke-test и подтвердить GREEN
Run: npm test -w apps/frontend -- BrokerPages.test.tsx
Expected: PASS.
- Step 5: Закоммитить безопасный FSD routing shell
git add apps/frontend/src/routes.tsx apps/frontend/src/pages/broker-accounts apps/frontend/src/pages/broker-account apps/frontend/src/pages/broker-positions apps/frontend/src/pages/broker-operations
git commit -m "refactor(frontend): add broker fsd page entrypoints"
Task 2: Перенести broker-account slice и read-model списка счетов
Files:
-
Create:
apps/frontend/src/entities/broker-account/index.ts -
Create:
apps/frontend/src/entities/broker-account/api/brokerAccountApi.ts -
Create:
apps/frontend/src/entities/broker-account/model/useBrokerAccounts.ts -
Create:
apps/frontend/src/entities/broker-account/model/useBrokerAccountPortfolios.ts -
Create:
apps/frontend/src/entities/broker-account/model/useBrokerPortfolio.ts -
Create:
apps/frontend/src/entities/broker-account/model/brokerAccountsOverview.ts -
Create:
apps/frontend/src/entities/broker-account/model/brokerAccountsOverview.test.ts -
Create:
apps/frontend/src/widgets/broker-account-card/index.ts -
Create:
apps/frontend/src/widgets/broker-account-card/ui/BrokerAccountCard.tsx -
Create:
apps/frontend/src/widgets/broker-accounts-summary/index.ts -
Create:
apps/frontend/src/widgets/broker-accounts-summary/ui/BrokerAccountsSummary.tsx -
Modify:
apps/frontend/src/pages/broker-accounts/ui/BrokerAccountsPage.tsx -
Step 1: Перенести unit-тесты read-model в новый slice path
import { aggregateBrokerAccounts } from '../model/brokerAccountsOverview';
describe('aggregateBrokerAccounts', () => {
it('keeps currencies separate and preserves daily percent rules', () => {
// reuse current brokerAccountsOverview.test.ts scenarios verbatim
});
});
- Step 2: Запустить read-model unit-тест и подтвердить RED
Run: npm test -w apps/frontend -- brokerAccountsOverview.test.ts
Expected: FAIL, потому что новый entity path пока не экспортирует implementation.
- Step 3: Перенести broker account API/hooks/aggregation и подключить widgets через public API
// apps/frontend/src/entities/broker-account/index.ts
export { useBrokerAccounts } from './model/useBrokerAccounts';
export { useBrokerAccountPortfolios } from './model/useBrokerAccountPortfolios';
export { useBrokerPortfolio } from './model/useBrokerPortfolio';
export { aggregateBrokerAccounts } from './model/brokerAccountsOverview';
export {
getBrokerAccounts,
getBrokerPortfolio,
type BrokerOperationQuery,
} from './api/brokerAccountApi';
// apps/frontend/src/pages/broker-accounts/ui/BrokerAccountsPage.tsx
import {
aggregateBrokerAccounts,
useBrokerAccounts,
useBrokerAccountPortfolios,
} from '../../../entities/broker-account';
import { BrokerAccountCard } from '../../../widgets/broker-account-card';
import { BrokerAccountsSummary } from '../../../widgets/broker-accounts-summary';
- Step 4: Запустить account slice тесты и страницы списка
Run: npm test -w apps/frontend -- brokerAccountsOverview.test.ts BrokerAccountsPage.test.tsx useBrokerAccountPortfolios.test.tsx useBrokerAccounts.test.tsx
Expected: PASS.
- Step 5: Удалить или превратить старые
src/hooks/useBrokerAccounts.ts,src/hooks/useBrokerAccountPortfolios.ts,src/hooks/useBrokerPortfolio.ts,src/pages/broker/BrokerAccountCard.tsx,src/pages/broker/BrokerAccountsSummary.tsx,src/pages/broker/brokerAccountsOverview.tsв совместимые re-export shim-файлы
export {
useBrokerAccounts,
useBrokerAccountPortfolios,
useBrokerPortfolio,
aggregateBrokerAccounts,
} from '../entities/broker-account';
- Step 6: Закоммитить broker-account slice
git add apps/frontend/src/entities/broker-account apps/frontend/src/widgets/broker-account-card apps/frontend/src/widgets/broker-accounts-summary apps/frontend/src/pages/broker-accounts apps/frontend/src/hooks/useBrokerAccounts.ts apps/frontend/src/hooks/useBrokerAccountPortfolios.ts apps/frontend/src/hooks/useBrokerPortfolio.ts apps/frontend/src/pages/broker/BrokerAccountCard.tsx apps/frontend/src/pages/broker/BrokerAccountsSummary.tsx apps/frontend/src/pages/broker/brokerAccountsOverview.ts
git commit -m "refactor(frontend): move broker account slice to fsd"
Task 3: Перенести broker-position slice и allocation/instrument helpers
Files:
-
Create:
apps/frontend/src/entities/broker-position/index.ts -
Create:
apps/frontend/src/entities/broker-position/api/brokerPositionApi.ts -
Create:
apps/frontend/src/entities/broker-position/model/useBrokerPositions.ts -
Create:
apps/frontend/src/entities/broker-position/model/brokerAllocation.ts -
Create:
apps/frontend/src/entities/broker-position/model/brokerAllocation.test.ts -
Create:
apps/frontend/src/entities/broker-position/model/brokerDisplay.ts -
Create:
apps/frontend/src/entities/broker-position/model/brokerDisplay.test.ts -
Create:
apps/frontend/src/widgets/broker-allocation-chart/index.ts -
Create:
apps/frontend/src/widgets/broker-allocation-chart/ui/BrokerAllocationChart.tsx -
Modify:
apps/frontend/src/pages/broker-account/ui/BrokerAccountOverviewPage.tsx -
Modify:
apps/frontend/src/pages/broker-positions/ui/BrokerPositionsPage.tsx -
Step 1: Переместить существующие unit-тесты
brokerAllocationиbrokerDisplayв новый entity slice
import { buildBrokerAllocation } from '../model/brokerAllocation';
import { getBrokerInstrumentPath } from '../model/brokerDisplay';
- Step 2: Запустить position-related unit-тесты и подтвердить RED
Run: npm test -w apps/frontend -- brokerAllocation.test.ts brokerDisplay.test.ts
Expected: FAIL, потому что новые entity exports ещё не подключены.
- Step 3: Перенести positions API/query/model и переключить overview/positions pages на public API
// apps/frontend/src/entities/broker-position/index.ts
export { useBrokerPositions } from './model/useBrokerPositions';
export { buildBrokerAllocation } from './model/brokerAllocation';
export { getBrokerInstrumentPath } from './model/brokerDisplay';
// apps/frontend/src/pages/broker-positions/ui/BrokerPositionsPage.tsx
import { useBrokerPositions, getBrokerInstrumentPath } from '../../../entities/broker-position';
- Step 4: Запустить position page tests
Run: npm test -w apps/frontend -- BrokerPages.test.tsx brokerAllocation.test.ts brokerDisplay.test.ts
Expected: PASS.
- Step 5: Перевести старые files
src/hooks/useBrokerPositions.ts,src/pages/broker/brokerAllocation.ts,src/pages/broker/brokerDisplay.ts,src/pages/broker/BrokerAllocationChart.tsx,src/pages/broker/BrokerPositionsPage.tsxв re-export shim или удалить после переключения импортов
git add apps/frontend/src/entities/broker-position apps/frontend/src/widgets/broker-allocation-chart apps/frontend/src/pages/broker-account apps/frontend/src/pages/broker-positions apps/frontend/src/hooks/useBrokerPositions.ts apps/frontend/src/pages/broker/brokerAllocation.ts apps/frontend/src/pages/broker/brokerDisplay.ts apps/frontend/src/pages/broker/BrokerAllocationChart.tsx apps/frontend/src/pages/broker/BrokerPositionsPage.tsx
git commit -m "refactor(frontend): move broker position slice to fsd"
Task 4: Перенести broker-operation slice, layout shell и page composition
Files:
-
Create:
apps/frontend/src/entities/broker-operation/index.ts -
Create:
apps/frontend/src/entities/broker-operation/api/brokerOperationApi.ts -
Create:
apps/frontend/src/entities/broker-operation/model/useBrokerOperations.ts -
Create:
apps/frontend/src/entities/broker-operation/model/operationFilters.ts -
Create:
apps/frontend/src/entities/broker-operation/model/operationFilters.test.ts -
Create:
apps/frontend/src/entities/broker-operation/model/useBrokerOperations.test.tsx -
Create:
apps/frontend/src/widgets/broker-operations-table/index.ts -
Create:
apps/frontend/src/widgets/broker-operations-table/ui/BrokerOperationsTable.tsx -
Create:
apps/frontend/src/entities/broker-account/ui/BrokerAccountLayout.tsx -
Modify:
apps/frontend/src/pages/broker-account/ui/BrokerAccountOverviewPage.tsx -
Modify:
apps/frontend/src/pages/broker-operations/ui/BrokerOperationsPage.tsx -
Modify:
apps/frontend/src/routes.tsx -
Step 1: Добавить unit-тесты для guards и filters операций
import {
BROKER_OPERATION_TYPE_OPTIONS,
isBrokerOperationType,
} from '../model/operationFilters';
it('accepts only declared broker operation types', () => {
expect(isBrokerOperationType('OPERATION_TYPE_BUY')).toBe(true);
expect(isBrokerOperationType('unexpected')).toBe(false);
});
- Step 2: Запустить tests операций и подтвердить RED
Run: npm test -w apps/frontend -- operationFilters.test.ts BrokerPages.test.tsx
Expected: FAIL, потому что filters/layout/operations public API ещё не созданы.
- Step 3: Перенести operations API/query/filter logic, route shell и operations table widget
// apps/frontend/src/entities/broker-operation/index.ts
export { useBrokerOperations } from './model/useBrokerOperations';
export {
BROKER_OPERATION_TYPE_OPTIONS,
isBrokerOperationType,
} from './model/operationFilters';
// apps/frontend/src/entities/broker-account/ui/BrokerAccountLayout.tsx
import { useBrokerPortfolio } from '../model/useBrokerPortfolio';
// apps/frontend/src/pages/broker-operations/ui/BrokerOperationsPage.tsx
import {
BROKER_OPERATION_TYPE_OPTIONS,
isBrokerOperationType,
useBrokerOperations,
} from '../../../entities/broker-operation';
import { BrokerOperationsTable } from '../../../widgets/broker-operations-table';
- Step 4: Запустить operations/layout/page tests
Run: npm test -w apps/frontend -- BrokerPages.test.tsx BrokerAccountsPage.test.tsx operationFilters.test.ts useBrokerOperations.test.tsx
Expected: PASS.
- Step 5: Перевести старые files
src/hooks/useBrokerOperations.ts,src/pages/broker/BrokerOperationsPage.tsx,src/pages/broker/BrokerOperationsTable.tsx,src/pages/broker/BrokerAccountLayout.tsxв shim или удалить
git add apps/frontend/src/entities/broker-operation apps/frontend/src/entities/broker-account/ui/BrokerAccountLayout.tsx apps/frontend/src/widgets/broker-operations-table apps/frontend/src/pages/broker-operations apps/frontend/src/routes.tsx apps/frontend/src/hooks/useBrokerOperations.ts apps/frontend/src/pages/broker/BrokerOperationsPage.tsx apps/frontend/src/pages/broker/BrokerOperationsTable.tsx apps/frontend/src/pages/broker/BrokerAccountLayout.tsx
git commit -m "refactor(frontend): move broker operations and layout to fsd"
Task 5: Завершить cleanup, документацию и verification
Files:
-
Modify:
apps/frontend/src/pages/broker/BrokerPages.test.tsx -
Modify:
apps/frontend/src/styles.css -
Modify:
apps/docs/docs/frontend/overview.md -
Modify:
docs/features/frontend-fsd-broker-pilot/tasks.md -
Step 1: Сконцентрировать broker route coverage вокруг новых FSD entrypoints
// keep behaviour assertions, but import only through new public routes/pages
expect(screen.getByRole('heading', { name: /брокерские счета/i })).toBeInTheDocument();
expect(screen.getByRole('link', { name: /вся история/i })).toHaveAttribute('href');
- Step 2: Обновить опубликованную frontend-документацию
## Структура исходников
Broker-домен переведён в пилотный FSD-срез:
- `pages/broker-*` — route entrypoints
- `widgets/broker-*` — screen-level композиция
- `entities/broker-account|broker-position|broker-operation` — доменные срезы
Остальные домены пока остаются в исторической технической структуре.
- Step 3: Отметить выполнение в
tasks.mdи прогнать обязательные проверки
Run: npm test -w apps/frontend
Expected: PASS.
Run: npm run lint -w apps/frontend
Expected: PASS.
Run: npm run build -w apps/frontend
Expected: PASS.
Run: npm run build -w apps/docs
Expected: PASS.
- Step 4: Выполнить финальный diff-review перед завершением
Run: git diff --stat main...HEAD
Expected: только broker FSD pilot, docs и связанные test/style updates без затрагивания других доменов.
- Step 5: Закоммитить cleanup и docs
git add apps/frontend/src/pages/broker/BrokerPages.test.tsx apps/frontend/src/styles.css apps/docs/docs/frontend/overview.md docs/features/frontend-fsd-broker-pilot/tasks.md
git commit -m "docs: document broker fsd pilot"