# Подключение T-Bank Авторизованный пользователь управляет одним подключением к T-Bank Invest в настройках. Токен вводится только в поле пароля, отправляется в backend для проверки и больше не отображается. ```mermaid sequenceDiagram participant F as Frontend participant B as Backend participant T as T-Bank gRPC participant D as SQLite F->>B: PUT /api/v1/tbank-connection (Bearer, token) B->>T: GetAccounts(OPEN) over TLS T-->>B: счета или ошибка проверки B->>D: сохранить шифротекст AES-256-GCM B-->>F: { connected, connectedAt } ``` ## API - `GET /api/v1/tbank-connection` возвращает `{ connected: false, connectedAt: null }` или статус подключенного аккаунта. - `PUT /api/v1/tbank-connection` принимает `{ token }`, проверяет его через `GetAccounts` и создает или заменяет подключение. - `DELETE /api/v1/tbank-connection` идемпотентен и возвращает `204`. - `connectedAt` - метка времени RFC 3339 в UTC. Ответы и ошибки API никогда не содержат токен. `INVALID_TBANK_TOKEN` означает, что T-Bank отклонил аутентификацию или права доступа. `TBANK_UNAVAILABLE` означает временную ошибку, превышение лимита, ожидание в очереди или другую ошибку внешнего сервиса. ## Граница финансового кэша Каждый успешный `PUT` заново шифрует token с новым AES-GCM nonce. Backend вычисляет из сохранённого шифротекста непрозрачную внутреннюю generation и разрешает повторно использовать Portfolio Snapshot и Ledger Page Cache только для текущей generation. Generation не хранится отдельным полем, не входит в API, logs или errors. Поэтому сохранённый или поздно завершившийся ответ предыдущего подключения не обслуживает запрос после создания, замены или удаления connection, включая замену тем же plaintext token. После успешного `PUT` или `DELETE` frontend сначала коммитит подтверждённый статус connection, затем сбрасывает все generated GET query в `/api/v1/brokerage-accounts` subtree. Активные выборки запрашиваются заново, а неактивные загружаются при следующем использовании; данные предыдущей границы не остаются Client Cached Snapshot. Неуспешная mutation не меняет status, backend generation или financial cache. Обычная ошибка фонового refetch сохраняет Client Cached Snapshot текущей generation. Logout остаётся отдельной границей Session и полностью очищает status connection и остальные session-scoped query. ## Конфигурация и ограничения - `TOKEN_ENCRYPTION_KEY` - закодированный в base64 32-байтный ключ AES-256-GCM; обязателен при запуске. - `TBANK_GRPC_ENDPOINT` по умолчанию имеет значение `invest-public-api.tbank.ru:443`. - `TBANK_RATE_LIMIT_PER_SECOND` задаёт максимальное число T-Bank RPC в секунду на экземпляр backend; значение по умолчанию -- `5`. - `TBANK_CA_CERT_PATH` - необязательный путь к корневому CA-сертификату PEM для сетей с TLS-инспекцией; проверка TLS остается включенной. FIFO-ограничитель на экземпляр запускает не более 5 запросов в секунду и принимает не более 50 ожидающих вызовов. Для `UNAVAILABLE`, `DEADLINE_EXCEEDED` и `RESOURCE_EXHAUSTED` выполняется одна повторная попытка через секунду. Deadline каждой попытки - 15 секунд. Портфель с большим числом ранее не кэшированных инструментов создаёт отдельные metadata lookup. Если в такой ситуации очередь переполняется и позиции получают FIGI вместо names, увеличьте `TBANK_RATE_LIMIT_PER_SECOND` в соответствии с разрешённой upstream-квотой; для локального портфеля из множества позиций использовалось значение `50`. ## Ограничения Подключение используется поставленными сценариями Brokerage Accounts, Portfolio, Account Ledger и Future Cash Events; frontend не обращается к T-Bank напрямую. Token encryption key не ротируется, rate limit остаётся per-instance, а обновление connection не сериализуется между распределёнными экземплярами backend. Вендорные protobuf-контракты взяты из `references/moex-vibe`; при необходимости обновляйте их вручную по официальной документации T-Bank Invest API.