f930f2fbcc
- /defter: önceki/sonraki/bu hafta, haftanın harcanan/bütçe toplamı - Form: tutar, 4 grup düğmesi, kategori ve ödeme türü seçimi, tarih, açıklama - Son seçimler bu cihazda hatırlanır; sunucu hataları ilgili alana düşer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
57 lines
2.5 KiB
TypeScript
57 lines
2.5 KiB
TypeScript
/**
|
||
* TanStack Query ayarları: sunucu verisinin önbelleği, yeniden deneme, yenileme.
|
||
*/
|
||
import { QueryCache, QueryClient } from '@tanstack/react-query'
|
||
import { ApiError } from './api'
|
||
|
||
/** Önbellek anahtarları tek yerde (yazım hatası olmasın) */
|
||
export const queryKeys = {
|
||
me: ['me'] as const,
|
||
registration: ['registration'] as const,
|
||
health: ['health'] as const,
|
||
household: ['household'] as const,
|
||
categories: (includeInactive = false) => ['categories', { includeInactive }] as const,
|
||
paymentMethods: (includeInactive = false) => ['payment-methods', { includeInactive }] as const,
|
||
/** Dönem listesi; `currentPeriod` da bu önekle başlar (birlikte yenilenir) */
|
||
periods: ['periods'] as const,
|
||
currentPeriod: ['periods', 'current'] as const,
|
||
/** Bir döneme bağlı tüm veriler bu önekle başlar → `invalidateQueries({ queryKey: period(id) })` */
|
||
period: (id: string) => ['period', id] as const,
|
||
planItems: (id: string) => ['period', id, 'plan-items'] as const,
|
||
summary: (id: string) => ['period', id, 'summary'] as const,
|
||
budget: (id: string) => ['period', id, 'budget'] as const,
|
||
suggestion: (id: string, method: string) => ['period', id, 'suggestion', method] as const,
|
||
notes: (id: string, context: string) => ['period', id, 'notes', context] as const,
|
||
/** Harcamalar; `range` verilmezse tüm dönem (`entries(id)` → tüm aralıkların öneki) */
|
||
entries: (id: string, range?: { from: string; to: string }) =>
|
||
range ? (['period', id, 'entries', range] as const) : (['period', id, 'entries'] as const),
|
||
}
|
||
|
||
/** 4xx hataları tekrar denemenin anlamı yok (yanlış istek / yetki); ağ ve 5xx için 2 kez dene. */
|
||
function shouldRetry(failureCount: number, error: unknown) {
|
||
if (error instanceof ApiError && error.status >= 400 && error.status < 500) return false
|
||
return failureCount < 2
|
||
}
|
||
|
||
export const queryClient = new QueryClient({
|
||
queryCache: new QueryCache({
|
||
onError: (error) => {
|
||
// Herhangi bir istek 401 alırsa oturum bitmiş demektir → "me" boşaltılır,
|
||
// korumalı sayfalar (Adım 4) kullanıcıyı giriş ekranına yönlendirir.
|
||
if (error instanceof ApiError && error.isUnauthorized) {
|
||
queryClient.setQueryData(queryKeys.me, null)
|
||
}
|
||
},
|
||
}),
|
||
defaultOptions: {
|
||
queries: {
|
||
retry: shouldRetry,
|
||
staleTime: 30_000, // 30 sn içinde aynı veri tekrar istenmez
|
||
refetchOnWindowFocus: true, // sekmeye dönünce güncel veri (ör. eşin eklediği harcama)
|
||
},
|
||
mutations: {
|
||
retry: false,
|
||
},
|
||
},
|
||
})
|