204 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Редизайн 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.