moex-vibe/docs/superpowers/specs/2026-06-17-broker-portfolio-display.md
Sergey Krylov bd8d6c11fe
All checks were successful
CI / lint (pull_request) Successful in 2m3s
CI / test (pull_request) Successful in 2m5s
CI / build (pull_request) Successful in 2m0s
CI / lint (push) Successful in 1m55s
CI / test (push) Successful in 8m13s
CI / build (push) Successful in 2m8s
feat: improove ui
2026-06-17 13:15:01 +03:00

12 KiB
Raw Permalink Blame History

Улучшение отображения брокерского портфеля

Дата: 2026-06-17 Статус: согласовано к планированию

Контекст

Страница брокерского счета находится в apps/frontend/src/pages/broker/BrokerAccountDetailPage.tsx. Сейчас она показывает все позиции одной таблицей, выводит колонку Доходность, не показывает отдельную колонку текущей цены, не делает тикеры кликабельными и загружает операции одним запросом с limit: 100.

Данные для страницы уже есть в текущем frontend-контракте:

  • BrokerPosition.instrumentType, ticker, name, quantity, currentPrice, currentValue;
  • BrokerOperation.type, category, description, ticker, instrumentType, payment, price;
  • BrokerOperationsPage.nextCursor и hasNext для cursor-пагинации.

Бэкенд и публичный API для этой задачи менять не нужно.

Цель

Сделать страницу брокерского портфеля легче для чтения: разделить классы инструментов, убрать лишнюю доходность из таблицы позиций, добавить текущую цену, сделать переходы к карточкам инструментов и явно показать финансовый смысл операций.

Область изменений

В рамках задачи меняется только frontend брокерской страницы:

  • apps/frontend/src/pages/broker/BrokerAccountDetailPage.tsx;
  • новые helper-функции и компоненты внутри apps/frontend/src/pages/broker/;
  • тесты в apps/frontend/src/pages/broker/ и существующий BrokerPages.test.tsx.

apps/docs, backend DTO, OpenAPI и codegen не меняются.

Позиции

Позиции брокерского портфеля показываются отдельными секциями:

  • Акции для instrumentType === 'share';
  • Облигации для instrumentType === 'bond';
  • Другие инструменты, если в портфеле есть позиции с другим или неизвестным типом.

Пустые секции не отображаются.

Таблица каждой секции использует компактные колонки:

Колонка Источник Поведение
Тикер ticker Если известен маршрут инструмента, тикер является ссылкой.
Название name Если имени нет, показывается -.
Количество quantity Если количества нет, показывается -.
Цена currentPrice Деньги форматируются как ru-RU currency.
Стоимость currentValue Деньги форматируются как ru-RU currency.

Колонка Доходность удаляется из таблиц позиций брокерского портфеля. Доходность остается доступной в summary над таблицами, где она не смешивается с построчным составом портфеля.

Ссылки на инструменты

Маршрутизация повторяет ручной портфель:

  • акция: /stocks/:ticker;
  • облигация: /bonds/:ticker.

Если ticker отсутствует или тип инструмента не поддержан, значение показывается текстом без ссылки. Для неизвестного instrumentType допускается fallback по classCode, если он однозначно указывает на акцию или облигацию.

Операции

Операции показываются по 10 штук на странице. Страница использует существующий cursor API:

  • первый запрос: { limit: 10 };
  • переход вперед: { limit: 10, cursor: nextCursor };
  • переход назад: восстановление предыдущего cursor из локального stack в UI.

UI показывает номер текущей страницы, кнопку Назад и кнопку Вперед. Назад выключена на первой странице. Вперед выключена, когда hasNext === false или нет nextCursor.

Таблица операций сохраняет основные колонки:

Колонка Источник Поведение
Дата date toLocaleString('ru-RU'), при отсутствии -.
Тип type, description, category Русскоязычное название и бейдж эффекта.
Инструмент ticker, description Если известен маршрут инструмента, значение является ссылкой.
Сумма payment Форматируется как деньги и окрашивается по эффекту операции.

Русские названия типов

Для известных T-Bank enum-значений frontend показывает русские названия. Минимальный набор:

T-Bank type Название
OPERATION_TYPE_BUY Покупка
OPERATION_TYPE_BUY_CARD Покупка
OPERATION_TYPE_SELL Продажа
OPERATION_TYPE_SELL_CARD Продажа
OPERATION_TYPE_COUPON Выплата купона
OPERATION_TYPE_DIVIDEND Дивиденды
OPERATION_TYPE_BOND_REPAYMENT Погашение облигации
OPERATION_TYPE_BOND_REPAYMENT_FULL Полное погашение облигации
OPERATION_TYPE_TAX Налог
OPERATION_TYPE_BOND_TAX Налог по облигациям
OPERATION_TYPE_DIVIDEND_TAX Налог на дивиденды
OPERATION_TYPE_BROKER_FEE Комиссия брокера
OPERATION_TYPE_SERVICE_FEE Комиссия за обслуживание
OPERATION_TYPE_INPUT Пополнение
OPERATION_TYPE_OUTPUT Вывод средств
OPERATION_TYPE_INPUT_SECURITIES Зачисление бумаг
OPERATION_TYPE_OUTPUT_SECURITIES Списание бумаг

Если тип неизвестен, но есть description, показывается description. Если нет и описания, показывается очищенный enum без префикса OPERATION_TYPE_.

Эффект операции

Выбранный дизайн: бейдж эффекта в колонке Тип плюс цвет суммы.

Эффект определяется не только знаком суммы, потому что сделки не являются доходом сами по себе:

  • Пополнение и доходы вроде купонов или дивидендов получают эффект Пополняет;
  • налоги, комиссии и вывод средств получают эффект Списывает;
  • покупки, продажи, ввод/вывод бумаг и погашение тела облигации получают эффект Перекладка;
  • неизвестные операции получают эффект Неясно.

Цвета используются как вспомогательный признак, а текст бейджа остается основным признаком для доступности:

  • Пополняет: зеленый акцент;
  • Списывает: красный акцент;
  • Перекладка: нейтральный или синий акцент;
  • Неясно: приглушенный серый акцент.

Ошибки и пустые состояния

  • Если портфель не загрузился, остается текущее сообщение об ошибке портфеля.
  • Если операции загружаются, показывается Загрузка операций....
  • Если операций нет, показывается пустое состояние Операций за выбранный период нет.
  • Если у позиции или операции нет тикера, вместо ссылки показывается текстовое значение или -.

TDD-стратегия

Сначала пишутся failing tests:

  1. Helper-тесты для группировки позиций, маршрутов инструментов, русских названий операций и эффекта операций.
  2. Component/page-тесты для раздельных таблиц акций и облигаций, отсутствия колонки Доходность и наличия Цена.
  3. Component/page-тесты для кликабельных инструментов в позициях и операциях.
  4. Component/page-тесты для cursor-пагинации операций по 10 элементов.

Затем реализуются helper-функции, компоненты таблиц и интеграция в BrokerAccountDetailPage.

Acceptance Criteria

  • Позиции акций и облигаций отображаются в отдельных таблицах.
  • Позиции с другим типом отображаются в Другие инструменты, если такие позиции есть.
  • В таблицах позиций нет колонки Доходность.
  • В таблицах позиций есть колонка Цена.
  • Тикеры позиций ведут на /stocks/:ticker или /bonds/:ticker.
  • Операции запрашиваются с limit: 10.
  • Пользователь может переходить вперед и назад по cursor-страницам операций.
  • В операциях колонка Инструмент ведет на страницу акции или облигации, если известен тип инструмента.
  • В операциях колонка Тип показывает русскоязычные названия.
  • В операциях визуально понятно, пополняет операция портфель, списывает средства, является перекладкой или не классифицирована.