## 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** User запрашивает режим `all` и у одного из разрешённых счетов есть незагруженный интервал периода - **THEN** система возвращает только разрешённые сохранённые записи с принадлежностью счёту и обозначает общий период неполным, не подменяя отсутствующий вклад пустым счётом #### Scenario: Пустая загруженная часть не доказывает отсутствие операций - **WHEN** в сохранённой части периода нет записей, но покрытие периода не завершено - **THEN** ответ обозначает неполноту и запрошенную загрузку, а интерфейс не сообщает, что операций за период нет ### Requirement: Account overview includes recent ledger events Обзор счёта MUST показывать пять последних исполненных записей журнала этого счёта, а в режиме «Все счета» — пять последних записей всех входящих счетов, и действие перехода к его полному журналу. Каждая запись MUST иметь ту же визуальную идентичность инструмента и семантику денежного движения, что и запись полного журнала; в группе режима «Все счета» визуальная идентичность, дата и тип показываются в заголовке группы. Неуспешный или пустой запрос MUST оставаться локальным состоянием блока и MUST NOT заменять успешно отображённый Portfolio. При временном сбое обновления блок MUST сохранять доступные записи без технического предупреждения или ручного повтора. При отсутствии результата он SHALL показывать первичное ожидание либо нейтральную недоступность, автоматически восстанавливая чтение. Неподтверждённая пустота MUST NOT представляться отсутствием операций. #### Scenario: Отображение последних событий - **WHEN** загружается обзор счёта и его журнал содержит исполненные операции - **THEN** обзор показывает не более пяти последних записей и ссылку на полный журнал #### Scenario: Последние записи недоступны - **WHEN** обзор счёта успешно загружается, но запрос последних записей завершается временной ошибкой - **THEN** Portfolio остаётся доступным, а блок сохраняет прежние записи либо показывает нейтральную недоступность без технического повтора и восстанавливается автоматически #### Scenario: Последняя запись не содержит visual metadata инструмента - **WHEN** одна из последних записей не имеет доступной presentation metadata инструмента - **THEN** обзор показывает для неё понятный текстовый fallback и сохраняет дату, тип, инструмент и денежное изменение записи доступными для чтения ### Requirement: Full ledger presents compact rows Страница полного журнала MUST показывать для каждой записи дату, тип операции, инструмент и денежное изменение в исходной валюте в компактной структурированной строке. При доступной presentation metadata инструмента строка MUST показывать его визуальную идентичность; при её отсутствии MUST использовать понятный текстовый fallback. Для купонных и дивидендных операций на странице полного журнала и в личной истории инструмента MUST использоваться то же представление выплаты, что в доходе, прогнозе и графиках инструментов, с обозначением исполненного движения. Для каждой записи денежное изменение в исходной валюте MUST сопровождаться подписью конкретного типа события и знаком: для купонной операции — «Купон», для дивидендной — «Дивиденд», для остальных записей — подпись их категории («Сделка», «Налог», «Комиссия», «Перевод», «Прочее»). Строка MUST NOT повторять подпись типа события во вторичной метадате записи. Знак «+» / «−» и семантический цвет MUST оставаться носителями направления и MUST NOT заменяться только текстом. Страница MUST обозначать записи без движения денег нейтрально и MUST NOT показывать цену или количество. В группе режима «Все счета» дата, тип операции, инструмент и его визуальная идентичность MUST показываться один раз в заголовке группы, а строка каждой записи группы MUST показывать её счёт и денежное изменение с подписью типа и знаком. #### Scenario: Отображение записи только с инструментом - **WHEN** полный журнал отображает запись без денежной выплаты - **THEN** страница определяет её как запись без движения денег #### Scenario: Отображение поступления - **WHEN** полный журнал отображает запись с положительной денежной выплатой - **THEN** строка явно показывает поступление знаком и подписью конкретного типа события («Купон», «Дивиденд» или категории) и его денежное изменение в исходной валюте, не полагаясь только на цвет #### Scenario: Отображение списания - **WHEN** полный журнал отображает запись с отрицательной денежной выплатой - **THEN** строка явно показывает списание знаком и подписью конкретного типа события («Купон», «Дивиденд» или категории) и его денежное изменение в исходной валюте, не полагаясь только на цвет #### Scenario: Отображение купона - **WHEN** полный журнал или личная история инструмента отображает исполненную операцию с upstream-типом купона - **THEN** запись показывает подпись «Купон» и исполненную сумму в том же представлении выплаты, что на других экранах #### Scenario: Отображение дивиденда - **WHEN** полный журнал или личная история инструмента отображает исполненную операцию с upstream-типом дивиденда - **THEN** запись показывает подпись «Дивиденд» и исполненную сумму в том же представлении выплаты, что на других экранах #### Scenario: Подпись типа не дублируется - **WHEN** полный журнал отображает запись с типом события и вторичной метадатой - **THEN** подпись типа события присутствует в строке один раз и не повторяется во вторичной метадате записи #### Scenario: Отсутствует visual metadata инструмента - **WHEN** полный журнал отображает запись без доступной presentation metadata инструмента - **THEN** строка показывает понятный текстовый fallback без подмены или сокрытия доступных данных инструмента #### Scenario: Запись внутри группы режима «Все счета» - **WHEN** полный журнал в режиме «Все счета» показывает запись в составе группы - **THEN** её дата, тип и инструмент читаются из заголовка группы, а строка записи показывает счёт и денежное изменение со знаком и подписью типа ## ADDED Requirements ### Requirement: All-accounts ledger groups same-day entries of one instrument В режиме «Все счета» полный журнал и последние записи обзора MUST объединять в визуальную группу две и более показанных записи с одинаковыми днём (как на экране), identity Instrument и точным upstream-типом операции, даже если они на одном счёте. Записи без Instrument или без пары MUST показываться как раньше. В режиме одного Brokerage Account группировка MUST NOT применяться. #### Scenario: Купоны одной облигации на двух счетах - **WHEN** в режиме «Все счета» журнал показывает за один день купон по облигации на брокерском счёте +200 RUB и купон по той же облигации на ИИС +100 RUB - **THEN** они показаны одной группой с облигацией, типом «Купон» и итогом +300 RUB, а под заголовком видны строки «брокерский счёт +200 RUB» и «ИИС +100 RUB» #### Scenario: Две операции одного типа на одном счёте - **WHEN** в режиме «Все счета» журнал показывает за один день две покупки одной бумаги на одном счёте - **THEN** они показаны одной группой, где каждая покупка остаётся отдельной строкой со своим денежным изменением #### Scenario: Разные типы по одной бумаге не объединяются - **WHEN** в режиме «Все счета» за один день по одной облигации есть купон и налог с этого купона - **THEN** купоны и налоги показаны раздельно, и ни одна группа не содержит записи разных типов #### Scenario: Покупка и продажа не объединяются - **WHEN** в режиме «Все счета» за один день показаны покупка и продажа одной бумаги - **THEN** они не входят в одну группу #### Scenario: Разные дни не объединяются - **WHEN** в режиме «Все счета» купоны по одной облигации на двух счетах датированы на экране разными днями - **THEN** они показаны отдельными записями без группы #### Scenario: Запись без Instrument - **WHEN** в режиме «Все счета» за один день показаны две записи одного типа без identity Instrument - **THEN** они показаны отдельными записями так же, как без группировки #### Scenario: Режим одного счёта не меняется - **WHEN** User открывает журнал или обзор одного Brokerage Account, где есть два купона по одной облигации за один день - **THEN** записи показаны отдельными строками без группы, как до изменения ### Requirement: All-accounts ledger group shows each entry and an exact total Заголовок группы журнала MUST показывать дату, Instrument с визуальной идентичностью, подпись типа операции, как в строке журнала, и итог. Под ним MUST всегда быть видна, без раскрытия, отдельная строка каждой записи со счётом и денежным изменением. Итог SHALL быть точной суммой со знаком по каждой исходной валюте без конвертации и округления. Итог MUST NOT показываться, если у записи группы нет денежного изменения (включая нулевое) или полнота периода не подтверждена. #### Scenario: Итог по нескольким валютам - **WHEN** группа содержит записи с денежными изменениями в RUB и в USD - **THEN** заголовок показывает отдельный точный итог в RUB и отдельный в USD, без конвертации #### Scenario: Итог со знаком - **WHEN** группа содержит поступление +150.10 RUB и отрицательную корректировку −50.05 RUB - **THEN** итог группы равен +100.05 RUB, а обе записи видны отдельными строками со своими знаками #### Scenario: Нулевой итог - **WHEN** группа содержит +150.10 RUB и −150.10 RUB - **THEN** заголовок показывает итог 0 RUB без знака направления, а обе записи видны со своими знаками #### Scenario: Группа с записью без денежного изменения - **WHEN** у одной из записей группы нет денежного изменения - **THEN** заголовок группы не показывает итог, а записи остаются видны отдельными строками #### Scenario: Запись с нулевой суммой скрывает итог - **WHEN** группа содержит запись +100 RUB и запись с денежным изменением 0 RUB - **THEN** заголовок группы не показывает итог, а запись с нулём обозначена как запись без движения денег #### Scenario: Итог скрыт при неполном периоде - **WHEN** журнал в режиме «Все счета» показывает группу, а период обозначен как `partial` - **THEN** заголовок группы не показывает итог, а записи группы остаются видны со своими суммами ### Requirement: All-accounts ledger grouping preserves order and limits Группа журнала MUST занимать позицию своей первой записи в серверном порядке; записи внутри группы и остальные строки MUST сохранять относительный серверный порядок. Группировка MUST NOT менять состав, фильтрацию, пагинацию или лимит обзора, который считается по записям. Группа собирается только из показанных записей; это осознанное исключение: её итог относится только к ним и не сопровождается пометкой о неполноте. #### Scenario: Позиция группы в списке - **WHEN** серверный порядок записей A, B, C, где A и C образуют группу, а B не входит ни в одну группу - **THEN** список показывает группу (A, C) на месте A, затем B #### Scenario: Группа на границе страницы - **WHEN** записи одной группы попадают на текущую и на ещё не показанную страницу журнала при подтверждённой полноте периода - **THEN** группа на текущей странице содержит только её показанные записи, итог равен их сумме, и заголовок не содержит пометки о неполноте #### Scenario: Группировка в последних записях обзора - **WHEN** в режиме «Все счета» среди пяти последних записей есть две записи с одинаковым ключом - **THEN** блок обзора показывает те же пять записей, что и без группировки, две из них одной группой