diff --git a/architecture/system-overview.md b/architecture/system-overview.md index 9c0b8a8..f918dcf 100644 --- a/architecture/system-overview.md +++ b/architecture/system-overview.md @@ -14,7 +14,9 @@ WealthLedger — локальное приложение для просмотр [Account Ledger](../features/brokerage-account-ledger.md) и [Future Cash Events](../features/brokerage-account-upcoming-events.md). - [Frontend UI resilience](../features/frontend-ui-resilience.md): явные - loading, error, empty и cached-snapshot состояния. + loading, error, empty и cached-snapshot состояния; initial и частичные + loading-состояния показывают structural skeleton, а уже доступный контекст + остаётся видимым при фоновом обновлении или действии пользователя. Термины этих возможностей определяет [глоссарий домена](domain-glossary.md), а причины ключевых технических решений — [ADR](../adr/README.md). diff --git a/features/authentication.md b/features/authentication.md index a4cb5b7..db6e2ca 100644 --- a/features/authentication.md +++ b/features/authentication.md @@ -4,7 +4,7 @@ Пользователь регистрируется или входит по email и паролю. Регистрация сразу создаёт первую сессию. Email сохраняется в нормализованном виде; пароль должен содержать от 12 до 72 UTF-8 байтов. -Access token живёт 15 минут только в памяти браузера. Refresh token живёт 7 дней в cookie `refresh_token` с `httpOnly` и `SameSite=Lax`; при восстановлении сессии он заменяется. После перезагрузки приложение восстанавливает access token через refresh-cookie до показа защищённых маршрутов. +Access token живёт 15 минут только в памяти браузера. Refresh token живёт 7 дней в cookie `refresh_token` с `httpOnly` и `SameSite=Lax`; при восстановлении сессии он заменяется. После перезагрузки приложение восстанавливает access token через refresh-cookie до показа защищённых маршрутов. Пока результат восстановления неизвестен, frontend показывает нейтральный structural skeleton каркаса без public или protected route content; после завершения bootstrap сохраняются прежние decisions и redirects. Все маршруты, кроме `/login` и `/register`, требуют сессию. После входа пользователь возвращается на исходный внутренний маршрут, если он был. Logout доступен в настройках, очищает локальную сессию независимо от состояния сети и отзывает серверную сессию при доступном refresh-cookie. diff --git a/features/brokerage-account-ledger.md b/features/brokerage-account-ledger.md index ee8d3c4..317878d 100644 --- a/features/brokerage-account-ledger.md +++ b/features/brokerage-account-ledger.md @@ -28,6 +28,11 @@ sequenceDiagram ## Поведение и ограничения +При первом открытии полного журнала frontend показывает structural skeleton +ожидаемых filters и rows вместо отдельного spinner. После появления response +filters и данные сохраняют существующую семантику; уже показанный контент не +заменяется skeleton во время pending action или фонового обновления. + - Запрашиваются только исполненные операции T-Bank. - Полный журнал фильтруется по периоду (два DateInput «С»/«По» с форматом DD.MM.YYYY и min/max-ограничением, русская локаль календаря) и категориям (MultiSelect с мультивыбором из trade, income, tax, fee, transfer, other). Фильтры имеют черновик в контролах и применённое состояние: изменение черновика не вызывает новый запрос к серверу; «Применить» коммитит черновик и сбрасывает cursor-пагинацию на первую страницу; «Сбросить» очищает черновик и немедленно применяет пустой фильтр (период по умолчанию и все категории). Cursor-пагинация («Назад»/«Далее») работает по последнему применённому фильтру, не по черновику. - В полном журнале и пяти последних записях обзора одна и та же компактная строка показывает логотип инструмента либо буквенный fallback, описание операции, дату, инструмент и денежное движение. Денежная метка строки показывает подпись конкретного типа события: для income-записи — «Купон» или «Дивиденд» (по upstream-типу купона или дивиденда), для остальных — подпись категории («Сделка», «Налог», «Комиссия», «Перевод», «Прочее»). Подпись типа выводится один раз и не повторяется во вторичной метадате (дата · инструмент); направление передаётся знаком «+» / «−` и семантическим цветом, а не текстом. Записи без движения денег остаются нейтральными («Без движения денег»). diff --git a/features/brokerage-account-upcoming-events.md b/features/brokerage-account-upcoming-events.md index 280cf9a..b3da1c5 100644 --- a/features/brokerage-account-upcoming-events.md +++ b/features/brokerage-account-upcoming-events.md @@ -26,6 +26,11 @@ sequenceDiagram ## Поведение и ограничения +При первом открытии полного списка frontend показывает structural skeleton +заголовка и event rows вместо отдельного spinner. Placeholder не представляет +данные и не является интерактивным; error и empty outcomes остаются отдельными +состояниями после завершения запроса. + - Период включает текущую календарную дату и следующие 30 дней. - Суммы до налогов рассчитываются по текущему количеству бумаг на `calculatedAt`; они не учитывают будущие сделки или владение на дату реестра. - Список не имеет фильтров, пагинации, конвертации валют и общего итога. diff --git a/features/brokerage-accounts.md b/features/brokerage-accounts.md index bcd9f1f..89b5bb9 100644 --- a/features/brokerage-accounts.md +++ b/features/brokerage-accounts.md @@ -56,6 +56,11 @@ sequenceDiagram ## Состояния +При первом запросе `/accounts` frontend показывает structural skeleton заголовка +и карточек, а не отдельный spinner; placeholder не содержит данных и не +участвует в keyboard focus. После успешного ответа либо ошибки используются +обычные нижеописанные состояния. + - `409 TBANK_NOT_CONNECTED`: список не запрашивается у T-Bank, экран ведёт в настройки. - `400 INVALID_TBANK_TOKEN`: сохранённый token не удаляется, экран ведёт в настройки для замены или удаления. - `503 TBANK_UNAVAILABLE`: экран предлагает повторить загрузку или открыть настройки. diff --git a/features/portfolio-view.md b/features/portfolio-view.md index 11cd279..a294036 100644 --- a/features/portfolio-view.md +++ b/features/portfolio-view.md @@ -45,6 +45,12 @@ Metadata инструмента ищется сначала по instrument UID, ## Свежесть и ошибки +При первом открытии Portfolio frontend показывает structural skeleton заголовка, +сводки и sections. На уже отрисованном обзоре Account independently loading +recent operations и future events заменяются skeleton только внутри своего +section; Portfolio и соседние sections остаются доступными. Skeleton placeholders +декоративны, не содержат пользовательских данных и не получают keyboard focus. + - Backend хранит успешный полный Snapshot для пары User и Brokerage Account свежим 30 секунд. - После истечения fresh TTL последний Snapshot можно вернуть как fallback не более пяти минут только при `TBANK_UNAVAILABLE`; такой ответ имеет `isStale: true` и исходный `lastSuccessfulAt`. - `INVALID_TBANK_TOKEN` никогда не маскируется fallback-данными.