Files
docs/integrations/tbank.md
T
ksv741 c666ca0053
Conventional commits / commits (pull_request) Successful in 12s
Docs security / security (pull_request) Failing after 6s
Docs verify / verify (pull_request) Successful in 11s
docs: describe concentration tab and stored instrument classification (WealthLedger/main#48)
2026-11-01 12:24:39 +03:00

16 KiB
Raw Blame History

Интеграция с T-Bank Invest

T-Bank — источник доступных пользователю инвестиционных счетов, текущих позиций и денег, исполненных операций и рыночных сведений об инструментах. WealthLedger обращается к Invest API на сервере по gRPC over TLS и преобразует ответы в собственный HTTP API. Изображения логотипов загружаются браузером отдельно из публичного CDN; это не доступ к личным брокерским данным.

Данные и ответственность

Категория Для чего используется
Открытые счета Определить доступный состав счетов и проверить доступ к конкретному счёту
Портфель и денежные остатки Показать текущий состав инвестиций и итоги по исходным валютам
Исполненные операции Построить журнал и выделить полученные купоны и дивиденды
Инструменты и рынок Имена, идентификаторы, цены, свечи, параметры акций и облигаций
Классификация инструментов Сектор акций, облигаций и фондов и бренд актива для разрезов концентрации
Купоны и дивиденды Построить будущие события по текущим позициям и календарь инструмента

Сектор получается из описаний инструмента (отдельные описания для акций, облигаций и фондов, поиск по UID, затем по FIGI); эмитент — из описания актива по asset_uid инструмента: его uid и название бренда. Эмитент не выводится из названия, тикера или ISIN. Классификация хранится как последнее известное значение с обновлением не чаще раза в сутки (ADR 022); все вызовы проходят через общий лимитер запросов T-Bank.

T-Bank определяет исходные данные и права token. Backend проверяет локальную сессию, выбирает подключение её пользователя и устанавливает доступ к счёту. Наличие идентификатора счёта в URL этого доступа не подтверждает.

Скринер акций получает полный online-каталог акций T-Bank для каждого нового поиска. В него входят только инструменты, для которых каталог подтверждает и доступность покупки, и торговли через API. Эти признаки описывают полученный снимок каталога: они не подтверждают личные права пользователя, состояние торгов или исполнение будущей заявки. Скринер не использует личный портфель как каталог.

MOEX и НКР дополняют публичные сведения об облигациях; они не заменяют брокера как источник личных позиций и исполненных выплат. Границы источников показаны в контексте, смысл дополнений — в описании облигаций.

Публичные логотипы

T-Bank Brands CDN — отдельная публичная граница для изображений. Backend передаёт имя файла logoName из метаданных инструмента; frontend строит URL на invest-brands.cdn-tinkoff.ru и загружает изображение браузером. Эти запросы не используют HTTP-клиент приложения, его Bearer token или token Invest API. Лимитер и повторы серверных gRPC-вызовов к ним не относятся.

Логотипы используются в портфеле, операциях, будущих событиях, поиске и страницах инструментов. Отсутствующее имя или ошибка изображения оставляют буквенную заглушку и не меняют финансовые значения. Логотип — это metadata инструмента; он не равен эмитенту из концентрации, который берётся из бренда актива. Правило построения URL принадлежит форматированию frontend.

Проверка и сохранение подключения

Авторизованный пользователь управляет одним подключением в настройках. Интерфейс просит read-only T-Bank Invest token: он вводится в поле пароля и отправляется backend. API возвращает только состояние подключения и время его сохранения, не token. Успешное сохранение очищает поле, ошибка оставляет введённое значение для исправления. Удаление требует подтверждения в форме; во время изменения действия секции заблокированы.

Схема показывает динамический сценарий создания или замены подключения. SQLite — локальное хранилище backend, а не отдельный сетевой участник.

sequenceDiagram
  participant U as Пользователь
  participant F as React SPA
  participant B as Backend API
  participant T as T-Bank Invest API
  participant D as Локальная SQLite
  U->>F: Вводит token и сохраняет подключение
  F->>B: PUT connection с Bearer и token
  B->>T: GetAccounts OPEN по gRPC over TLS
  alt Проверка успешна, в том числе при пустом списке счетов
    T-->>B: Доступные открытые счета
    B->>D: Атомарно сохранить token, новую revision и membership
    B-->>F: Подключено и время сохранения
    F->>F: Обновить статус и сбросить финансовые выборки
    F-->>U: Показать подтверждённое подключение
  else Token отклонён или источник недоступен
    T-->>B: Ошибка проверки
    B-->>F: INVALID_TBANK_TOKEN или TBANK_UNAVAILABLE
    F-->>U: Локальная ошибка, прежнее подключение сохранено
  end

Перед проверкой backend удаляет внешние пробелы token и отклоняет пустое значение. Успешный пустой список счетов подтверждает token: наличие позиций не является условием подключения. Ошибка проверки не заменяет уже сохранённое подключение. Сетевой вызов T-Bank и запись SQLite выполняются последовательно, но не образуют общую транзакцию между системами.

Состояние и ошибки

Состояние без подключения содержит connected: false и connectedAt: null. После создания или замены connectedAt содержит время успешного сохранения в RFC 3339 UTC. Это время подключения, а не отметка свежести портфеля. Чтение статуса показывает сохранённое состояние; оно не выполняет заново проверку token у брокера. Если статус загрузить не удалось, интерфейс показывает ошибку с повтором, а не форму с предполагаемым отсутствием подключения.

INVALID_TBANK_TOKEN означает отказ внешней аутентификации или прав доступа. TBANK_UNAVAILABLE сообщает о временной или иной upstream-ошибке, включая исчерпание очереди. Диагностические причины жизненного цикла часовой попытки (INTERRUPTED — прерывание до нормального завершения, DEADLINE — истечение ограничения ожидания шага) не относятся к ошибкам T-Bank: они остаются внутренней диагностикой и не раскрываются в hourly-read. Истечение ограничения ожидания не отменяет уже начатые обращения к T-Bank; их поздние результаты остаются в строках шагов. Ответы и ошибки не содержат token. Удаление подключения идемпотентно: удаляются локальный секрет, личные datasets и work; поздняя публикация прежней revision запрещена. Общие неперсональные источники могут сохраняться. Оно не описывает отзыв token на стороне T-Bank.

Согласованное поведение сохранено в workspace-спецификации T-Bank connection. Точные endpoints и формы ответов определяет backend OpenAPI; HTTP API описывает общую границу.

Граница финансового кэша

Успешное создание, замена или удаление подключения меняет границу повторного использования финансовых данных. Это относится и к сохранению того же самого token: предыдущее подключение не становится источником данных нового. Неуспешная операция сохраняет прежнее подключение и его доступные данные. Механизм внутренней revision, поздние ответы и сброс клиентских выборок объясняет свежесть данных.

Конфигурация и ограничения

Backend хранит token в шифротексте AES-256-GCM с новым nonce при каждом сохранении. Ключ находится только в серверном окружении. Расшифровка нужна серверной интеграции; ни шифротекст, ни token не входят в публичное API. Причины границы и шифрования сохранены в ADR 003 и ADR 004.

Настройка Значение и смысл
TOKEN_ENCRYPTION_KEY Обязательный ключ AES-256-GCM: 32 байта, закодированные в base64
TBANK_GRPC_ENDPOINT Адрес gRPC; по умолчанию invest-public-api.tbank.ru:443
TBANK_RATE_LIMIT_PER_SECOND Число стартующих T-Bank RPC в секунду на экземпляр backend; по умолчанию 5
TBANK_CA_CERT_PATH Необязательный путь к доверенному корневому CA в PEM для сетей с TLS-инспекцией; проверка TLS сохраняется

Параметры окружения определяет backend validateEnv (справочный источник). Общий FIFO-лимитер ограничивает поток RPC и не допускает более 50 ожидающих. Для UNAVAILABLE, DEADLINE_EXCEEDED и RESOURCE_EXHAUSTED каждый RPC допускает один повтор через секунду. Deadline каждой попытки — 15 секунд, а ожидание места в лимитере не является временем этой сетевой попытки. Метаданные используют ту же retry policy. Переполненная очередь завершается ошибкой сразу, без повторов admission. Постоянные ошибки и отказ авторизации не повторяются. Подтверждённый NOT_FOUND при поиске метаданных означает отсутствие инструмента, а не временный сбой. Параметры попыток принадлежат T-Bank client (справочный источник); решение об ограниченных повторах — ADR 005.

Большое число ранее неизвестных инструментов требует отдельных запросов metadata. При перегруженной очереди необязательные имена могут быть заменены идентификаторами; это не доказывает потерю самой позиции. Изменение локального лимита требует учёта разрешённой квоты T-Bank: оно не увеличивает квоту поставщика.

Ключ шифрования не ротируется автоматически. Новый ключ не расшифрует прежнее подключение: нужен исходный ключ либо повторный ввод собственного token через настройки. Правила резервного копирования учитывают отдельное хранение ключа. Лимитер и кэши принадлежат одному экземпляру; изменения подключения не координируются между распределёнными экземплярами backend. Интеграция использует сохранённый protobuf-контракт T-Bank: обновление внешнего протокола и проверка совместимости требуют отдельного изменения интеграции.