96 lines
15 KiB
Markdown
96 lines
15 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: User can retrieve an account ledger
|
||
Система MUST предоставлять аутентифицированный журнал только для чтения выбранного Brokerage Account либо существующего режима «Все счета» (`all`) в границах текущего User и его T-Bank connection. В режиме `all` доступ MUST проверяться для каждого входящего счёта, операции MUST сохранять принадлежность исходному счёту, а полнота периода MUST учитывать покрытие каждого входящего счёта. Журнал MUST содержать только исполненные операции T-Bank и при отсутствии периода по умолчанию охватывать интервал от начала текущего календарного года в UTC до момента запроса.
|
||
|
||
Система MUST читать сохранённые операции и локальное подтверждение доступа текущего подключения без синхронного обращения к T-Bank, включая запрос списка счетов. Ответ MUST содержать envelope `{ data, meta }` по `tbank-data-sync`, отражающий полноту запрошенного периода независимо от текущей страницы. Отсутствующие данные MUST возвращаться с `data: null` и состоянием загрузки, а частично сохранённый период MUST обозначаться как `partial`. Только подтверждённо полный пустой период MUST обозначать отсутствие операций.
|
||
|
||
#### Scenario: Получение журнала с периодом по умолчанию
|
||
- **WHEN** аутентифицированный User запрашивает журнал принадлежащего ему Brokerage Account без периода
|
||
- **THEN** система возвращает сохранённые исполненные операции в `data` и полноту периода в `meta` за период от начала текущего календарного года в UTC до момента запроса, запрашивая отсутствующие интервалы в фоне
|
||
|
||
#### Scenario: Отклонение недоступного счёта
|
||
- **WHEN** аутентифицированный User запрашивает журнал счёта, для которого локальные данные текущего подключения подтверждают отсутствие доступа либо неподдерживаемое или закрытое состояние
|
||
- **THEN** система возвращает существующий ответ о недоступности счёта и не раскрывает операции
|
||
|
||
#### Scenario: Общий журнал содержит неполный счёт
|
||
- **WHEN** User запрашивает режим `all` и у одного из разрешённых счетов есть незагруженный интервал периода
|
||
- **THEN** система возвращает только разрешённые сохранённые записи с принадлежностью счёту и обозначает общий период неполным, не подменяя отсутствующий вклад пустым счётом
|
||
|
||
#### Scenario: Пустая загруженная часть не доказывает отсутствие операций
|
||
- **WHEN** в сохранённой части периода нет записей, но покрытие периода не завершено
|
||
- **THEN** ответ обозначает неполноту и запрошенную загрузку, а интерфейс не сообщает, что операций за период нет
|
||
|
||
### Requirement: User can browse a filtered ledger
|
||
Система MUST позволять User ограничивать журнал включительным периодом дат и любым подмножеством категорий trade, income, tax, fee, transfer, other. Система MUST фильтровать сохранённые операции локально, не перечитывая T-Bank из-за категории, instrument UID, размера страницы или перехода между страницами полного периода. Система MUST разбивать упорядоченный результат на страницы с непрозрачным cursor и возвращать признак доступности следующей страницы.
|
||
|
||
Cursor MUST быть привязан к User, текущему подключению, составу счетов, применённым фильтрам, зафиксированной верхней границе периода и версии читаемых данных. Курсор другой границы или изменившейся версии MUST отклоняться существующим `INVALID_OPERATIONS_CURSOR`, позволяя повторить первую страницу с прежними фильтрами. Доступность следующей локальной страницы MUST NOT заменять признак полноты периода. Равнозначные порядок и дубли categories MUST NOT создавать другую идентичность запроса.
|
||
|
||
#### Scenario: Фильтрация доходных операций за период
|
||
- **WHEN** User запрашивает период дат и категорию income
|
||
- **THEN** результат содержит только исполненные доходные операции с датой в пределах этого периода
|
||
|
||
#### Scenario: Продолжение истории
|
||
- **WHEN** User запрашивает cursor следующей страницы, возвращённый предыдущим ответом журнала, и версия данных не изменилась
|
||
- **THEN** система возвращает следующую страницу без повторения записей предыдущей страницы
|
||
|
||
#### Scenario: Обновление изменило данные между страницами
|
||
- **WHEN** после выдачи первой страницы успешная синхронизация изменила её набор операций и User передаёт прежний cursor
|
||
- **THEN** система возвращает `INVALID_OPERATIONS_CURSOR`, а повторная загрузка начинает первую страницу с сохранёнными применёнными фильтрами без пропуска или дублирования записей
|
||
|
||
#### Scenario: Полный период фильтруется локально
|
||
- **WHEN** User меняет категории или страницы в полностью сохранённом прошлом периоде
|
||
- **THEN** система формирует результат из сохранённых операций без нового запроса операций T-Bank
|
||
|
||
### Requirement: Ledger entries preserve broker operation meaning
|
||
Система MUST представлять одну upstream-операцию одной записью журнала и MUST передавать её timestamp, тип операции, категорию, описание, доступные идентификаторы инструмента, доступную presentation metadata инструмента, денежную выплату, количество, цену, НКД и комиссию. Денежные поля MUST сохранять исходную валюту и точное десятичное значение.
|
||
|
||
В пределах текущего подключения идентичность Ledger Entry MUST включать User, Brokerage Account и upstream operation ID. Повторное получение того же ID MUST обновлять доступные поля этой операции без создания второй записи; одинаковые ID разных счетов MUST оставаться разными записями. Стабильность ID MUST считаться допущением проекта, а не гарантией T-Bank.
|
||
|
||
#### Scenario: Отображение купонной выплаты
|
||
- **WHEN** T-Bank возвращает исполненную купонную операцию с выплатой и данными инструмента
|
||
- **THEN** запись журнала определяет её как income и передаёт исходную сумму выплаты, валюту и данные инструмента
|
||
|
||
#### Scenario: Отображение комиссии сделки без синтетической записи
|
||
- **WHEN** T-Bank возвращает исполненную сделку, содержащую выплату и комиссию
|
||
- **THEN** журнал содержит одну запись сделки с комиссией в качестве её детали
|
||
|
||
#### Scenario: Отображение движения бумаг без денег
|
||
- **WHEN** T-Bank возвращает исполненную операцию, изменяющую состав инструментов, но без денежной выплаты
|
||
- **THEN** запись журнала передаёт доступное количество и не содержит искусственной денежной выплаты с нулевым значением
|
||
|
||
#### Scenario: Доступна визуальная идентичность инструмента
|
||
- **WHEN** для инструмента исполненной операции доступна presentation metadata бренда
|
||
- **THEN** запись журнала передаёт её вместе с доступными идентификаторами инструмента, не меняя остальные сведения операции
|
||
|
||
#### Scenario: Повторная операция содержит исправленные поля
|
||
- **WHEN** успешная синхронизация получает операцию с уже сохранённым ID того же счёта и изменёнными полями
|
||
- **THEN** последующее чтение возвращает одну запись с обновлёнными полями без удвоения денежного движения
|
||
|
||
### Requirement: Account overview includes recent ledger events
|
||
Обзор счёта MUST показывать не более пяти последних сохранённых исполненных записей журнала этого счёта с состоянием полноты и загрузки требуемого периода и действие перехода к его полному журналу. Каждая показанная запись MUST иметь ту же визуальную идентичность инструмента и семантику денежного движения, что и запись полного журнала. Неуспешный или пустой запрос последних записей MUST оставаться локальным состоянием блока последних событий и MUST NOT заменять успешно отображённый обзор Portfolio.
|
||
|
||
#### Scenario: Отображение последних событий
|
||
- **WHEN** загружается обзор счёта и его журнал содержит исполненные операции
|
||
- **THEN** обзор показывает не более пяти последних записей и ссылку на полный журнал
|
||
|
||
#### Scenario: Последние записи недоступны
|
||
- **WHEN** обзор счёта успешно загружается, но запрос последних записей завершается ошибкой
|
||
- **THEN** обзор Portfolio остаётся доступным, а блок последних событий отображает собственное состояние восстановления
|
||
|
||
#### Scenario: Последняя запись не содержит visual metadata инструмента
|
||
- **WHEN** одна из последних записей не имеет доступной presentation metadata инструмента
|
||
- **THEN** обзор показывает для неё понятный текстовый fallback и сохраняет дату, тип, инструмент и денежное изменение записи доступными для чтения
|
||
|
||
#### Scenario: Первичная история обзора неполна
|
||
- **WHEN** обзор получил только часть требуемых операций или `data: null`
|
||
- **THEN** блок обозначает загрузку или неполноту и не утверждает, что показанные записи окончательны либо операции отсутствуют
|
||
|
||
## REMOVED Requirements
|
||
|
||
### Requirement: Кэш страниц журнала ограничивает локальные ресурсы
|
||
|
||
**Reason:** Постоянное хранение операций и запросная синхронизация заменяют обязательный RAM-кэш на 100 страниц с TTL 30 секунд; его запрет на выдачу старой страницы противоречит локальному чтению сохранённой истории.
|
||
|
||
**Migration:** Чтение, свежесть, объединение загрузок и сохранение прогресса переходят к `tbank-data-sync`; локальная фильтрация и привязанный к версии данных cursor регулируются `User can browse a filtered ledger`. Существующие transient cursors не являются доказательством полноты и при несовместимости возвращают `INVALID_OPERATIONS_CURSOR`.
|