Files
specs/openspec/specs/brokerage-account-upcoming-events/spec.md
T
ksv741 329d66e767
Specs security / security (push) Successful in 8s
Specs verify / verify (push) Successful in 11s
spec: finalize wealth-ledger SDD migration
2026-10-09 21:14:22 +03:00

21 KiB
Raw Blame History

Brokerage Account Upcoming Events Specification

Purpose

Позволяет пользователю просматривать известные будущие денежные и связанные корпоративные события одного брокерского счёта на ближайший месяц.

Requirements

Requirement: User can retrieve upcoming events for an account

Система MUST предоставлять аутентифицированному User read-only GET /api/v1/brokerage-account-upcoming-events для выбранного открытого поддерживаемого Brokerage Account либо существующего режима «Все счета» (all) в границах текущего T-Bank connection User. Параметры from и to MUST сохранять существующий контракт: необязательные строгие календарные даты YYYY-MM-DD с включительными границами в UTC. Без from начало MUST соответствовать текущей календарной дате UTC; без to конец MUST соответствовать дате from плюс 30 календарных дней. При from позже to система MUST возвращать существующую ошибку INVALID_EVENTS_PERIOD, не подменять период, не запускать загрузку другого периода и не возвращать его прогноз. Обычный GET MUST NOT запускать личную синхронизацию.

Ответ MUST иметь { data, meta }, где meta соответствует наблюдаемому состоянию resource по tbank-data-sync. Доступный data MUST содержать только события coupon, dividend, maturity и offer, отсортированные по дате по возрастанию, calculatedAt, а в режиме all -- принадлежность каждого события счёту. Прогноз MUST быть рассчитан по количеству бумаг полного Portfolio Snapshot на calculatedAt; сохранённый прогноз MUST сохранять свой исходный calculatedAt и рассчитанное от него включительное окно, даже когда запрошенное from/to отличается. При чтении сохранённого прогноза система MUST возвращать только события, чьи даты попадают во включительное пересечение исходного окна прогноза и запрошенного UTC-окна; пустое пересечение либо отсутствие событий в пересечении MUST возвращать успешный пустой список с теми же calculatedAt, meta и исходным окном. В режиме all доступ и полнота обязательных источников MUST проверяться для каждого входящего счёта; отсутствие вклада счёта MUST NOT подменяться полным результатом. Список будущих событий является прогнозом по наблюдаемому состоянию счёта и количеству бумаг на calculatedAt и MUST NOT означать долговременное право владения Brokerage Account независимо от T-Bank connection.

Scenario: Получение событий доступного счёта

  • WHEN аутентифицированный User запрашивает события доступного счёта с последним полным прогнозом
  • THEN система возвращает из сохранённого прогноза события в запрошенном включительном UTC-окне, его исходные calculatedAt и рассчитанное окно без обращения к T-Bank

Scenario: Запрошенное окно не пересекается с сохранённым прогнозом

  • WHEN запрошенный включительный UTC-окно не пересекается с исходным окном последнего полного прогноза
  • THEN система возвращает успешный пустой data с исходными calculatedAt, окном и meta

Scenario: Отсутствие событий в периоде

  • WHEN пересечение запрошенного и исходного окна прогноза не содержит событий
  • THEN система возвращает успешный пустой список, момент расчёта, исходное окно и meta

Scenario: Некорректный период

  • WHEN User передаёт from позже to
  • THEN система возвращает существующую ошибку INVALID_EVENTS_PERIOD без прогноза и без запуска личной синхронизации

Scenario: Прогноз всех счетов

  • WHEN User запрашивает режим all и для каждого входящего счёта доступен полный прогноз
  • THEN система возвращает события всех счетов в запрошенном окне с принадлежностью каждого события счёту

Scenario: Отклонение недоступного счёта

  • WHEN User запрашивает события счёта, недоступного через его текущий T-Bank connection
  • THEN система возвращает существующий ответ о недоступности счёта и не раскрывает события

Requirement: Forecasts preserve event meaning and uncertainty

Система MUST передавать для каждого события его календарную дату, тип, доступные идентификаторы и название Instrument, а также прогнозную сумму до налогов как Money, если она известна. Прогнозная сумма MUST рассчитываться по количеству бумаг полного Portfolio Snapshot на calculatedAt, использованного для сохранённого прогноза, а не по количеству бумаг на момент HTTP-запроса. Сохранённый прогноз MUST сохранять свой calculatedAt и эту исходную зависимость, в том числе после неуспешного обновления, и MUST NOT приписываться более новому Portfolio Snapshot. Если денежные условия события неизвестны или неприменимы, прогнозная сумма MUST быть null, а не нулём и не парой разрозненных полей. Дивиденд MUST обозначать переданную дату как дату реестра, а offer MUST передаваться без вымышленной суммы.

Instrument в Future Cash Event MUST иметь тот же доменный смысл, что и в Portfolio: это финансовый инструмент, к которому относится событие, даже если событие не является Portfolio Position.

Scenario: Прогноз купона по текущей позиции

  • WHEN поддерживаемая облигация в Portfolio Snapshot на calculatedAt имеет известный купон в пределах исходного окна прогноза
  • THEN система возвращает сохранённое событие coupon с прогнозной суммой до налогов как Money в исходной валюте, рассчитанной по количеству облигаций этого Snapshot

Scenario: Прогноз дивиденда

  • WHEN поддерживаемая акция в Portfolio Snapshot на calculatedAt имеет объявленный дивиденд с датой фиксации реестра в пределах исходного окна прогноза
  • THEN система возвращает сохранённое событие dividend с датой, обозначенной как дата реестра (record_date), и прогнозной суммой до налогов как Money, равной dividend_net на одну бумагу, умноженной на количество акций этого Snapshot

Scenario: Отменённый дивиденд не попадает в прогноз

  • WHEN запись дивиденда T-Bank имеет тип выплаты Cancelled
  • THEN система не добавляет такое событие в сохранённый прогноз

Scenario: Отображение оферты без суммы

  • WHEN для поддерживаемой облигации известна оферта в пределах исходного окна прогноза, но её денежные условия недоступны
  • THEN система возвращает событие offer с прогнозной суммой null

Scenario: Неподдерживаемое частичное погашение

  • WHEN источник не предоставляет расписание будущих частичных погашений или амортизации облигации
  • THEN система НЕ создаёт синтетическое событие частичного погашения

Requirement: Upcoming events use complete source results

Система MUST публиковать прогноз только после полного получения необходимых данных брокера и MOEX для полного Portfolio Snapshot, по количеству бумаг которого он рассчитан. Неуспешное обновление MUST NOT заменять последний полный прогноз, его calculatedAt или окно событий частичным списком. При неуспешном обновлении и существующем последнем полном прогнозе система MUST возвращать отфильтрованную для запрошенного окна часть этого прогноза с его исходными calculatedAt, окном и meta, отдельно обозначающим неуспех последней попытки, даже если результат фильтрации пуст. При отсутствии последнего полного прогноза система MUST возвращать data: null и в meta обозначать выполнение первой загрузки либо её неуспех без частичного списка. Система MUST пропускать инструменты, для которых источник не предоставляет поддерживаемые события, не создавая строки «нет данных».

Scenario: Недоступность источника

  • WHEN необходимый источник данных брокера или MOEX временно недоступен во время часового обновления
  • THEN система не публикует частичный список как полный прогноз

Scenario: Ошибка обновления при сохранённом прогнозе

  • WHEN часовой обход не завершает обновление необходимых источников, а последний полный прогноз существует
  • THEN система возвращает его события только в запрошенном окне, исходные calculatedAt и окно, а meta отдельно обозначает ошибку обновления

Scenario: Ошибка обновления при сохранённом прогнозе вне запрошенного окна

  • WHEN часовой обход не завершает обновление, последний полный прогноз существует, но его окно не пересекается с запрошенным
  • THEN система возвращает успешный пустой data с исходными calculatedAt, окном и meta, обозначающим ошибку обновления

Scenario: Инструмент без поддерживаемых данных

  • WHEN Portfolio содержит инструмент, для которого источник не предоставляет поддерживаемые будущие события
  • THEN система не добавляет для него синтетическую строку в результат

Scenario: MOEX отвечает без запрошенного блока

  • WHEN MOEX отвечает успешно, но не содержит запрошенного блока данных
  • THEN система трактует ответ как отсутствие данных по инструменту и не завершает обновление ошибкой

Requirement: Account page presents an upcoming events list

Страница Brokerage Account MUST предоставлять read-only действие перехода на отдельную страницу «Будущие события». Эта страница MUST показывать события сохранённого полного прогноза компактным списком без фильтров, пагинации, суммарного итога или действия ручной синхронизации, с датой, типом, инструментом и прогнозной суммой в исходной валюте, если она известна. Страница MUST показывать calculatedAt, исходное окно прогноза и наблюдаемые freshness, полноту, время последнего успешного прогноза, последнюю часовую попытку и доступность из meta понятным текстом или иконкой с доступным именем, а не только цветом. Она MUST объяснять, что прогноз рассчитан по количеству бумаг на calculatedAt, а показанные события дополнительно ограничены запрошенным включительным UTC-окном; прогноз указан до налогов и может быть неполным из-за доступности данных источника. Открытие страницы и повтор HTTP-чтения MUST NOT запускать личную синхронизацию.

Scenario: Просмотр ближайших событий

  • WHEN User открывает «Будущие события» из обзора Brokerage Account
  • THEN он видит отсортированный read-only список событий сохранённого 30-календарного окна и calculatedAt, где offer обозначен без суммы

Scenario: Пустое состояние страницы

  • WHEN запрос будущих событий успешно возвращает пустой список
  • THEN страница сообщает, что в сохранённом окне прогноза событий не найдено, показывает calculatedAt и объясняет ограничения покрытия источника

Scenario: Первая загрузка либо ошибка без сохранённого прогноза

  • WHEN запрос будущих событий возвращает data: null, а meta обозначает выполнение первой загрузки либо её неуспех
  • THEN страница показывает доступное состояние загрузки либо ошибки без частичного списка и предоставляет при ошибке действие повторить только HTTP-чтение

Scenario: Ошибка страницы

  • WHEN запрос будущих событий завершается ошибкой
  • THEN страница не показывает частичный список и предоставляет действие повторить только HTTP-чтение

Scenario: Ошибка обновления при сохранённом прогнозе на странице

  • WHEN запрос будущих событий возвращает последний полный прогноз вместе с ошибкой его обновления
  • THEN страница показывает этот прогноз с его исходными calculatedAt и окном, отдельно сообщает об ошибке обновления и предоставляет действие повторить только HTTP-чтение

Requirement: Account overview includes upcoming events

Обзор Brokerage Account MUST показывать не более пяти ближайших Future Cash Event сохранённого полного прогноза в применённом запрошенном окне, его calculatedAt, исходное окно, наблюдаемую freshness, полноту, последнюю часовую попытку и доступность из meta, а также действие перехода на read-only полную страницу «Будущие события». Статус MUST быть понятен текстом или иконкой с доступным именем, а не только цветом. Неуспешное обновление при сохранённом прогнозе MUST оставаться локальным состоянием блока, сохранять показанные события и их исходное окно и MUST NOT заменять успешно отображённый Portfolio. Если полного прогноза нет, неуспешное обновление MUST оставаться локальным состоянием блока без частичного списка. Обзор MUST NOT предоставлять действие ручной синхронизации; его повтор MUST выполнять только HTTP-чтение.

Scenario: Отображение ближайших событий

  • WHEN обзор счёта успешно загружен и сохранённый прогноз содержит будущие события
  • THEN обзор показывает первые пять событий в порядке даты, calculatedAt и действие перехода к полной странице

Scenario: Ближайшие события недоступны без сохранённого прогноза

  • WHEN обзор счёта успешно загружен, а события возвращают data: null и meta обозначает выполнение первой загрузки либо её неуспех
  • THEN Portfolio остаётся доступным, а блок будущих событий отображает собственное доступное состояние загрузки либо ошибки без частичного списка

Scenario: Ближайшие события недоступны

  • WHEN обзор счёта успешно загружен, но запрос будущих событий завершается ошибкой
  • THEN Portfolio остаётся доступным, а блок будущих событий отображает собственную ошибку

Scenario: Неуспешное обновление не скрывает сохранённый прогноз

  • WHEN обзор счёта получает сохранённый полный прогноз вместе с ошибкой его обновления
  • THEN Portfolio и события сохранённого окна остаются доступными, а блок отдельно обозначает ошибку и предлагает повторить только HTTP-чтение