fix(tradein/ui): чистить TanStack Query cache при смене identity (#2567) #2651

Merged
bot-backend merged 1 commit from fix/tradein-clear-query-cache-identity into main 2026-08-05 10:06:32 +00:00
Collaborator

Summary

#2567: при смене пользователя в одной SPA-сессии инвалидировался только ME_QUERY_KEY — данные предыдущего аккаунта (team/employees, история оценок, квоты) оставались в кэше и могли отрендериться следующему до рефетча. Это и приватность между аккаунтами, и рассинхрон UI.

Три точки смены identity (найдены по коду, совпало с оценкой issue):

  • lib/useLogout.ts — логаут DB-сессии
  • app/login/page.tsx — успешный логин (другой пользователь без предварительного логаута в той же вкладке)
  • components/auth/GuardedRoute.tsx — 401-редирект (истёкшая/отозванная сессия)

Почему queryClient.clear(), а не точечный removeQueries: allowlist ключей пришлось бы синхронизировать с каждым новым запросом приложения — один промах и утечка возвращается. clear() — один вызов, рекомендованный самим TanStack для sign-out. In-flight запросы безопасны: удалённый Query при следующей подписке получает свежий инстанс, поздний ответ старого пользователя пишет в осиротевший объект. Активные наблюдатели рефетчатся — это и есть желаемое поведение; во всех трёх точках приложение одновременно навигирует, окна для «вспышки» устаревших данных нет.

Не тронуто осознанно: легаси lib/logout.ts (путь Caddy basic-auth, window.location.href — hard reload уничтожает весь JS-heap вместе с QueryClient, чистить нечего). Persist-слоя нет (QueryClient создаётся в providers.tsx без персистера) — переживания кэша через перезагрузку не бывает. Другого identity-состояния нет: zustand/Redux в проекте отсутствуют, lib/sessionId.ts — device-id для анонимного чата, не аккаунт.

Test plan

  • type-check / lint / build (20 роутов) чисто; тест-раннера во фронте нет — не выдумывал
  • Ручной сценарий: логин менеджером → «Команда» загрузилась → логаут → логин другим аккаунтом в той же вкладке без релоада → данных прошлой организации нет ни в UI, ни в кэше (React Query devtools). Повторить через истечение сессии (401-редирект).

Refs #2567

## Summary **#2567**: при смене пользователя в одной SPA-сессии инвалидировался только `ME_QUERY_KEY` — данные предыдущего аккаунта (team/employees, история оценок, квоты) оставались в кэше и могли отрендериться следующему до рефетча. Это и приватность между аккаунтами, и рассинхрон UI. **Три точки смены identity** (найдены по коду, совпало с оценкой issue): - `lib/useLogout.ts` — логаут DB-сессии - `app/login/page.tsx` — успешный логин (другой пользователь без предварительного логаута в той же вкладке) - `components/auth/GuardedRoute.tsx` — 401-редирект (истёкшая/отозванная сессия) **Почему `queryClient.clear()`, а не точечный `removeQueries`**: allowlist ключей пришлось бы синхронизировать с каждым новым запросом приложения — один промах и утечка возвращается. `clear()` — один вызов, рекомендованный самим TanStack для sign-out. In-flight запросы безопасны: удалённый `Query` при следующей подписке получает свежий инстанс, поздний ответ старого пользователя пишет в осиротевший объект. Активные наблюдатели рефетчатся — это и есть желаемое поведение; во всех трёх точках приложение одновременно навигирует, окна для «вспышки» устаревших данных нет. **Не тронуто осознанно**: легаси `lib/logout.ts` (путь Caddy basic-auth, `window.location.href` — hard reload уничтожает весь JS-heap вместе с QueryClient, чистить нечего). Persist-слоя нет (`QueryClient` создаётся в `providers.tsx` без персистера) — переживания кэша через перезагрузку не бывает. Другого identity-состояния нет: zustand/Redux в проекте отсутствуют, `lib/sessionId.ts` — device-id для анонимного чата, не аккаунт. ## Test plan - [x] type-check / lint / build (20 роутов) чисто; тест-раннера во фронте нет — не выдумывал - [ ] Ручной сценарий: логин менеджером → «Команда» загрузилась → логаут → логин другим аккаунтом в той же вкладке без релоада → данных прошлой организации нет ни в UI, ни в кэше (React Query devtools). Повторить через истечение сессии (401-редирект). Refs #2567
bot-backend added 1 commit 2026-08-05 10:04:07 +00:00
fix(tradein/ui): чистить TanStack Query cache при смене identity (#2567)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m1s
482b0be1fa
Логин, логаут и 401-редирект инвалидировали только ME_QUERY_KEY — данные
предыдущего пользователя (team/employees, история оценок, квоты) оставались
в кэше и могли отрендериться следующему в той же SPA-сессии до рефетча.
queryClient.clear() во всех трёх точках смены identity.

clear() вместо точечного removeQueries: allowlist ключей пришлось бы
синхронизировать с каждым новым запросом приложения, один промах — снова
утечка. In-flight запросы безопасны: удалённый Query получает новый
инстанс при следующей подписке, поздний ответ старого пользователя пишет
в осиротевший объект. Легаси basic-auth logout (hard reload) не тронут —
там весь JS-heap и так уничтожается. Persist-слоя у QueryClient нет.

Refs #2567
bot-backend merged commit 5162659277 into main 2026-08-05 10:06:32 +00:00
bot-backend deleted branch fix/tradein-clear-query-cache-identity 2026-08-05 10:06:32 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2651
No description provided.