Some checks failed
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / changes (push) Successful in 7s
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Blocked by required conditions
Deploy Trade-In / build-browser (push) Blocked by required conditions
Deploy Trade-In / test (push) Blocked by required conditions
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Has been cancelled
На стойком 401/протухшей сессии фронт повторял /me + /trade-in/quota в бесконечном цикле (184+ запросов): errored query + дефолтный refetchOnMount=true → каждый новый observer (useMe дёргают RouteGuard, Topbar, UserMenu, useBrand) ре-фетчил при mount = re-subscribe storm. Глобально выключаем refetchOnMount/onReconnect в QueryClient + экспоненциальный retryDelay (cap 30s); те же гарды на useQuota. retry-предикат 4xx→false уже был. Graceful session-screen (RouteGuard/NoAccessScreen) уже на месте. Closes #800
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
"use client";
|
||
|
||
import { useQuery } from "@tanstack/react-query";
|
||
import { apiFetch } from "@/lib/api";
|
||
import type { QuotaStatus } from "@/types/trade-in";
|
||
|
||
const BASE = "/api/v1/trade-in";
|
||
|
||
/**
|
||
* GET /api/v1/trade-in/quota
|
||
* Fetches the monthly evaluation quota status for the current session/account.
|
||
* Fail-open: if the query errors, the UI must NOT block the user (treat as unlimited).
|
||
*
|
||
* #800: `retry:false` — на 401/протухшей сессии quota НЕ должна ре-стучаться в бэк.
|
||
* `refetchOnMount/Reconnect/WindowFocus:false` — иначе errored quota ре-фетчит на
|
||
* каждый ремаунт владельца → вклад в retry-storm. Освежается явным
|
||
* `invalidateQueries(["trade-in","quota"])` после успешной оценки (см. page.tsx).
|
||
*/
|
||
export function useQuota() {
|
||
return useQuery<QuotaStatus>({
|
||
queryKey: ["trade-in", "quota"],
|
||
queryFn: () => apiFetch<QuotaStatus>(`${BASE}/quota`),
|
||
staleTime: 30_000,
|
||
retry: false,
|
||
refetchOnMount: false,
|
||
refetchOnReconnect: false,
|
||
refetchOnWindowFocus: false,
|
||
});
|
||
}
|