14 KiB
Raw Blame History

План реализации редизайна обзора брокерского счёта

Для агентных исполнителей: ОБЯЗАТЕЛЬНЫЙ SUB-SKILL: использовать superpowers:subagent-driven-development (предпочтительно) или superpowers:executing-plans для пошагового выполнения. Шаги ведутся чекбоксами - [ ].

Цель: превратить /broker/:accountId в компактный инвестиционный дашборд на текущей светлой теме без изменения backend-контрактов и URL-структуры.

Архитектура: маршрут и FSD-границы остаются прежними. Композиция собирается в widgets/broker-dashboard, данные продолжают приходить из существующих entities/* hooks. Навигация счёта остаётся в BrokerAccountLayout, а dashboard использует только локальные presentation/helpers без выноса брокерской логики в design system.

Технологии: React 18, TanStack Router, TanStack Query, MUI через @moex-vibe/design-system, Vitest, Testing Library.


Область реализации

Файлы

  • Modify: apps/frontend/src/widgets/broker-account-layout/ui/BrokerAccountLayout.tsx — горизонтальные вкладки над контентом обзора и подробных разделов.
  • Modify: apps/frontend/src/pages/broker-account/ui/BrokerAccountOverviewPage.tsx — точка входа обзора через dashboard.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/index.ts — публичный API dashboard-виджета.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboard.tsx — верхнеуровневая композиция и управление filter state.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardHero.tsx — hero KPI с fallback-значениями и выравниванием Metric.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardCard.tsx — локальный паттерн карточки.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardEventsCard.tsx — карточка событий.
  • Create: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardDateFilter.tsx — переиспользуемый фильтр дат с draft/apply поведением.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardIncomeCard.tsx — карточка доходов.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardAnalyticsCard.tsx — карточка аналитики доходности.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardAllocationCard.tsx — карточка аллокации с горизонтальными барами.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardSkeleton.tsx — skeleton-форма dashboard.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboard.test.tsx — компонентные тесты композиции и фильтров.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/lib/dashboardIncome.ts — чистые helpers доходных операций.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/lib/dashboardIncome.test.ts — unit-тесты income helpers.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/lib/dashboardFilters.ts — пресеты дат, validate и mapping income types.
  • Create/Modify: apps/frontend/src/widgets/broker-dashboard/lib/dashboardFormatters.ts — локальные formatter/helpers для fallback и event labels.
  • Modify: docs/features/broker-dashboard-redesign/tasks.md — фиксация статусов выполнения.

Источники данных

  • Портфель: useBrokerAccountContext().portfolio.
  • События: useBrokerEvents(accountId, { from, to, types }).
  • Операции: useBrokerOperations(accountId, { from, to, operationTypes, cursor, limit: 10 }).
  • Аналитика: useBrokerAnalytics(accountId).
  • Аллокация: buildBrokerAllocation(portfolio).

Технические решения

1. Композиция страницы

  • Dashboard на desktop и mobile строится в одну колонку: Hero, События, Доходы, Аналитика доходности, Аллокация.
  • Двухколоночный layout из прототипа не переносится.
  • Навигация счёта находится над контентом в BrokerAccountLayout и не дублируется внутри dashboard.

2. Hero KPI

  • Hero показывает название счёта, стоимость портфеля, доходность, дневное изменение и всего полученных доходов.
  • Приоритет доходности: analytics.totalReturnPercent, затем portfolio.yields.expectedPercent, иначе .
  • Дневное изменение берётся из portfolio.yields.daily и portfolio.yields.dailyPercent, при недоступности показывается .
  • Все Metric должны иметь одинаковую высоту; supporting text не должен ломать вертикальный ритм.

3. События

  • Типы событий переключаются chip-фильтрами с немедленным применением.
  • Диапазон дат редактируется отдельно от применённого состояния: draft state меняется локально, запрос уходит только по Показать.
  • При пустом выборе типов запрос отключается, карточка показывает валидационное сообщение.
  • Пагинация локальная, по 10 событий на страницу, сбрасывается при смене применённых фильтров.

4. Доходы

  • Доходы строятся на существующем endpoint операций только для OPERATION_TYPE_DIVIDEND, OPERATION_TYPE_DIV_EXT, OPERATION_TYPE_COUPON.
  • Типы доходов переключаются chip-фильтрами с немедленным применением.
  • Диапазон дат использует тот же draft/apply паттерн, что и события.
  • Пагинация cursor-based, размер страницы 10, сбрасывается при смене применённых фильтров.

5. Аналитика и аллокация

  • Карточка аналитики использует существующий analytics endpoint и показывает спокойное empty state при отсутствии данных.
  • Карточка аллокации не использует donut chart. Она строит список горизонтальных bar rows по buildBrokerAllocation.
  • Отрицательные значения показываются текстом без полосы.

6. Ошибки и пустые состояния

  • Ошибка portfolio роняет весь обзор.
  • Ошибки events, income, analytics локальны соответствующим карточкам.
  • Пустые данные показываются отдельными сообщениями, а не нулевыми значениями.

Задачи

Задача 1: Базовые helpers и локальные dashboard-patterns

Файлы:

  • apps/frontend/src/widgets/broker-dashboard/lib/dashboardIncome.ts

  • apps/frontend/src/widgets/broker-dashboard/lib/dashboardIncome.test.ts

  • apps/frontend/src/widgets/broker-dashboard/lib/dashboardFilters.ts

  • apps/frontend/src/widgets/broker-dashboard/lib/dashboardFormatters.ts

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardCard.tsx

  • Убедиться, что income helpers покрывают только допустимые типы доходов и умеют считать итог отображаемых строк.

  • Убедиться, что filter helpers содержат default state, date presets, validate и mapping income type -> operation types.

  • Убедиться, что formatters покрывают fallback-значения, label типов событий и label статусов.

  • Использовать локальный BrokerDashboardCard как основной контейнер карточек; design system расширять только если без этого нельзя реализовать требования спецификации.

Задача 2: Hero и layout overview

Файлы:

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardHero.tsx

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardSkeleton.tsx

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboard.tsx

  • apps/frontend/src/pages/broker-account/ui/BrokerAccountOverviewPage.tsx

  • apps/frontend/src/widgets/broker-account-layout/ui/BrokerAccountLayout.tsx

  • Собрать обзор через BrokerDashboard и BrokerDashboardSkeleton.

  • Оставить навигацию счёта в BrokerAccountLayout как горизонтальные вкладки над контентом.

  • Исправить hero так, чтобы все Metric были одной высоты и поддерживающий текст не поднимал одну ячейку выше остальных.

  • Проверить, что dashboard остаётся одноколоночным и на desktop, и на mobile.

Задача 3: Карточка событий

Файлы:

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardDateFilter.tsx

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardEventsCard.tsx

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboard.tsx

  • Добавить переиспользуемый BrokerDashboardDateFilter с preset chips, полями from/to, действиями Сбросить и Показать.

  • Подключить для событий draft/applied state: типы применяются сразу, даты только по Показать.

  • Сохранять локальную пагинацию по 10 событий и сбрасывать её при смене применённых фильтров.

  • Оставить локальные loading/error/empty states внутри карточки.

Задача 4: Карточка доходов

Файлы:

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardIncomeCard.tsx

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboard.tsx

  • Подключить тот же BrokerDashboardDateFilter для доходов с draft/applied state.

  • Оставить chip-фильтры типов доходов с немедленным применением.

  • Сохранить cursor pagination по 10 операций и сбрасывать её при смене применённых фильтров.

  • Если endpoint операций даёт недостаточно релевантных строк для dashboard, зафиксировать ограничение в заметках по реализации, а не расширять backend в рамках этой фичи.

Задача 5: Карточки аналитики и аллокации

Файлы:

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardAnalyticsCard.tsx

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboardAllocationCard.tsx

  • Довести карточку аналитики до соответствия спецификации по полям и состояниям.

  • Заменить donut chart на горизонтальные бары, построенные из buildBrokerAllocation.

  • Отрицательные значения аллокации выводить отдельно текстом без bar.

Задача 6: Тесты и верификация

Файлы:

  • apps/frontend/src/widgets/broker-dashboard/ui/BrokerDashboard.test.tsx

  • docs/features/broker-dashboard-redesign/tasks.md

  • Обновить компонентные тесты dashboard так, чтобы они покрывали текущую композицию, фильтры и основные empty/error states.

  • Прогнать rtk npm run test:frontend -- --run src/widgets/broker-dashboard.

  • Прогнать rtk npm run test:frontend.

  • Прогнать rtk npm run test:design-system && rtk npm run lint -w apps/frontend && rtk npm run build:frontend.

  • Проверить вручную desktop layout /broker/2084014113.

  • Проверить вручную mobile layout /broker/2084014113 на viewport 390x844.

  • После завершения обновить docs/features/broker-dashboard-redesign/tasks.md и выполнить graphify update ..

Проверка покрытия спецификации

  • Общая композиция и горизонтальная навигация: задачи 2 и 6.
  • Hero KPI и equal-height Metric: задача 2.
  • События с chip filters, date filters и локальной пагинацией: задача 3.
  • Доходы с chip filters, date filters и cursor pagination: задача 4.
  • Аналитика и аллокация с горизонтальными барами: задача 5.
  • Ошибки, empty states, тесты и ручная верификация: задача 6.