169 lines
19 KiB
Markdown
169 lines
19 KiB
Markdown
# frontend-data-resilience Specification
|
|
|
|
## Purpose
|
|
|
|
Определяет, когда frontend сохраняет последний успешный ответ на экране и как
|
|
сообщает пользователю о неудачном фоновом обновлении без искажения доменных
|
|
состояний Portfolio.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Client Cached Snapshot остаётся доступным при обновлении Accounts и Portfolio
|
|
|
|
Frontend MUST сохранять последний успешный результат списка Brokerage Accounts,
|
|
Portfolio и других экранов чтения при фоновом обновлении и временной ошибке
|
|
для того же пользователя, подключения и набора данных. Подтверждённый пустой
|
|
результат MUST также считаться успешным. Смена счёта, инструмента, поискового
|
|
запроса, страницы или применённого периода MUST NOT представлять данные прежней
|
|
выборки как результат новой.
|
|
|
|
Доступный результат MUST оставаться видимым без индикаторов фонового чтения
|
|
клиента, технических предупреждений об этом чтении и действий ручного повтора,
|
|
пока автоматические повторы не исчерпаны; после их исчерпания применяется
|
|
требование «Временные сбои чтения восстанавливаются автоматически».
|
|
Frontend MUST NOT подменять внутренние признаки свежести и полноты, успешное
|
|
время источника или ошибку обновления только ради отсутствия их отображения.
|
|
Client Cached Snapshot MUST оставаться отличным от server-side fallback;
|
|
ошибка чтения MUST NOT изменять `Portfolio.isStale`.
|
|
|
|
Состояние источника из `meta` — время последнего успешного результата, признак
|
|
устаревания, исход последней часовой попытки и неполнота — MUST представляться
|
|
текстом либо доступно именованным элементом, а не только цветом, и MUST
|
|
различать отсутствие попытки, выполнение, полный успех, частичный успех и
|
|
неуспех. Это состояние принадлежит источнику данных, а не собственному чтению
|
|
клиента, и MUST NOT требовать от пользователя действия.
|
|
|
|
Обновление MUST сохранять выбранные фильтры, период, открытые разделы, ввод,
|
|
фокус и положение просмотра, пока соответствующее содержимое существует.
|
|
При logout, смене подключения или подтверждённом отказе доступа личные данные
|
|
прежней границы MUST перестать отображаться; поздний результат прежней загрузки
|
|
MUST NOT возвращать их на экран.
|
|
|
|
#### Scenario: Список Brokerage Accounts обновляется в фоне
|
|
- **WHEN** экран Accounts уже показывает Client Cached Snapshot и начинается фоновое обновление того же списка
|
|
- **THEN** frontend оставляет список видимым без индикации собственного чтения и технических действий
|
|
|
|
#### Scenario: Resource сохраняется после неуспешной часовой попытки
|
|
- **WHEN** response содержит полный `data` и `meta`, обозначающий неуспех последней часовой попытки
|
|
- **THEN** frontend сохраняет `data` и его исходное время видимыми и отдельно обозначает неуспех попытки, не предлагая запуск повторного получения данных из источника
|
|
|
|
#### 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 сохраняет доступные данные без технических сообщений и не подменяет один внутренний вид состояния другим
|
|
|
|
#### Scenario: Подтверждённая пустота переживает фоновую ошибку
|
|
- **WHEN** текущая выборка ранее успешно вернула полный пустой результат, а её обновление временно не удалось
|
|
- **THEN** подтверждённое пустое состояние сохраняется без предупреждения и не заменяется первичной загрузкой
|
|
|
|
#### Scenario: Изменились параметры выборки
|
|
- **WHEN** пользователь применил другой период или открыл другой счёт, а данных новой выборки ещё нет
|
|
- **THEN** экран показывает ожидание или недоступность новой выборки и не подписывает прежние суммы новым периодом или счётом
|
|
|
|
#### Scenario: Обновление не сбрасывает работу пользователя
|
|
- **WHEN** пользователь раскрыл раздел, выбрал фильтры или вводит данные, а фоновое чтение завершилось
|
|
- **THEN** обновление не сбрасывает эти действия, не переносит фокус и не возвращает пользователя в начало сохранившегося содержимого
|
|
|
|
#### Scenario: Изменился доступ к личным данным
|
|
- **WHEN** пользователь вышел, успешно сменил подключение либо получил подтверждённый отказ доступа к текущим данным
|
|
- **THEN** прежние личные данные скрываются, а позднее завершение старой загрузки не восстанавливает их
|
|
|
|
### Requirement: Временные сбои чтения восстанавливаются автоматически
|
|
|
|
Frontend SHALL автоматически повторять временно неуспешное чтение и восстанавливать
|
|
получение необходимых текущему экрану данных без ручного обновления. Повторы
|
|
одной попытки MUST иметь конечный предел и паузы, исключающие непрерывную
|
|
череду запросов. При исчерпании предела доступные данные SHALL сохраняться,
|
|
а при их отсутствии SHALL показываться локальная недоступность. На экранах
|
|
Account, Accounts, Income, Operations, Events и секций деталей инструмента при исчерпании предела
|
|
frontend SHALL дополнительно показывать неблокирующее локализованное предупреждение
|
|
о неудачном обновлении и действие «Повторить» рядом с затронутым результатом либо
|
|
локальной недоступностью. Действие MUST повторять только чтение (GET) затронутого
|
|
запроса, не запускать получение данных из источника и не менять выбранные
|
|
фильтры, период, открытые разделы и ввод; успешное чтение MUST снимать
|
|
предупреждение и MUST NOT сообщать об успехе. Предупреждение MUST NOT дублировать
|
|
состояние источника из `meta` и MUST NOT изменять `Portfolio.isStale`. На остальных
|
|
экранах чтения, включая поиск, диапазон графика, карты и настройки подключения,
|
|
предупреждение и действие повтора MUST NOT показываться. Возвращение сети,
|
|
возвращение пользователя к открытому экрану и повторное открытие экрана MUST
|
|
возобновлять получение отсутствующих или требующих обновления данных без
|
|
перезагрузки страницы. Свежий полный результат MUST NOT требовать обращения
|
|
к источнику только из-за такого события.
|
|
|
|
Восстановление MUST учитывать сбой чтения результата и сбой самого получения
|
|
данных из источника, даже если чтение состояния завершилось успешно. Наблюдение
|
|
уже выполняющейся работы MUST NOT запускать её повторно. Уход с экрана MUST
|
|
прекращать новые попытки его восстановления; это не требует отменять уже начатую
|
|
работу источника. Автоматическое восстановление MUST NOT повторять запросы,
|
|
требующие исправления ввода, входа или восстановления доступа, и MUST NOT
|
|
переносить старые параметры в новую пользовательскую выборку.
|
|
|
|
#### Scenario: Кратковременный сбой чтения
|
|
- **WHEN** чтение текущей выборки временно не удалось, а следующая разрешённая автоматическая попытка успешна
|
|
- **THEN** экран самостоятельно показывает результат без ручного действия и без сообщения о сбое или восстановлении
|
|
|
|
#### Scenario: Источник завершил работу ошибкой
|
|
- **WHEN** чтение сохранённых данных успешно, но получение необходимых новых данных из источника временно не удалось
|
|
- **THEN** приложение применяет ограниченное автоматическое восстановление к неуспешной работе, а не считает успешное чтение доказательством её успеха
|
|
|
|
#### Scenario: Повторы исчерпаны
|
|
- **WHEN** временная недоступность сохраняется после конечного предела автоматических попыток
|
|
- **THEN** приложение прекращает серию повторов, сохраняет доступный результат либо локальную недоступность без бесконечной загрузки и ожидает следующего события восстановления
|
|
|
|
#### Scenario: Повторы исчерпаны при сохранённом результате
|
|
- **WHEN** на экране Account, Accounts, Income, Operations, Events либо в секции деталей инструмента автоматические повторы исчерпаны, а ранее полученный результат остаётся доступным
|
|
- **THEN** результат и его исходное состояние источника остаются видимыми, рядом показываются неблокирующее предупреждение о неудачном обновлении и действие «Повторить», а активация действия повторяет только чтение затронутого запроса и после успеха снимает предупреждение
|
|
|
|
#### Scenario: Повторы исчерпаны без результата
|
|
- **WHEN** на тех же экранах автоматические повторы исчерпаны, а результата выборки нет
|
|
- **THEN** локальная недоступность содержит действие «Повторить», повторяющее только чтение затронутого запроса, и результат одной секции деталей не блокирует восстановление остальных
|
|
|
|
#### Scenario: Поиск, график и карты остаются тихими
|
|
- **WHEN** автоматические повторы исчерпаны при чтении результата поиска, диапазона графика, карт либо настроек подключения
|
|
- **THEN** приложение не показывает предупреждение и действие повтора и сохраняет прежнее локальное поведение
|
|
|
|
#### Scenario: Сеть или пользователь вернулись
|
|
- **WHEN** после временного сбоя восстановилась сеть либо пользователь вернулся к экрану с отсутствующим или требующим обновления результатом
|
|
- **THEN** получение данных возобновляется автоматически для текущей выборки и при успехе заменяет состояние недоступности содержимым
|
|
|
|
#### Scenario: Несколько событий восстановления совпали
|
|
- **WHEN** сеть восстановилась одновременно с возвращением пользователя на экран
|
|
- **THEN** приложение не запускает дублирующую работу получения одного набора данных
|
|
|
|
#### Scenario: Работа источника ещё выполняется
|
|
- **WHEN** приложение восстанавливает чтение состояния уже выполняющейся работы
|
|
- **THEN** оно продолжает получение её результата без повторного запуска той же работы
|
|
|
|
#### Scenario: Пользователь покинул экран
|
|
- **WHEN** пользователь ушёл со страницы с ожидающим восстановлением
|
|
- **THEN** новые попытки для покинутого экрана прекращаются, а уже начатая работа не изменяет содержимое другой выборки
|
|
|
|
#### Scenario: Ошибка требует действия пользователя
|
|
- **WHEN** подтверждены недействительное подключение, отсутствие доступа или некорректный ввод
|
|
- **THEN** автоматическая серия повторов прекращается и появляется соответствующее действие или локальная ошибка без технической кнопки повторной загрузки
|
|
|
|
### Requirement: Неполный результат не выдаётся за окончательный
|
|
|
|
Frontend MUST различать неизвестный результат, доступную часть данных и
|
|
подтверждённую пустоту. Неполные суммы и сравнения MUST NOT показываться как
|
|
окончательные или заменяться нулями. Доступные записи MAY оставаться видимыми,
|
|
но их список MUST NOT представляться полным при неподтверждённой полноте.
|
|
Состояние SHALL относиться к содержимому конкретной области, например
|
|
недоступному итогу, без отчёта о прогрессе синхронизации. Готовая область MUST
|
|
NOT ждать догрузки истории, которая не влияет на её результат.
|
|
|
|
#### Scenario: Итог ещё не определён
|
|
- **WHEN** часть данных, необходимых для суммы или сравнения, отсутствует
|
|
- **THEN** соответствующее значение обозначается как недоступное без вымышленного нуля или окончательного частичного итога
|
|
|
|
#### Scenario: Пустота ещё не подтверждена
|
|
- **WHEN** записи не получены и полнота выбранного периода неизвестна
|
|
- **THEN** экран не сообщает об отсутствии операций или выплат за этот период
|
|
|
|
#### Scenario: Период готов раньше остальной истории
|
|
- **WHEN** данные показанного периода полны, а не влияющая на него история ещё загружается
|
|
- **THEN** пользователь видит готовый результат без сообщения о догрузке остальной истории
|