204 lines
17 KiB
Markdown
204 lines
17 KiB
Markdown
# Редизайн overview брокерского счёта в инвестиционный дашборд
|
||
|
||
Дата: 2026-06-26
|
||
Статус: согласовано к планированию
|
||
Эпик: [Портфель брокера](../../epics/BrokerPortfolio.md)
|
||
|
||
## Контекст
|
||
|
||
Текущий маршрут `/broker/:accountId` показывает корректный overview выбранного брокерского счёта, но
|
||
визуально остаётся вертикальным набором отдельных блоков: сводка, аллокация, карточки активов,
|
||
ближайшие события и последние операции. Пользователь подготовил прототип `temp.html`, где тот же домен
|
||
представлен как более плотный инвестиционный дашборд: hero KPI, события и доходы рядом, аналитика и
|
||
аллокация в нижнем ряду.
|
||
|
||
После обсуждения выбран вариант A: страница `/broker/:accountId` должна стать единым дашбордом,
|
||
используя структуру и плотность прототипа, но сохраняя текущую светлую тему и компоненты
|
||
`@moex-vibe/design-system`. Тёмная тема из прототипа не переносится в первую версию.
|
||
|
||
## Цель
|
||
|
||
Сделать overview брокерского счёта быстрым обзором состояния портфеля, будущих/прошедших событий,
|
||
полученных доходов, аналитики доходности и аллокации без перехода по вкладкам.
|
||
|
||
## Пользовательский результат
|
||
|
||
Пользователь может на `/broker/:accountId`:
|
||
|
||
- сразу увидеть стоимость портфеля, доходность и сумму полученных доходов;
|
||
- увидеть ближайшие события по счёту в компактной таблице;
|
||
- увидеть последние доходные операции по дивидендам и купонам и итог по ним;
|
||
- оценить вложения, полученные выплаты и доходность по существующей аналитике;
|
||
- увидеть структуру портфеля через donut-диаграмму и легенду;
|
||
- перейти в существующие подробные вкладки `Акции`, `Облигации`, `Операции`, `События` и `Аналитика`
|
||
для 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-страницей, а не вертикальным списком независимых секций.
|
||
- На desktop первый экран содержит hero KPI и два основных информационных блока рядом: `События` и
|
||
`Доходы`.
|
||
- Ниже отображаются `Аналитика доходности` и `Аллокация`.
|
||
- Существующая навигация счёта сохраняет ссылки на `Обзор`, `Акции`, `Облигации`, `Операции`,
|
||
`События`, `Аналитика`.
|
||
- На мобильном viewport дашборд перестраивается в одну колонку с порядком: hero KPI, события, доходы,
|
||
аналитика, аллокация.
|
||
|
||
### 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 `—` для недоступных значений.
|
||
|
||
### 4. Блок `События`
|
||
|
||
- Блок использует существующий источник `useBrokerEvents(accountId, query)`.
|
||
- По умолчанию применяется период `сегодня - 7 дней` / `сегодня + 7 дней` и типы
|
||
`dividend,coupon,maturity,offer`, как в существующей вкладке событий.
|
||
- Блок содержит фильтр типов событий: `Дивиденды`, `Купоны`, `Погашения`, `Оферты`.
|
||
- Пользователь может выбрать несколько типов событий.
|
||
- Если пользователь снимает все типы событий, запрос не выполняется, а блок показывает
|
||
валидационное сообщение.
|
||
- Блок содержит фильтр периода `from` / `to`.
|
||
- Изменение черновых фильтров не запускает запрос до нажатия `Показать`.
|
||
- Блок содержит быстрые пресеты периода `7д`, `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`.
|
||
- Блок содержит фильтр типов доходов: `Дивиденды`, `Купоны`.
|
||
- Пользователь может выбрать один или оба типа доходов.
|
||
- Если пользователь снимает все типы доходов, запрос не выполняется, а блок показывает
|
||
валидационное сообщение.
|
||
- Блок содержит фильтр периода `from` / `to`.
|
||
- По умолчанию используется период с начала текущего календарного года до текущей даты, как в разделе
|
||
операций.
|
||
- Изменение черновых фильтров не запускает запрос до нажатия `Показать`.
|
||
- Блок содержит быстрые пресеты периода `7д`, `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` и текущая `BrokerAllocationChart` либо её
|
||
dashboard-адаптация.
|
||
- Блок показывает итоговую стоимость портфеля и ненулевые секторы с названием, суммой и процентом.
|
||
- Отрицательные значения отображаются текстом, а не сектором диаграммы.
|
||
- Информация остаётся понятной без различения цветов.
|
||
|
||
### 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, `События`, `Доходы`,
|
||
`Аналитика доходности`, `Аллокация`.
|
||
- На desktop блоки `События` и `Доходы` расположены рядом.
|
||
- На мобильном viewport dashboard читаемо перестраивается в одну колонку.
|
||
- Hero показывает стоимость портфеля, доходность или fallback, дневное изменение или fallback, всего
|
||
доходов или fallback.
|
||
- Блок `События` использует существующие events data и показывает дату, инструмент, тип, сумму и статус.
|
||
- Блок `События` поддерживает multi-select фильтр типов, фильтр периода, быстрые пресеты, сброс и
|
||
локальную пагинацию по 10 событий.
|
||
- Блок `Доходы` показывает доходные операции дивидендов и купонов и итог по отображаемым строкам.
|
||
- Блок `Доходы` поддерживает multi-select фильтр типов, фильтр периода, быстрые пресеты, сброс и
|
||
cursor-пагинацию по 10 операций.
|
||
- Блок `Аналитика доходности` показывает данные существующего analytics endpoint.
|
||
- Блок `Аллокация` показывает donut/легенду существующей структуры портфеля.
|
||
- Ошибка одного вторичного блока не скрывает остальные блоки dashboard.
|
||
- Существующие detailed вкладки остаются доступны из навигации счёта.
|
||
- Первая версия не содержит график истории стоимости портфеля и не добавляет API для него.
|
||
- Дизайн использует светлую DS-тему, а не тёмную тему из `temp.html`.
|
||
|
||
## Вне области фичи
|
||
|
||
- график стоимости портфеля по датам;
|
||
- новые исторические снапшоты стоимости;
|
||
- dark mode;
|
||
- изменение backend-расчётов доходности;
|
||
- налоговая аналитика;
|
||
- экспорт dashboard;
|
||
- объединение нескольких брокерских счетов в один dashboard.
|