Files
specs/openspec/specs/tbank-connection/spec.md
T
codex-bot f0478c6d6b
Specs security / security (push) Successful in 8s
Specs verify / verify (push) Successful in 10s
spec: archive quiet-user-feedback and sync canonical specs (#50)
Native archive применил 9 added и 12 modified требований без удалений; все 10 сценариев сохранены. Новый canonical spec frontend-user-feedback внесён в AI_INDEX.
2026-10-17 22:18:27 +03:00

13 KiB
Raw Blame History

tbank-connection Specification

Purpose

Позволяет авторизованному пользователю безопасно подключить T-Bank Invest для будущего получения только собственных инвестиционных данных через backend.

Requirements

Requirement: Статус подключения T-Bank

Система SHALL предоставлять авторизованному User GET /api/v1/tbank-connection, возвращающий состояние его единственного подключения в форме { connected, connectedAt }. При отсутствии подключения ответ MUST быть { connected: false, connectedAt: null }; при наличии подключения connectedAt MUST быть timestamp в RFC 3339 UTC. Получение статуса MUST NOT обращаться к T-Bank.

Scenario: Подключение отсутствует

  • WHEN авторизованный User запрашивает статус без сохранённого подключения
  • THEN система отвечает 200 с { connected: false, connectedAt: null }

Scenario: Подключение существует

  • WHEN авторизованный User запрашивает статус после успешного подключения
  • THEN система отвечает 200 с { connected: true, connectedAt: <RFC 3339 UTC timestamp> } без token

Requirement: Создание и замена подключения T-Bank

Система SHALL позволять авторизованному User создать или заменить единственное подключение через PUT /api/v1/tbank-connection с token. Система MUST удалить внешние пробелы token, отклонить пустое значение как ошибку валидации и проверить token запросом T-Bank открытых счетов до сохранения. Пустой список счетов MUST считаться успешной проверкой. Успех MUST вернуть 200 с текущим статусом подключения; успешная замена MUST установить новый connectedAt. После успешного подключения MUST начинаться первый часовой обход без команды frontend. История стоимости прежних счетов MUST сохраняться, но MUST быть доступна только для счетов, доступ к которым подтверждён новым подключением.

Scenario: Успешное создание подключения без счетов

  • WHEN User отправляет непустой token и T-Bank успешно возвращает пустой список открытых счетов
  • THEN система сохраняет подключение, отвечает 200 с { connected: true, connectedAt: <RFC 3339 UTC timestamp> } и не создаёт фиктивные счета

Scenario: Успешная замена подключения

  • WHEN User с подключением отправляет другой token и T-Bank успешно его проверяет
  • THEN система заменяет token, обновляет connectedAt, отвечает текущим статусом без token и начинает первый часовой обход нового подключения

Scenario: Невалидный token не заменяет существующее подключение

  • WHEN T-Bank отклоняет token как неаутентифицированный или не имеющий прав
  • THEN система отвечает 400 Problem Details с code INVALID_TBANK_TOKEN и сохраняет прежнее подключение без изменений

Scenario: T-Bank временно недоступен при проверке token

  • WHEN проверка token не завершается из-за временной или иной upstream-ошибки
  • THEN система отвечает 503 Problem Details с code TBANK_UNAVAILABLE и не создаёт либо не изменяет подключение

Requirement: Удаление подключения T-Bank

Система SHALL позволять авторизованному User удалить своё подключение через DELETE /api/v1/tbank-connection. Удаление MUST быть идемпотентным и отвечать 204; после успешного удаления backend MUST прекратить использовать удалённый token и сделать относящиеся к User текущие личные данные недоступными. История стоимости счёта MUST сохраняться, но MUST NOT раскрываться до подтверждения нового доступа к тому же счёту.

Scenario: Удаление существующего подключения

  • WHEN User удаляет существующее подключение
  • THEN система удаляет token, скрывает текущие личные данные и историю стоимости и отвечает 204

Scenario: Повторное удаление подключения

  • WHEN User удаляет уже отсутствующее подключение
  • THEN система отвечает 204, не раскрывая сохранённую историю

Requirement: Конфиденциальность token T-Bank

Система MUST хранить не более одного token T-Bank для каждого User только в зашифрованном виде. Token MUST расшифровываться только для серверного вызова T-Bank и MUST NOT передаваться в frontend, HTTP-ответах, OpenAPI examples, сообщениях ошибок или application logs.

Scenario: API не раскрывает token

  • WHEN User создаёт, заменяет, удаляет или получает статус подключения
  • THEN ни один HTTP-ответ не содержит token или его фрагмент

Requirement: Устойчивость проверки T-Bank

Система SHALL выполнять проверку token только через защищённое TLS-подключение к T-Bank. Все вызовы T-Bank MUST проходить через общий для экземпляра backend лимит, задаваемый конфигурацией и равный 5 запросам в секунду по умолчанию, с FIFO-очередью не более 50 ожидающих вызовов. Для временных ошибок система MUST выполнить не более одного повторного вызова; если проверка не завершается успешно, token MUST NOT сохраняться.

Scenario: Лимит ожидания upstream-вызовов исчерпан

  • WHEN 50 вызовов T-Bank уже ожидают общий лимитер
  • THEN следующий запрос не обращается к T-Bank и получает 503 Problem Details с code TBANK_UNAVAILABLE

Scenario: Временная ошибка успешно повторяется

  • WHEN первая проверка token завершается временной ошибкой, а единственный повтор завершается успешно
  • THEN система сохраняет подключение и отвечает текущим статусом

Requirement: Управление подключением в настройках

Клиент SHALL показывать в настройках статус T-Bank connection, текст о необходимости read-only T-Bank Invest token, поле token и действие подключения либо замены. Для существующего подключения клиент MUST показывать действие удаления с modal-подтверждением. Во время создания, замены или удаления все действия секции подключения и действия modal MUST быть отключены. После успешного создания или замены клиент MUST очистить поле token и обновить статус; при ошибке token MUST остаться в поле.

Временный сбой чтения статуса SHALL восстанавливаться автоматически без кнопки повтора и технического предупреждения. Пока первый статус неизвестен, клиент MUST NOT показывать форму как подтверждённое отсутствие подключения: после первичного ожидания SHALL отображаться нейтральная недоступность секции. Если статус уже известен для текущей сессии, временный сбой его фонового чтения MUST NOT скрывать доступную секцию или очищать ввод. Подтверждённое изменение сессии или доступа MUST NOT маскироваться старым статусом.

Ошибки создания, замены и удаления MUST оставаться локальными, сохранять ввод и возвращать применимые действия формы. Эти действия MUST NOT повторяться автоматически как чтение статуса. Подтверждения успеха SHALL следовать frontend-user-feedback: очевидное изменение статуса не требует дублирующего уведомления, неочевидный результат получает одно краткое подтверждение.

Scenario: Пользователь подтверждает удаление

  • WHEN User подтверждает удаление в modal
  • THEN клиент блокирует действия секции до результата и после успешного ответа показывает состояние без подключения

Scenario: Ошибка загрузки статуса

  • WHEN клиент временно не может получить статус подключения
  • THEN он автоматически восстанавливает чтение, сохраняет известный статус текущей сессии либо показывает нейтральную недоступность после первичного ожидания без формы и кнопки повтора

Scenario: Ошибка проверки token в клиенте

  • WHEN создание или замена получает INVALID_TBANK_TOKEN либо TBANK_UNAVAILABLE
  • THEN клиент показывает соответственно локализованное сообщение о token и правах либо о временной недоступности T-Bank в контексте формы, возвращает интерактивность и сохраняет введённый token

Scenario: Фоновое чтение не сбрасывает ввод

  • WHEN пользователь редактирует token в доступной секции, а фоновое чтение статуса временно не удалось
  • THEN ввод и доступная секция сохраняются без технического предупреждения или уведомления

Scenario: Удаление не удалось

  • WHEN пользователь подтвердил удаление подключения, а действие завершилось ошибкой
  • THEN клиент не показывает успех, сохраняет известный статус и локальную ошибку, возвращает применимые действия и не повторяет удаление автоматически