57 lines
6.8 KiB
Markdown
57 lines
6.8 KiB
Markdown
# Пассивный доход брокерского счёта
|
||
|
||
Авторизованный User открывает `/accounts/:accountId/income` из обзора выбранного Brokerage Account. Экран показывает исполненные купоны и дивиденды за применённый календарный период, а известный прогноз ближайших событий оставляет отдельным блоком.
|
||
|
||
## API
|
||
|
||
`GET /api/v1/brokerage-accounts/:accountId/income-summary` возвращает текущий месяц по сегодняшнюю дату для компактного блока обзора. Он не зависит от периода, который User ранее выбрал на странице аналитики.
|
||
|
||
`GET /api/v1/brokerage-accounts/:accountId/income-analytics?from=YYYY-MM-DD&to=YYYY-MM-DD` возвращает полный результат. Даты задают включительный период в `Europe/Moscow`; без них применяется текущий месяц. Период не может быть будущим, обратным или длиннее 366 дней.
|
||
|
||
Оба endpoint требуют Bearer token и используют обычные ответы о неподключённом T-Bank, неверном token, недоступном счёте и временной недоступности upstream.
|
||
|
||
## Реализованный поток
|
||
|
||
- Backend проверяет доступ к счёту, проходит все cursor pages исполненных операций и не возвращает частичный результат при ошибке страницы или повреждённой cursor chain.
|
||
- Только точные upstream types coupon и dividend формируют результат. Суммы остаются exact decimal strings в исходной валюте; отрицательные корректировки сохраняют знак. Налоги, комиссии, сделки, переводы, погашения и dividend transfer не входят в доход.
|
||
- Итоги, сравнения, buckets и Instrument breakdown не смешивают валюты и не создают общий FX total. Сравнения показывают предыдущий период и, когда календарная дата и история счёта позволяют, период годом ранее.
|
||
- Trend buckets приходят с backend: дни для 1–45 дней, недели для 46–180 и месяцы для более длинного периода. Пустые buckets остаются в response и текстовом представлении.
|
||
- Breakdown раскрывает включённые Ledger Entries из того же ответа, поэтому отображённые строки не требуют отдельного запроса и воспроизводят сумму Instrument и валюты.
|
||
|
||
## Связь breakdown с выплатами
|
||
|
||
Каждая запись `income-analytics.entries` содержит обязательный `instrumentKey`,
|
||
равный `key` соответствующей строки `instruments`. Backend вычисляет этот ключ
|
||
один раз при подготовке income entries и использует его же для группировки.
|
||
Приоритет UID, FIGI, ticker/type и operation ID с разделением по валюте остаётся
|
||
серверным правилом; клиент воспринимает ключ как непрозрачную строку.
|
||
Общий Ledger endpoint не приобретает income-specific поле.
|
||
|
||
Income VM группирует entries по полученному ключу. Отсутствующий, пустой или
|
||
нестроковый ключ, неоднозначные instrument keys, неизвестная группа, другая
|
||
валюта или несовпадение receipt count приводят к существующему локальному
|
||
error/retry состоянию аналитики. Частичный drill-down не показывается как
|
||
полный; формула идентификации в клиенте не восстанавливается. Полностью пустой
|
||
ответ допустим. Состав и порядок выплат, signed Money и сортировка breakdown
|
||
сохраняются, frontend не пересчитывает денежные итоги.
|
||
|
||
## Совместимость и локальное обновление
|
||
|
||
Сначала обновляется backend: дополнительное поле совместимо с прежним
|
||
frontend. Затем синхронизируются OpenAPI snapshot/generated types и обновляется
|
||
frontend consumer. При переключении клиент перезагружается, чтобы не переносить
|
||
старые in-memory results и незавершённые запросы. Новый frontend требует новый
|
||
backend; отсутствие membership не скрывается fallback на прежнюю формулу.
|
||
|
||
При регрессии сначала возвращается прежний frontend вместе с соответствующим
|
||
snapshot/types и перезагружается клиент; затем при необходимости возвращается
|
||
backend. Старый frontend может временно работать с новым additive response.
|
||
SQLite schema, credentials и broker-reported операции не меняются: rollback
|
||
не удаляет данные, производные результаты запрашиваются заново.
|
||
|
||
## Прогноз и ограничения
|
||
|
||
Блок прогноза переиспользует `/events`: его `incomeTotalsByCurrency` содержит только coupon/dividend с известной projected amount, а на UI отображаются не более трёх ближайших таких событий. Maturity, offer и неизвестные суммы не искажают totals. Прогноз не гарантирован, не входит в фактические итоги и не зависит от выбранного исторического периода; его loading/error/empty outcome локален для блока.
|
||
|
||
Аналитика read-only, не хранит историю операций и не рассчитывает налоги, инвестиционную эффективность, доходность, валютную конвертацию или общий мультивалютный итог.
|