146 lines
21 KiB
Markdown
146 lines
21 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: Realized income analytics is account-scoped and period-bound
|
||
|
||
Система MUST предоставлять аутентифицированному User аналитику фактически полученного дохода выбранного открытого поддерживаемого Brokerage Account либо существующего режима «Все счета» (`all`) из счетов, доступных через текущий T-Bank connection User. В режиме `all` система MUST проверять доступ каждого входящего счёта и подтверждать полноту каждого исходного периода по всем входящим счетам; отсутствующий вклад счёта MUST NOT заменяться нулём. Применённый период MUST задаваться включительными календарными датами `from` и `to` в Europe/Moscow, MUST NOT начинаться после своего окончания, MUST NOT содержать будущую дату. Система MUST NOT ограничивать максимальную длительность периода. При отсутствии применённого периода система MUST использовать интервал от первого дня текущего месяца до сегодняшнего дня включительно.
|
||
|
||
Чтение MUST использовать сохранённые операции текущего подключения и локальное подтверждение доступа без синхронного запроса T-Bank. Ответ MUST иметь envelope `{ data, meta }` по `tbank-data-sync`. Полнота MUST определяться для выбранного периода и каждого необходимого периода сравнения отдельно. Запрос MUST приоритетно загружать их пропуски до фоновой догрузки остальной истории; известные правила календарных дат MUST сохраняться.
|
||
|
||
#### Scenario: Аналитика за период по умолчанию
|
||
|
||
- **WHEN** аутентифицированный User запрашивает аналитику доступного Brokerage Account без периода
|
||
- **THEN** система рассчитывает результат от первого дня текущего месяца по Europe/Moscow до сегодняшнего дня включительно
|
||
|
||
#### Scenario: Аналитика за допустимый пользовательский период
|
||
|
||
- **WHEN** User применяет включительный период любой длительности, в том числе более 366 дней, без будущих дат
|
||
- **THEN** система рассчитывает аналитику доступного Brokerage Account за все календарные даты этого периода по Europe/Moscow
|
||
|
||
#### Scenario: Отклонение недопустимого периода
|
||
|
||
- **WHEN** User запрашивает период с некорректной или будущей датой либо с `from` после `to`
|
||
- **THEN** система отклоняет запрос и не возвращает результат для другого или усечённого периода
|
||
|
||
#### Scenario: Отклонение недоступного счёта
|
||
|
||
- **WHEN** User запрашивает аналитику Brokerage Account, который не является открытым поддерживаемым счётом, доступным через его текущий T-Bank connection
|
||
- **THEN** система возвращает существующий ответ о недоступности счёта и не раскрывает его доход или операции
|
||
|
||
#### Scenario: Общий доход требует полноты всех счетов
|
||
- **WHEN** User запрашивает режим `all` и выбранный период одного доступного счёта ещё не загружен полностью
|
||
- **THEN** система не возвращает окончательные общие суммы, сохраняет раздельное состояние покрытия счетов и запрашивает недостающую разрешённую историю
|
||
|
||
#### Scenario: Открыт ещё не загруженный период
|
||
- **WHEN** запрошенный допустимый период ещё не имеет сохранённых операций или подтверждённого полного пустого покрытия
|
||
- **THEN** система отвечает `200` со статусом первичной загрузки или частичного покрытия, запрашивает нужные интервалы и не выдаёт нулевой окончательный доход
|
||
|
||
### Requirement: Period comparisons preserve calendar and currency meaning
|
||
|
||
Система MUST сопоставлять выбранный период с непосредственно предшествующим периодом. Для полного календарного месяца предыдущим периодом MUST быть предыдущий полный календарный месяц; для любого другого периода предыдущий период MUST иметь ту же включительную продолжительность и непосредственно предшествовать выбранному. Когда соответствующие календарные даты годом ранее доступны, система MUST также показывать year-over-year comparison; когда они недоступны, система MUST обозначать сравнение как недоступное, а не подменять его нулём. Только сравнение с подтверждённым полным покрытием обоих периодов MUST показывать абсолютные coupon, dividend и total значения и их денежные разницы отдельно по исходным валютам и MUST NOT характеризовать их как инвестиционную эффективность.
|
||
|
||
Отсутствие ещё не загруженной истории сравнения MUST отличаться от невозможности сравнения по календарю или доступной истории счёта. Система MUST сообщать загрузку, неполноту либо ошибку каждого периода сравнения и MUST NOT подменять их нулевыми суммами или денежными разницами. Полный основной период MAY отображаться при отдельно обозначенной незавершённой загрузке сравнения; его значения MUST NOT смешиваться с частичным сравнением.
|
||
|
||
#### Scenario: Сравнение полного календарного месяца
|
||
|
||
- **WHEN** User применяет период от первого до последнего дня календарного месяца
|
||
- **THEN** система сравнивает его с полным непосредственно предшествующим календарным месяцем
|
||
|
||
#### Scenario: Сравнение произвольного периода
|
||
|
||
- **WHEN** User применяет период, не являющийся полным календарным месяцем
|
||
- **THEN** система сравнивает его с непосредственно предшествующим включительным периодом той же продолжительности
|
||
|
||
#### Scenario: Доступно сравнение год к году
|
||
|
||
- **WHEN** для соответствующих календарных дат годом ранее доступна полная история подходящих операций
|
||
- **THEN** система показывает отдельные source-currency значения и денежные разницы относительно этого периода
|
||
|
||
#### Scenario: Годовая история недоступна
|
||
|
||
- **WHEN** полная история для соответствующих календарных дат годом ранее недоступна
|
||
- **THEN** система обозначает year-over-year comparison как недоступное и не показывает отсутствующие данные как нулевой доход
|
||
|
||
#### Scenario: Основной период полон, сравнение ещё загружается
|
||
- **WHEN** выбранный период имеет подтверждённое полное покрытие, а необходимый предыдущий период ещё загружается
|
||
- **THEN** система возвращает полный итог выбранного периода, отмечает загрузку сравнения и не возвращает для него окончательные суммы или разницы
|
||
|
||
#### Scenario: Сравнение догружено после основного периода
|
||
- **WHEN** все необходимые интервалы периода сравнения успешно завершены
|
||
- **THEN** следующее локальное чтение возвращает его точные валютные суммы и разницы без ожидания T-Bank
|
||
|
||
### Requirement: Realized analytics never presents an incomplete result as complete
|
||
|
||
Система MUST формировать окончательные totals, trend buckets, instrument breakdown и drill-down выбранного периода только по подтверждённому полному покрытию его исполненных операций. Каждое comparison MUST отдельно требовать полного покрытия своих исходных периодов. Повторное локальное чтение полного периода MUST NOT ожидать повторного получения cursor pages T-Bank. Ошибка любой необходимой страницы фоновой загрузки MUST сохранять подтверждённый ранее результат и покрытие, фиксировать восстанавливаемую ошибку синхронизации и MUST NOT возвращать частичные totals, comparisons, buckets или breakdown как полный результат. Если полный выбранный результат ещё не получен, envelope MUST возвращать `data: null` с отсутствующим либо частичным покрытием в `meta`, а интерфейс MUST показывать незавершённую загрузку либо её ошибку без окончательных финансовых итогов. Успешный период без подходящих выплат MUST возвращать нулевой результат и отображаться с явным объяснением пустого состояния.
|
||
|
||
#### Scenario: Все страницы операций успешно получены
|
||
|
||
- **WHEN** для покрытия расчёта требуется несколько cursor pages и каждая страница успешно сохранена с подтверждением окончания диапазона
|
||
- **THEN** система формирует результат по всем подходящим Ledger Entries со всех страниц
|
||
|
||
#### Scenario: Одна из страниц операций недоступна
|
||
|
||
- **WHEN** получение любой необходимой cursor page завершается ошибкой
|
||
- **THEN** ответ сообщает ошибку синхронизации, а страница сохраняет ранее полный результат с прежним временем либо показывает ошибку незавершённой загрузки без окончательных частичных итогов
|
||
|
||
#### Scenario: В периоде нет купонов и дивидендов
|
||
|
||
- **WHEN** все необходимые операции успешно получены, но среди них нет подходящих coupon или dividend Ledger Entries
|
||
- **THEN** страница показывает нулевой результат и объясняет, что за выбранный период купоны и дивиденды не найдены
|
||
|
||
#### Scenario: Частичная загрузка пока не нашла дохода
|
||
- **WHEN** только часть операций выбранного периода получена и в этой части нет купонов или дивидендов
|
||
- **THEN** система не возвращает окончательный нулевой результат и сообщает неполноту периода
|
||
|
||
#### Scenario: Ошибка ручной сверки полного периода
|
||
- **WHEN** ранее полный период перечитывается вручную и промежуточная страница не получена
|
||
- **THEN** прежний полный результат и время его успешной сверки остаются доступными с ошибкой обновления, а частичная новая выборка не заменяет их
|
||
|
||
### Requirement: Account overview has an independent current-month income summary
|
||
|
||
Обзор выбранного Brokerage Account MUST показывать компактный source-currency summary «Получено купонами и дивидендами» за период от первого дня текущего месяца по Europe/Moscow до сегодняшнего дня включительно и действие перехода на страницу «Пассивный доход». Summary MUST всегда использовать этот current-month период и MUST NOT наследовать последний пользовательский период страницы аналитики. Пустой или неуспешный расчёт summary MUST оставаться локальным состоянием блока и MUST NOT заменять успешно отображённый Portfolio или другие блоки обзора.
|
||
|
||
Summary MUST использовать тот же локальный источник операций и правило полноты, что и полная аналитика. До завершения требуемого текущего периода он MUST показывать состояние загрузки или неполноты без окончательного нулевого дохода. Ошибка фонового обновления MUST сохранять ранее полный summary с прежним временем и безопасным предупреждением.
|
||
|
||
#### Scenario: Обзор показывает доход текущего месяца
|
||
|
||
- **WHEN** обзор Brokerage Account загружен и current-month analytics успешно рассчитана
|
||
- **THEN** он показывает отдельные source-currency итоги с начала текущего месяца по сегодняшний день и переход к полной аналитике
|
||
|
||
#### Scenario: Пользовательский период не влияет на обзор
|
||
|
||
- **WHEN** User ранее применил на странице аналитики период, отличный от текущего месяца
|
||
- **THEN** summary обзора по-прежнему рассчитывается от первого дня текущего месяца по сегодняшний день
|
||
|
||
#### Scenario: Current-month summary недоступен
|
||
|
||
- **WHEN** Portfolio обзора успешно загружен, но расчёт current-month summary завершается ошибкой
|
||
- **THEN** Portfolio и остальные успешно загруженные блоки остаются доступными, а summary показывает собственное состояние восстановления
|
||
|
||
#### Scenario: Текущий месяц ещё не загружен полностью
|
||
- **WHEN** обзор доступен, но текущий месяц операций имеет пропуски
|
||
- **THEN** блок дохода обозначает неполноту или загрузку, не выдаёт частичный доход за окончательный и не скрывает Portfolio
|
||
|
||
### Requirement: Income payments remain traceable to exact Ledger Entries
|
||
|
||
В разделе «Выплаты» страница MUST показывать единый список карточек точных исполненных Ledger Entries применённого периода в исходном серверном порядке entries. Каждая выплата MUST иметь собственную сразу видимую карточку с описанием, датой, доступной identity Instrument и signed Money в исходной валюте. Страница MUST NOT добавлять внешние группировочные карточки или заголовки по Instrument либо валюте, subtotals инструмента или количество выплат инструмента. Список MUST сохранять отрицательные корректировки как самостоятельные Ledger Entries и MUST отражать одну запись на идентичность User, Brokerage Account, текущее подключение и operation ID; повторная загрузка того же ID MUST обновлять поля и MUST NOT удваивать выплату. Одинаковые operation IDs разных счетов MUST оставаться отдельными записями. Список MUST NOT включать записи вне аналитического итога. Отказ от группировочного UI MUST NOT отменять проверки принадлежности entries к instrumentKey, валюты и receipt count ответа или приводить к пересчёту денежных итогов на клиенте.
|
||
|
||
#### Scenario: Каждая выплата показана отдельной карточкой
|
||
|
||
- **WHEN** выбранный период содержит несколько включённых Ledger Entries одного или разных Instrument
|
||
- **THEN** раздел «Выплаты» сразу показывает отдельную карточку каждой записи в исходном порядке без внешних группировочных блоков, раскрытия, итогов инструмента и receipt count на UI
|
||
|
||
#### Scenario: Список воспроизводит точный состав дохода
|
||
|
||
- **WHEN** User просматривает загруженный раздел «Выплаты»
|
||
- **THEN** он видит все и только включённые coupon и dividend Ledger Entries применённого периода с датой, описанием, доступной identity и исходной суммой
|
||
|
||
#### Scenario: Отрицательная корректировка и повторяющиеся IDs сохраняются
|
||
|
||
- **WHEN** доход содержит отрицательную корректировку, повторно загруженный ID того же счёта либо одинаковые operation IDs разных счетов
|
||
- **THEN** корректировка отображается с исходным знаком; одна операция того же счёта имеет одну карточку с актуальными полями, а операции разных счетов остаются отдельными карточками
|
||
|
||
#### Scenario: Валюта видна в сумме каждой выплаты
|
||
|
||
- **WHEN** подходящие выплаты одного Instrument представлены в нескольких исходных валютах
|
||
- **THEN** каждая карточка показывает свою Money с исходной валютой, без отдельного заголовка валютной группы или объединённого мультивалютного итога
|