Files
specs/openspec/changes/persist-tbank-data/specs/frontend-data-resilience/spec.md
T
ksv741 2f5814abdd
Conventional commits / commits (pull_request) Successful in 12s
Specs security / security (pull_request) Successful in 7s
Specs verify / verify (pull_request) Successful in 11s
Specs security / security (push) Successful in 7s
Specs verify / verify (push) Successful in 9s
spec: complete persist-tbank-data implementation
Record the approved proposal, delta specifications, design and 27 verified
implementation tasks. Keep the change active; archiving and main-spec synchronization
are deferred.
2026-09-26 21:29:24 +03:00

9.7 KiB
Raw Blame History

MODIFIED Requirements

Requirement: Client Cached Snapshot остаётся доступным при обновлении Accounts и Portfolio

Frontend MUST сохранять Client Cached Snapshot на всех экранах с данными T-Bank: список Brokerage Accounts, Portfolio, операции, доходы, инструменты, котировки, свечи и выплаты. Снимок MUST сохраняться для того же пользователя, текущего подключения и набора данных, если ранее получен успешный результат с непустым data. Подтверждённые data: [] или пустой полный Portfolio также MUST считаться успешным результатом. Начальная загрузка без такого ответа может показывать блокирующее состояние загрузки. Client Cached Snapshot MUST оставаться видимым во время фонового обновления и после его временной ошибки; он отличается от постоянно сохранённых серверных данных и MUST NOT изменять поле Portfolio.isStale. Клиент MUST независимо показывать свежесть серверного результата, полноту требуемых периодов, ход синхронизации и ошибку HTTP-refetch. Успешный HTTP-ответ с meta.sync.state: failed MUST NOT представляться успешным обновлением источника. Поля meta.lastSuccessfulAt, meta.availability, meta.freshness, meta.sync и при наличии meta.coverage MUST определять эти состояния по tbank-data-sync; клиент MUST NOT выводить их из возраста своего query-кэша. Ошибка ручного обновления ещё свежего источника MUST показываться отдельно от его свежести: клиент MUST NOT объявлять данные устаревшими до истечения серверного TTL либо изменять исходное успешное время.

Состояние data: null MUST показывать отсутствие загруженного результата и ход первичной загрузки либо её ошибку. Неполный период MUST явно отличаться от полного и MUST NOT представляться окончательным финансовым итогом или подтверждённым отсутствием операций. Неполное сравнение доходов MUST иметь собственное состояние и MUST NOT подменяться нулём. Статусы MUST быть доступны текстом, не только цветом; действия обновления и повтора MUST быть доступны с клавиатуры и сохранять читаемость на узком экране.

Действие «Обновить» MUST обходить серверную проверку давности для текущего экрана, его применённого периода и зависимостей, сохраняя доступные данные и фильтры. Обычное повторное получение HTTP-ответа MUST NOT считаться ручным принудительным обновлением. Наблюдение за уже запрошенной работой MUST прекращаться после её завершения, ошибки или ухода с экрана, MUST NOT запускать новую синхронизацию и MUST NOT создавать периодическое обновление источника. Уже начатая серверная работа MAY завершиться после ухода.

При подтверждённом TBANK_NOT_CONNECTED, INVALID_TBANK_TOKEN, недоступности счёта либо изменении пользователя/подключения frontend MUST скрыть личный Snapshot прежней границы. Поздние ответы данных и статусов прежнего подключения MUST NOT попадать в новое состояние; обычная временная ошибка MUST NOT менять эту границу.

Scenario: Список Brokerage Accounts обновляется в фоне

  • WHEN экран Accounts уже показывает Client Cached Snapshot и начинается фоновое обновление того же списка
  • THEN frontend оставляет список видимым и показывает только неблокирующий индикатор обновления

Scenario: Обновление Portfolio завершается ошибкой после успешного ответа

  • WHEN экран Brokerage Account уже показывает Client Cached Snapshot Portfolio, а последующее обновление этого же Portfolio завершается временной ошибкой
  • THEN frontend сохраняет Portfolio видимым, показывает локализованное неблокирующее предупреждение о показе последних полученных данных и предоставляет повторную попытку обновления

Scenario: Server-side fallback и client cached snapshot различаются

  • WHEN backend возвращает Portfolio с isStale либо фоновое обновление Client Cached Snapshot завершается временной ошибкой
  • THEN frontend отображает соответствующее server-side либо client-side предупреждение независимо, не представляя один вид состояния другим

Scenario: Серверная синхронизация не завершена после успешного HTTP-ответа

  • WHEN экран получает 200 с сохранёнными данными и meta.sync.state: running
  • THEN он показывает данные и прежнее успешное время вместе с состоянием обновления, не считая HTTP-успех завершением синхронизации

Scenario: Первичная загрузка без данных

  • WHEN любой экран T-Bank получает data: null с отсутствующим либо частичным покрытием
  • THEN он показывает загрузку либо её ошибку без вымышленных нулей, окончательных итогов и утверждения об отсутствии операций

Scenario: Ошибка синхронизации при успешном HTTP-ответе

  • WHEN экран получает 200 с сохранёнными данными, meta.sync.state: failed и безопасным кодом ошибки
  • THEN данные и время их успешного получения остаются видимыми с отдельным предупреждением об ошибке обновления и действием повтора

Scenario: Ошибка обновления не подменяет свежесть

  • WHEN экран получает ещё свежие данные с meta.freshness: fresh и meta.sync.state: failed после ручного обновления
  • THEN он показывает ошибку обновления и сохранённое успешное время без предупреждения об устаревших данных только из-за этой ошибки

Scenario: Ручное обновление сохраняет текущий контекст

  • WHEN User нажимает «Обновить» на экране с выбранным счётом, периодом и фильтрами
  • THEN клиент запрашивает принудительное обновление этого экрана и зависимостей, сохраняет контекст и доступные данные и не запрашивает обновление всей накопленной истории

Scenario: Недействительный token скрывает личный снимок

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

Scenario: Наблюдение не превращается в расписание

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