14 KiB
Delta Spec: portfolio-view
MODIFIED Requirements
Requirement: Нормализованный состав Portfolio
Система MUST возвращать только обычные Portfolio Position с ненулевым количеством и доступные Cash Balance с ненулевой суммой. Cash Balance MUST быть отдельным от Portfolio Position элементом и агрегироваться до одного значения на валюту. Порядок Portfolio Position и Cash Balance MUST соответствовать upstream-порядку; система MUST NOT сортировать или объединять Portfolio Position с одинаковым FIGI. Виртуальные позиции и заблокированные денежные остатки MUST NOT входить в Portfolio.
Каждая Portfolio Position MUST содержать нормализованный тип STOCK, BOND, FUND, CURRENCY, FUTURE, OPTION, STRUCTURED_NOTE, DIGITAL_FINANCIAL_ASSET либо OTHER, строковое quantity, nullable currentValue, nullable averagePurchasePrice, nullable absoluteReturn, nullable isin и nullable logoName — имя файла логотипа бренда инструмента. Имя файла логотипа MUST заполняться из metadata инструмента, когда upstream предоставляет бренд с непустым именем файла логотипа; во всех остальных случаях оно MUST быть null. Логотип является presentation metadata: он не влияет на количество, стоимость, агрегаты, успешность или свежесть Portfolio Snapshot. Система MUST искать metadata по instrument UID при его наличии, затем по FIGI. Отображаемый идентификатор MUST предпочитать name, затем ticker, а при недоступности metadata использовать FIGI, не скрывая финансовые значения.
Scenario: Позиция с неизвестным upstream-типом
- WHEN upstream возвращает обычную ненулевую позицию с нераспознанным типом инструмента
- THEN система возвращает её в исходном порядке с типом
OTHER
Scenario: Позиция без metadata инструмента
- WHEN lookup metadata по FIGI не дал ticker или name либо временно недоступен
- THEN система возвращает позицию с FIGI как fallback-идентификатором и всеми доступными финансовыми значениями
Scenario: Имя инструмента доступно
- WHEN metadata инструмента по FIGI содержит непустое name
- THEN система возвращает name как отображаемый идентификатор позиции вместо FIGI или ticker
Scenario: FIGI не разрешается, но доступен instrument UID
- WHEN FIGI позиции не даёт metadata, а её instrument UID возвращает непустое name
- THEN система возвращает name, полученное по instrument UID
Scenario: ISIN инструмента доступен
- WHEN metadata инструмента позиции содержит непустой
isin - THEN система возвращает его в поле
isinпозиции
Scenario: ISIN инструмента отсутствует
- WHEN у инструмента позиции нет ISIN либо metadata недоступна
- THEN система возвращает позицию с
isin: null, не скрывая финансовые значения
Scenario: Имя файла логотипа бренда доступно
- WHEN metadata инструмента позиции содержит бренд с непустым именем файла логотипа
- THEN система возвращает его в поле
logoNameпозиции
Scenario: Имя файла логотипа бренда отсутствует
- WHEN у инструмента позиции нет бренда, имя файла логотипа пустое либо metadata недоступна
- THEN система возвращает позицию с
logoName: null, не скрывая финансовые значения
Scenario: Денежные остатки в одной валюте
- WHEN upstream возвращает несколько ненулевых доступных денежных остатков одной валюты
- THEN система возвращает один Cash Balance с их точной суммой
Scenario: Штатный пустой Portfolio
- WHEN у доступного Brokerage Account нет ненулевых обычных позиций и доступных денежных остатков
- THEN система отвечает
200с пустымиpositions,cashBalancesиtotalsByCurrency
Requirement: Ошибки и состояния Portfolio на клиенте
Клиент SHALL загружать Portfolio при открытии защищённого маршрута /accounts/:accountId. Он MUST использовать успешный ответ в течение 30 секунд, без automatic retry, polling или refetch при возврате фокуса. После истечения срока клиент MUST скрыть предыдущий ответ и показать loading-состояние до нового результата.
Клиент MUST показать штатное empty-состояние только при пустых positions и cashBalances. При isStale: true клиент MUST показывать Snapshot, lastSuccessfulAt и нейтральное предупреждение о временной недоступности T-Bank. При 404 клиент MUST показать состояние недоступного счёта с действием возврата к списку счетов. При отсутствии Snapshot и TBANK_NOT_CONNECTED, INVALID_TBANK_TOKEN, TBANK_UNAVAILABLE или иной ошибке клиент MUST показать безопасное error-состояние с доступными для ошибки действиями; действие повтора разрешено только для временной и неизвестной ошибки.
Клиент MUST отображать STOCK и BOND отдельными секциями. Внутри каждой секции MUST сохраняться upstream-порядок позиций. Позиции иных типов MUST оставаться доступными в отдельной общей секции.
Карточки секции STOCK MUST отображаться по одной в ряду при любой ширине экрана. Карточка акции MUST показывать визуальный логотип бренда инструмента рядом с отображаемым идентификатором позиции; при отсутствии имени файла логотипа либо неудачной загрузке изображения вместо логотипа MUST отображаться первая буква отображаемого идентификатора позиции. Абсолютный доход в карточке акции MUST отображаться значением с явным знаком (+ для положительного, - для отрицательного, без знака при нуле) с цветовой индикацией знака и без текстовой подписи доходности.
Карточки секции BOND и общей секции иных типов MUST сохранять прежнее поведение: компактная плитка в адаптивном grid (одна колонка на узком экране, несколько колонок на широком), абсолютный доход с текстовой подписью доходности и цветовой индикацией знака, без визуального логотипа. Плитки всех секций MUST показывать отображаемый идентификатор позиции, количество, currentValue как главную метрику, absoluteReturn, averagePurchasePrice, долю позиции среди позиций той же валюты и isin. Отсутствующие метрики MUST быть скрыты, а не отображаться заглушкой. При форматировании денежных значений в русской локали клиент MUST отображать RUB как символ ₽; другие валюты MUST сохранять понятное обозначение.
Scenario: Показ устаревшего Portfolio
- WHEN клиент получает успешный ответ с
isStale: true - THEN клиент показывает позиции и остатки, время последнего успешного снимка и предупреждение без действия ручного обновления
Scenario: Недоступный счёт на клиенте
- WHEN клиент получает
404для Portfolio - THEN клиент не показывает Portfolio и предлагает вернуться к списку Brokerage Account без действия повтора
Scenario: Портфель отображается на мобильном устройстве
- WHEN User открывает загруженный Portfolio на узком экране
- THEN клиент сохраняет читаемое одноколоночное отображение агрегатов, позиций и Cash Balance
Scenario: Отдельные акции и облигации
- WHEN Portfolio содержит позиции
STOCKиBOND - THEN клиент отображает их в отдельных секциях «Акции» и «Облигации» без изменения порядка в каждой секции
Scenario: Карточка позиции отображает доступные метрики
- WHEN позиция имеет значение текущей стоимости, абсолютного дохода, средней цены покупки и ISIN
- THEN клиент показывает идентификатор, количество, текущую стоимость, абсолютный доход, среднюю цену покупки, долю среди позиций той же валюты и ISIN
Scenario: Отсутствующие метрики скрыты
- WHEN у позиции отсутствует значение текущей стоимости, средней цены покупки или дохода
- THEN клиент скрывает соответствующую метрику вместо отображения заглушки
Scenario: Доход окрашен по знаку
- WHEN у позиции абсолютный доход положительный или отрицательный
- THEN клиент отображает его зелёным для положительного и красным для отрицательного, без цвета при его отсутствии
Scenario: Доля позиции в валюте
- WHEN позиция имеет вычислимую текущую стоимость в валюте
- THEN клиент отображает её долю среди всех позиций той же валюты, не включая Cash Balance
Scenario: Одноколоночная секция акций
- WHEN User открывает загруженный Portfolio с позициями
STOCKна широком экране - THEN клиент отображает карточки акций по одной в ряду
Scenario: Логотип акции отображается
- WHEN позиция
STOCKсодержит непустое имя файла логотипа бренда и изображение успешно загружается - THEN клиент показывает изображение логотипа рядом с отображаемым идентификатором позиции
Scenario: Фолбэк без логотипа
- WHEN у позиции
STOCKимя файла логотипа отсутствует либо изображение не загружается - THEN вместо логотипа клиент показывает первую букву отображаемого идентификатора позиции
Scenario: Доходность акции со знаком без подписи
- WHEN карточка акции показывает абсолютный доход
- THEN клиент отображает значение с явным знаком
+или-(без знака при нуле) и без текстовой подписи доходности
Scenario: Секция облигаций сохраняет прежний вид
- WHEN User открывает загруженный Portfolio с позициями
BOND - THEN клиент отображает облигации плитками в адаптивном grid с текстовой подписью доходности и без визуального логотипа