Sergey Krylov f7dc338719
Some checks failed
CI / ci (pull_request) Failing after 3m9s
CI / ci (push) Failing after 3m9s
feat: add actual payouts and filter-as-draft UX to broker events calendar
- Backend: actual events from T-Bank operations, types filter, split forecast/actual summary
- Frontend: draft/applied filters with multi-select types, status column (Факт/Прогноз), green actual amounts
- Docs: update spec, plan, tasks
2026-06-22 21:48:03 +03:00

240 lines
17 KiB
Markdown
Raw Permalink 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.

# Календарь событий и прогноз будущих выплат брокерского счёта
Дата: 2026-06-21
Статус: реализовано; доработка UX и смешанного календаря согласована к реализации
Эпик: [Портфель брокера](../../epics/BrokerPortfolio.md)
## Цель
Дать пользователю брокерского счёта T-Bank отдельный раздел, где можно увидеть будущие события по
бумагам счёта, фактически прошедшие выплаты и ориентировочный денежный поток по выбранному
диапазону дат.
## Пользовательский результат
Пользователь может:
- быстро увидеть ближайшие события по текущему счёту прямо на overview;
- открыть отдельную вкладку `События` внутри счёта;
- выбрать период, например с `2026-06-22` по `2026-07-29`;
- получить список дивидендов, купонов, погашений и оферт, попадающих в этот период;
- увидеть ориентировочную сумму будущих выплат по выбранному диапазону;
- увидеть фактически поступившие прошедшие выплаты из операций брокерского счёта;
- выбрать несколько типов событий, которые нужно показать;
- понимать, какие значения являются оценкой по текущим позициям, а не подтверждённым правом на
выплату.
## Область изменений
Фича относится только к брокерским счетам T-Bank и включает:
- новый блок ближайших событий на overview счёта;
- новую вкладку `События` в навигации брокерского счёта;
- фильтр диапазона дат;
- фильтр нескольких типов событий;
- список событий по текущим позициям счёта;
- список прошедших фактических выплат по операциям счёта;
- агрегированный summary по будущим выплатам за выбранный период.
## Требования
### 1. Область первой версии
- Первая версия работает только внутри маршрутов `/broker/:accountId/*`.
- Ручные портфели `PortfolioModule` не входят в область фичи.
- Backend остаётся единственным клиентом T-Bank и MOEX.
- Фича является read-only и не изменяет состав счёта или права пользователя.
### 2. Навигация и точки входа
- На overview брокерского счёта показывается компактный блок ближайших событий.
- Блок overview содержит переход во вкладку `События`.
- У счёта появляется отдельный раздел `События` рядом с существующими разделами `Обзор`, `Акции`,
`Облигации` и `Операции`.
- Переход между разделами не меняет выбранный счёт.
### 3. Типы событий первой версии
Первая версия поддерживает события:
- `dividend` — дивиденд по акции;
- `coupon` — купон по облигации;
- `maturity` — погашение облигации;
- `offer` — оферта по облигации.
По смыслу события делятся на:
- `cashflow` — событие с ожидаемым денежным эффектом;
- `corporate` — важное событие без обязательной денежной оценки в первой версии.
Правила классификации:
- `dividend` относится к `cashflow`;
- `coupon` относится к `cashflow`;
- `maturity` относится к `cashflow`;
- `offer` относится к `corporate`.
### 4. Диапазон дат
- Пользователь задаёт диапазон `from` / `to`.
- Диапазон фильтруется по дате события, а не по дате поступления денег.
- Границы диапазона включительные.
- Если `eventDate` не попадает в диапазон, событие не показывается.
- В первой версии отдельный режим фильтрации по `paymentDate` отсутствует.
- При первом открытии вкладки без параметров период по умолчанию равен `сегодня - 7 дней` / `сегодня
+ 7 дней`.
- Изменение дат в интерфейсе не запускает запрос автоматически: пользователь редактирует черновик
фильтров и применяет его кнопкой `Показать`.
### 4.1. Фильтр типов событий
- Пользователь может выбрать несколько типов событий через multi-select: `dividend`, `coupon`,
`maturity`, `offer`.
- При первом открытии включены все типы событий.
- После применения фильтра выбранные типы сохраняются в URL в параметре `types`.
- URL отражает только применённые фильтры, а не черновые значения в полях.
- Если пользователь снимает все типы, запрос не выполняется, а UI показывает валидационное сообщение.
### 5. Источники данных
- Для состава счёта используются текущие позиции T-Bank.
- Для акций используются дивидендные данные MOEX.
- Для облигаций используются уже доступные поля MOEX enrichment, включая `nextCouponDate`,
`couponValue`, `matDate`, `offerDate` и `faceValue`.
- Фича не требует отдельного постоянного хранилища событий в первой версии.
### 6. Правила прогноза выплат
- Все денежные суммы первой версии являются оценкой по текущим позициям счёта на момент запроса.
- Фича не восстанавливает историческое владение бумагой на дату отсечки.
- Если состав счёта изменится, прогноз по тем же датам может измениться.
- UI обязан явно показывать, что сумма является estimate или прогнозом.
#### Дивиденды
- Событие строится по `registryCloseDate`.
- Если размер выплаты доступен, ориентировочная сумма считается как количество бумаг в текущем
счёте, умноженное на выплату на единицу.
- Если размер выплаты отсутствует, событие всё равно может быть показано без итоговой суммы.
#### Купоны
- Событие строится по `nextCouponDate`.
- Если размер купона доступен, ориентировочная сумма считается как количество облигаций в текущем
счёте, умноженное на `couponValue`.
- Если размер купона отсутствует, событие показывается без итоговой суммы.
#### Погашение
- Событие строится по `matDate`.
- Если известен `faceValue`, ориентировочная сумма считается как количество облигаций в текущем
счёте, умноженное на номинал.
- Если номинал отсутствует, событие показывается без итоговой суммы.
#### Оферта
- Событие строится по `offerDate`.
- В первой версии оферта считается информационным событием.
- Для оферты не требуется обязательная денежная оценка.
### 6.1. Фактические прошедшие события
- Для прошедшей части выбранного диапазона календарь добавляет фактические события из операций
T-Bank.
- Фактические события строятся только по исполненным операциям счёта.
- В фактические события входят дивиденды, купоны и погашения облигаций.
- Фактические события имеют источник `actual`, не являются оценкой и используют фактическую сумму
операции.
- Фактические поступления визуально выделяются зелёным как уже поступившие деньги.
- Будущие события имеют источник `forecast`, строятся по текущим позициям и сохраняют признак оценки
`current_position`.
- Оферты остаются прогнозными событиями, если доступны по данным облигаций; фактическая оферта из
операций в этой доработке не строится.
- Если одно и то же событие доступно как факт и как прогноз за прошедшую дату, UI должен отдавать
приоритет факту, чтобы не показывать пользователю дубль одного поступления.
### 7. Overview счёта
- Overview показывает ближайшие 3-5 событий выбранного счёта.
- Для каждого события overview показывает дату, инструмент, тип события и сумму при наличии.
- Если ближайших событий нет, overview показывает спокойное пустое состояние.
- Ошибка загрузки блока событий не должна ломать остальной overview счёта.
### 8. Вкладка `События`
- Вкладка содержит фильтр периода, multi-select типов событий, summary и список событий.
- Фильтры используют компоненты и визуальные паттерны дизайн-системы.
- Изменение фильтров не запускает запрос до нажатия кнопки `Показать`.
- Кнопка `Показать` применяет фильтры, обновляет URL и запускает загрузку данных.
- Список событий показывает:
- дату события;
- тип события;
- источник события (`Факт` или `Прогноз`);
- инструмент;
- тип инструмента;
- количество бумаг, использованное для расчёта;
- выплату на единицу при наличии;
- итоговую ориентировочную сумму при наличии;
- фактическую сумму поступления при наличии;
- валюту при наличии.
- Для денежных оценок UI показывает признак `estimate`.
- Для фактических поступлений UI показывает признак `Поступило` и зелёное выделение суммы или статуса.
### 9. Summary по периоду
Summary по выбранному периоду показывает:
- количество событий;
- ближайшую дату события;
- общий ориентировочный денежный поток по прогнозам;
- общий фактический денежный поток по прошедшим поступлениям;
- сумму дивидендов;
- сумму купонов;
- сумму погашений.
Оферты не обязаны входить в денежные итоги.
### 10. Ошибки, пустые состояния и частичная деградация
- Ошибка по одному инструменту не должна ломать весь календарь счёта.
- Если по событию недоступна сумма, событие может быть показано без суммы.
- Если в выбранном диапазоне нет событий, пользователь видит пустое состояние, а не ошибку.
- Ошибка вкладки `События` не должна скрывать общую навигацию счёта.
## Ограничения
- Первая версия не покрывает ручные портфели.
- Первая версия не учитывает налоги, комиссии и валютную конвертацию.
- Первая версия не различает в UI `eventDate` и `paymentDate` как отдельные режимы фильтрации.
- Если источник облигаций даёт только ближайший купон, дальний график будущих купонов не
гарантируется.
- Фича не заменяет историческую аналитику операций и не является налоговым расчётом.
## Acceptance Criteria
- На overview брокерского счёта отображается блок ближайших событий.
- В навигации брокерского счёта есть вкладка `События`.
- Пользователь может задать диапазон дат.
- По умолчанию вкладка открывает период `сегодня - 7 дней` / `сегодня + 7 дней`.
- Изменение дат или типов событий не запускает запрос до нажатия `Показать`.
- Пользователь может выбрать несколько типов событий через multi-select.
- Выбранные применённые фильтры восстанавливаются из URL.
- Вкладка показывает только события, дата которых попадает в выбранный диапазон.
- Пользователь видит дивиденды, купоны, погашения и оферты, если они доступны по текущим позициям.
- Пользователь видит фактические прошедшие дивиденды, купоны и погашения из операций счёта.
- Фактические прошедшие поступления помечены как `Поступило` и визуально выделены зелёным.
- Summary показывает агрегированный прогноз будущих выплат по диапазону.
- Summary отдельно показывает фактические поступления и прогноз выплат.
- Все денежные суммы явно обозначены как оценочные.
- Пустой диапазон отображается как отдельное пустое состояние.
- Ошибка по одному инструменту не ломает весь ответ.
## Вне области фичи
- точный entitlement-расчёт по историческому владению и датам отсечки;
- поддержка ручных портфелей;
- единый календарь по нескольким доменам портфелей;
- налоги, мультивалютный net cashflow и комиссии;
- iCal/export, уведомления и напоминания;
- отдельный аналитический раздел вне брокерского счёта.