Files
codex-bot a2d2df3b5a
Specs security / security (push) Successful in 6s
Specs verify / verify (push) Successful in 7s
spec: archive group-account-rows-by-instrument and sync canonical specs (WealthLedger/main#47) (#65)
2026-10-30 07:35:30 +03:00

22 KiB
Raw Blame History

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 блок обзора показывает те же пять записей, что и без группировки, две из них одной группой