Во время деплоя backend остановлен, nginx отвечает 502. Любой неуспех POST /auth/refresh вызывал clearSession(): пользователь с валидной refresh-cookie уходил на login, кэш очищался.
Изменения
auth.vm.ts: refresh() очищает session только при ответе сервера без data и статусе ниже 500 (практически 401). Сетевая ошибка и 5xx выставляют unavailable, session и кэш остаются. Успешный refresh и clearSession сбрасывают unavailable. В контекст добавлен retry() (тот же single-flight refresh, нового loop нет).
client.ts: если refresh не удался из-за unavailable, shared client не вызывает clear() после исходного 401. Следующий 401 снова запускает refresh.
RouteGuards.tsx: вместо редиректа на /login при !user && unavailable показывается StateView с кнопкой «Повторить»; тексты в auth.* (ru).
.ai/conventions/data.md: правило «Auth и invalidation» дополнено этой политикой.
Retry/backoff внутри refresh не добавлялся (решение владельца задачи).
Проверки (Node 24.22.1)
Тесты на transport boundary (MSW): холодный старт с 401 очищает session; с сетевой ошибкой, 502 и 503 сохраняет кэш и ставит unavailable; retry() после сбоя восстанавливает session; protected 401 при недоступном refresh не очищает session; route-тест: retry-экран вместо login, затем возврат на маршрут; client-тест: clear не вызывается при unavailable.
Без правки в src восьми новых/изменённых тестов красные, с правкой зелёные.
npm run verify зелёный (467 тестов, depcruise, knip, build, storybook build). Падающие в этот момент на develop два теста AccountEventsPage.filters (зависимость от даты) исправлены отдельным PR к WealthLedger/frontend#98 и были подключены для прогона.
Влияние
Пользователь больше не теряет вход из-за кратковременной недоступности backend. После окончания простоя нужно нажать «Повторить» или перезагрузить страницу.
Порядок merge
Код #97 не зависит от #98, но зелёный CI verify на develop требует #98 (иначе падает дата-зависимый тест).
Closes #97
Связано с WealthLedger/backend#123 (refresh cookie без срока жизни, PR WealthLedger/backend#124)
## Проблема
Во время деплоя backend остановлен, nginx отвечает 502. Любой неуспех `POST /auth/refresh` вызывал `clearSession()`: пользователь с валидной refresh-cookie уходил на login, кэш очищался.
## Изменения
- `auth.vm.ts`: `refresh()` очищает session только при ответе сервера без `data` и статусе ниже 500 (практически 401). Сетевая ошибка и 5xx выставляют `unavailable`, session и кэш остаются. Успешный refresh и `clearSession` сбрасывают `unavailable`. В контекст добавлен `retry()` (тот же single-flight `refresh`, нового loop нет).
- `client.ts`: если refresh не удался из-за `unavailable`, shared client не вызывает `clear()` после исходного 401. Следующий 401 снова запускает refresh.
- `RouteGuards.tsx`: вместо редиректа на `/login` при `!user && unavailable` показывается `StateView` с кнопкой «Повторить»; тексты в `auth.*` (ru).
- `.ai/conventions/data.md`: правило «Auth и invalidation» дополнено этой политикой.
- Retry/backoff внутри refresh не добавлялся (решение владельца задачи).
## Проверки (Node 24.22.1)
- Тесты на transport boundary (MSW): холодный старт с 401 очищает session; с сетевой ошибкой, 502 и 503 сохраняет кэш и ставит `unavailable`; `retry()` после сбоя восстанавливает session; protected 401 при недоступном refresh не очищает session; route-тест: retry-экран вместо login, затем возврат на маршрут; client-тест: `clear` не вызывается при `unavailable`.
- Без правки в `src` восьми новых/изменённых тестов красные, с правкой зелёные.
- `npm run verify` зелёный (467 тестов, depcruise, knip, build, storybook build). Падающие в этот момент на `develop` два теста `AccountEventsPage.filters` (зависимость от даты) исправлены отдельным PR к WealthLedger/frontend#98 и были подключены для прогона.
## Влияние
Пользователь больше не теряет вход из-за кратковременной недоступности backend. После окончания простоя нужно нажать «Повторить» или перезагрузить страницу.
## Порядок merge
Код #97 не зависит от #98, но зелёный CI `verify` на `develop` требует #98 (иначе падает дата-зависимый тест).
A backend outage during deploy cleared the session and sent the user
to login although the refresh cookie was still valid. Only a definitive
401 ends the session now; network errors and 5xx keep it and show a
retry screen.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #97
Связано с WealthLedger/backend#123 (refresh cookie без срока жизни, PR WealthLedger/backend#124)
Проблема
Во время деплоя backend остановлен, nginx отвечает 502. Любой неуспех
POST /auth/refreshвызывалclearSession(): пользователь с валидной refresh-cookie уходил на login, кэш очищался.Изменения
auth.vm.ts:refresh()очищает session только при ответе сервера безdataи статусе ниже 500 (практически 401). Сетевая ошибка и 5xx выставляютunavailable, session и кэш остаются. Успешный refresh иclearSessionсбрасываютunavailable. В контекст добавленretry()(тот же single-flightrefresh, нового loop нет).client.ts: если refresh не удался из-заunavailable, shared client не вызываетclear()после исходного 401. Следующий 401 снова запускает refresh.RouteGuards.tsx: вместо редиректа на/loginпри!user && unavailableпоказываетсяStateViewс кнопкой «Повторить»; тексты вauth.*(ru)..ai/conventions/data.md: правило «Auth и invalidation» дополнено этой политикой.Проверки (Node 24.22.1)
unavailable;retry()после сбоя восстанавливает session; protected 401 при недоступном refresh не очищает session; route-тест: retry-экран вместо login, затем возврат на маршрут; client-тест:clearне вызывается приunavailable.srcвосьми новых/изменённых тестов красные, с правкой зелёные.npm run verifyзелёный (467 тестов, depcruise, knip, build, storybook build). Падающие в этот момент наdevelopдва тестаAccountEventsPage.filters(зависимость от даты) исправлены отдельным PR к WealthLedger/frontend#98 и были подключены для прогона.Влияние
Пользователь больше не теряет вход из-за кратковременной недоступности backend. После окончания простоя нужно нажать «Повторить» или перезагрузить страницу.
Порядок merge
Код #97 не зависит от #98, но зелёный CI
verifyнаdevelopтребует #98 (иначе падает дата-зависимый тест).d1a6e3d930tof5b8b16966fe91ddbb91tod4d5edecec