19 KiB
Raw Blame History

Редизайн обзора брокерского счёта в инвестиционный дашборд

Дата: 2026-06-26 (обновлено 2026-06-27) Статус: согласовано к планированию Эпик: Портфель брокера

Контекст

Текущий маршрут /broker/:accountId показывает корректный overview выбранного брокерского счёта, но визуально остаётся вертикальным набором отдельных блоков: сводка, аллокация, карточки активов, ближайшие события и последние операции. Пользователь подготовил прототип temp.html, где тот же домен представлен как более плотный инвестиционный дашборд с hero KPI, компактными таблицами и аналитическими карточками.

После обсуждения выбран вариант A: страница /broker/:accountId должна стать единым дашбордом, используя структуру и плотность прототипа, но сохраняя текущую светлую тему и компоненты @moex-vibe/design-system. Тёмная тема из прототипа не переносится в первую версию. При этом двухколоночная desktop-композиция прототипа сознательно не переносится: и на desktop, и на mobile блоки dashboard идут по одному на строке в фиксированном порядке.

Цель

Сделать overview брокерского счёта быстрым обзором состояния портфеля, будущих/прошедших событий, полученных доходов, аналитики доходности и аллокации без перехода по вкладкам.

Пользовательский результат

Пользователь может на /broker/:accountId:

  • сразу увидеть стоимость портфеля, доходность и сумму полученных доходов;
  • увидеть ближайшие события по счёту в компактной таблице;
  • увидеть последние доходные операции по дивидендам и купонам и итог по ним;
  • оценить вложения, полученные выплаты и доходность по существующей аналитике;
  • увидеть структуру портфеля через горизонтальные полосы аллокации и подписи к ним;
  • перейти в существующие подробные вкладки Акции, Облигации, Операции, События и Аналитика для drill-down сценариев.

Область изменений

Фича относится только к frontend-маршруту /broker/:accountId и связанным frontend-компонентам брокерского overview.

В область входят:

  • новая dashboard-композиция для BrokerAccountOverviewPage;
  • переиспользуемые frontend-паттерны для dashboard card, KPI, compact table и filter chips;
  • адаптация существующих брокерских widgets под новую компоновку, если это нужно для читаемости;
  • точечные доработки @moex-vibe/design-system, если существующие компоненты блокируют корректное использование текущей светлой DS-темы;
  • тесты новой композиции и ключевых представлений.

Требования

1. Общая композиция

  • /broker/:accountId остаётся overview выбранного брокерского счёта.
  • Overview визуально становится dashboard-страницей, а не вертикальным списком независимых секций.
  • Существующая навигация счёта отображается горизонтальными вкладками над контентом, чтобы не занимать левую колонку и оставить больше пространства для таблиц dashboard.
  • На desktop и mobile блоки dashboard отображаются по одному блоку на строке: hero KPI, События, Доходы, Аналитика доходности, Аллокация.
  • Существующая навигация счёта сохраняет ссылки на Обзор, Акции, Облигации, Операции, События, Аналитика.
  • На мобильном viewport сохраняется тот же порядок блоков в одну колонку.

2. Визуальный стиль

  • Используется текущая светлая DS-тема MoexVibe.
  • Не добавляется dark mode и не переносится тёмная палитра temp.html.
  • Визуальная плотность, структура карточек, KPI-иерархия и компактность таблиц ориентируются на temp.html.
  • Дизайн использует компоненты и токены @moex-vibe/design-system там, где они применимы.
  • Если DS-компонент слишком ограничен, допускается точечно расширить DS API или создать локальный dashboard-pattern в frontend, но не добавлять доменную брокерскую логику в DS.

3. Hero KPI

Hero показывает:

  • название счёта или fallback Брокерский счёт;
  • стоимость портфеля из portfolio.totals.portfolio;
  • доходность из существующих данных: приоритет broker analytics.totalReturnPercent, если загружена, иначе portfolio.yields.expectedPercent, если доступна;
  • дневное изменение из portfolio.yields.daily и portfolio.yields.dailyPercent, если доступно;
  • всего полученных доходов из broker analytics.totalReceived, если аналитика загружена;
  • спокойный fallback для недоступных значений.
  • Все Metric-блоки имеют одинаковую высоту в grid-ряду, даже если у некоторых есть supportingText. Поддерживающий текст остаётся внутри Metric, но все Metrics растягиваются на полную высоту grid-ячейки с выравниванием от верхнего края.

4. Блок События

  • Блок использует существующий источник useBrokerEvents(accountId, query).
  • По умолчанию применяется период сегодня - 7 дней / сегодня + 7 дней и типы dividend,coupon,maturity,offer, как в существующей вкладке событий.
  • Блок содержит кликабельные chip-фильтры типов событий: Дивиденды, Купоны, Погашения, Оферты.
  • Пользователь может выбрать несколько типов событий.
  • Если пользователь снимает все типы событий, запрос не выполняется, а блок показывает валидационное сообщение.
  • Изменение chip-фильтров типов событий применяется сразу и возвращает локальную пагинацию на первую страницу.
  • Блок содержит фильтр периода from / to.
  • Изменение черновых фильтров не запускает запрос до нажатия Показать.
  • Блок содержит быстрые пресеты периода , 30д, 90д, 1г, Всё и действие Сбросить.
  • Применённые фильтры dashboard не обязаны синхронизироваться с URL; URL-синхронизация остаётся обязанностью подробной вкладки События.
  • В dashboard отображается не более 10 событий на странице.
  • Если в выбранном диапазоне больше 10 событий, блок показывает локальную пагинацию по страницам.
  • Смена применённых фильтров возвращает пагинацию блока на первую страницу.
  • Таблица показывает дату, инструмент, тип, сумму и статус.
  • Сумма для actual берётся из actualAmount, сумма для forecast берётся из estimatedAmount.
  • Фактические поступления визуально отмечаются как Поступило.
  • Прогнозные суммы помечаются как оценочные.
  • Блок содержит ссылку на подробную вкладку /broker/:accountId/events.
  • Ошибка загрузки событий не ломает остальной dashboard.

5. Блок Доходы

  • Блок показывает последние доходные операции по дивидендам и купонам из существующего endpoint операций.
  • В первую версию входят операции с типами дивидендов и купонов, которые уже используются в backend analytics: OPERATION_TYPE_DIVIDEND, OPERATION_TYPE_DIV_EXT, OPERATION_TYPE_COUPON.
  • Блок содержит кликабельные chip-фильтры типов доходов: Дивиденды, Купоны.
  • Пользователь может выбрать один или оба типа доходов.
  • Если пользователь снимает все типы доходов, запрос не выполняется, а блок показывает валидационное сообщение.
  • Изменение chip-фильтров типов доходов применяется сразу и сбрасывает cursor-пагинацию.
  • Блок содержит фильтр периода from / to.
  • По умолчанию используется период с начала текущего календарного года до текущей даты, как в разделе операций.
  • Изменение черновых фильтров не запускает запрос до нажатия Показать.
  • Блок содержит быстрые пресеты периода , 30д, 90д, 1г, Всё и действие Сбросить.
  • Применённые фильтры dashboard не обязаны синхронизироваться с URL; URL-синхронизация остаётся обязанностью подробных разделов.
  • Для блока используется cursor-пагинация existing operations endpoint с размером страницы 10.
  • Смена применённых фильтров сбрасывает cursor-пагинацию блока на первую страницу.
  • Таблица показывает дату, инструмент, тип и сумму.
  • Блок показывает итог по отображаемым доходным операциям.
  • Блок содержит ссылку на подробную вкладку /broker/:accountId/operations.
  • Если текущий endpoint операций не позволяет корректно получить доходные операции без изменения backend-контракта, первая реализация должна явно зафиксировать это в plan.md перед изменением API.

6. Блок Аналитика доходности

  • Блок использует существующий endpoint /api/v1/broker/accounts/:accountId/analytics.
  • Отображаются: пополнения, выводы, нетто вложено, дивиденды, купоны, всего получено, доходность.
  • При отсутствии analytics data блок показывает спокойное пустое состояние.
  • Ошибка analytics не ломает остальные блоки.

7. Блок Аллокация

  • Используется существующий расчёт buildBrokerAllocation.
  • Вместо donut-диаграммы используется горизонтальный bar chart: каждый сектор — полоса с процентом, подписью и суммой.
  • Сверху блока показывается итоговая стоимость портфеля.
  • Каждая полоса содержит: название сектора, долю в процентах, сумму в валюте.
  • Цвета полос соответствуют существующей палитре аллокации (акции, облигации, ETF, деньги, прочие).
  • Отрицательные значения отображаются текстом без полосы.
  • Текст подписей контрастный и читаемый на всех цветах фона.
  • Информация остаётся понятной без различения цветов.

8. Загрузка, ошибки и пустые состояния

  • Первичная загрузка portfolio показывает dashboard skeleton соответствующей формы.
  • Ошибка portfolio показывает ошибку overview, потому что без portfolio dashboard не имеет основного контекста.
  • Ошибка событий, доходов или analytics отображается внутри соответствующей карточки.
  • Пустые события, пустые доходы и пустая analytics имеют отдельные понятные сообщения.
  • Недоступные отдельные значения отображаются как , не подменяются нулём.

Ограничения

  • Backend остаётся единственным клиентом T-Bank и MOEX.
  • В первой версии не добавляется график истории стоимости портфеля.
  • В первой версии не добавляется backend storage/API для снапшотов стоимости портфеля.
  • Тёмная тема и переключатель темы не входят в область фичи.
  • Не меняются правила расчёта доходности, событий, операций и аллокации.
  • Не удаляются существующие detailed вкладки счёта.
  • Не изменяется URL-структура /broker/:accountId/*.

Backlog

Идея Broker portfolio value history вынесена в docs/inbox.md и docs/roadmap.md: хранить снапшоты стоимости брокерского счёта и позже заменить отсутствие графика полноценным блоком Стоимость портфеля.

Acceptance Criteria

  • /broker/:accountId показывает dashboard-композицию: hero KPI, События, Доходы, Аналитика доходности, Аллокация.
  • Навигация счёта отображается горизонтальными вкладками над dashboard-контентом.
  • На desktop и mobile блоки События, Доходы, Аналитика доходности, Аллокация расположены по одному блоку на строке.
  • На мобильном viewport dashboard читаемо перестраивается в одну колонку.
  • Hero показывает стоимость портфеля, доходность или fallback, дневное изменение или fallback, всего доходов или fallback.
  • Все Metric-блоки hero имеют одинаковую высоту; supportingText не создаёт перекоса.
  • Блок События использует существующие events data и показывает дату, инструмент, тип, сумму и статус.
  • Блок События поддерживает multi-select chip-фильтр типов и локальную пагинацию по 10 событий.
  • Блок Доходы показывает доходные операции дивидендов и купонов и итог по отображаемым строкам.
  • Блок Доходы поддерживает multi-select chip-фильтр типов и cursor-пагинацию по 10 операций.
  • Блок Аналитика доходности показывает данные существующего analytics endpoint.
  • Блок Аллокация показывает горизонтальные бары секторов с названием, долей и суммой, а также итоговую стоимость портфеля.
  • Ошибка одного вторичного блока не скрывает остальные блоки dashboard.
  • Существующие detailed вкладки остаются доступны из навигации счёта.
  • Первая версия не содержит график истории стоимости портфеля и не добавляет API для него.
  • Дизайн использует светлую DS-тему, а не тёмную тему из temp.html.

Вне области фичи

  • график стоимости портфеля по датам;
  • новые исторические снапшоты стоимости;
  • dark mode;
  • изменение backend-расчётов доходности;
  • налоговая аналитика;
  • экспорт dashboard;
  • объединение нескольких брокерских счетов в один dashboard.