refactor: enhance cache invalidation logic across banking API routes and components for improved data consistency and performance
This commit is contained in:
@@ -5,17 +5,16 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
import type { Transaction } from "@/lib/types";
|
||||
import { getTransactionsQueryKey } from "@/lib/hooks";
|
||||
import type { TransactionsPaginatedParams } from "@/services/banking.service";
|
||||
import { invalidateAllTransactionQueries } from "@/lib/cache-utils";
|
||||
|
||||
interface UseTransactionMutationsProps {
|
||||
transactionParams: TransactionsPaginatedParams;
|
||||
transactionsData: { transactions: Transaction[]; total: number } | undefined;
|
||||
invalidateTransactions: () => void;
|
||||
}
|
||||
|
||||
export function useTransactionMutations({
|
||||
transactionParams,
|
||||
transactionsData,
|
||||
invalidateTransactions,
|
||||
}: UseTransactionMutationsProps) {
|
||||
const queryClient = useQueryClient();
|
||||
const [updatingTransactionIds, setUpdatingTransactionIds] = useState<
|
||||
@@ -64,21 +63,19 @@ export function useTransactionMutations({
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// TOUJOURS revalider après succès pour garantir la cohérence
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} catch (error) {
|
||||
console.error("Failed to update transaction:", error);
|
||||
// Rollback on error
|
||||
if (previousData) {
|
||||
queryClient.setQueryData(queryKey, previousData);
|
||||
}
|
||||
invalidateTransactions();
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
}
|
||||
},
|
||||
[
|
||||
transactionsData,
|
||||
transactionParams,
|
||||
queryClient,
|
||||
invalidateTransactions,
|
||||
]
|
||||
[transactionsData, transactionParams, queryClient]
|
||||
);
|
||||
|
||||
const markReconciled = useCallback(
|
||||
@@ -120,21 +117,19 @@ export function useTransactionMutations({
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// TOUJOURS revalider après succès pour garantir la cohérence
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} catch (error) {
|
||||
console.error("Failed to update transaction:", error);
|
||||
// Rollback on error
|
||||
if (previousData) {
|
||||
queryClient.setQueryData(queryKey, previousData);
|
||||
}
|
||||
invalidateTransactions();
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
}
|
||||
},
|
||||
[
|
||||
transactionsData,
|
||||
transactionParams,
|
||||
queryClient,
|
||||
invalidateTransactions,
|
||||
]
|
||||
[transactionsData, transactionParams, queryClient]
|
||||
);
|
||||
|
||||
const setCategory = useCallback(
|
||||
@@ -148,6 +143,22 @@ export function useTransactionMutations({
|
||||
|
||||
setUpdatingTransactionIds((prev) => new Set(prev).add(transactionId));
|
||||
|
||||
// Optimistic cache update
|
||||
const queryKey = getTransactionsQueryKey(transactionParams);
|
||||
const previousData =
|
||||
queryClient.getQueryData<typeof transactionsData>(queryKey);
|
||||
|
||||
queryClient.setQueryData<typeof transactionsData>(queryKey, (oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
|
||||
return {
|
||||
...oldData,
|
||||
transactions: oldData.transactions.map((t) =>
|
||||
t.id === transactionId ? { ...t, categoryId } : t
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/banking/transactions", {
|
||||
method: "PUT",
|
||||
@@ -159,21 +170,15 @@ export function useTransactionMutations({
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// Optimistic cache update
|
||||
const queryKey = getTransactionsQueryKey(transactionParams);
|
||||
queryClient.setQueryData<typeof transactionsData>(queryKey, (oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
|
||||
return {
|
||||
...oldData,
|
||||
transactions: oldData.transactions.map((t) =>
|
||||
t.id === transactionId ? { ...t, categoryId } : t
|
||||
),
|
||||
};
|
||||
});
|
||||
// TOUJOURS revalider après succès pour garantir la cohérence
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} catch (error) {
|
||||
console.error("Failed to update transaction:", error);
|
||||
invalidateTransactions();
|
||||
// Rollback on error
|
||||
if (previousData) {
|
||||
queryClient.setQueryData(queryKey, previousData);
|
||||
}
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} finally {
|
||||
setUpdatingTransactionIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
@@ -182,7 +187,7 @@ export function useTransactionMutations({
|
||||
});
|
||||
}
|
||||
},
|
||||
[transactionsData, transactionParams, queryClient, invalidateTransactions]
|
||||
[transactionsData, transactionParams, queryClient]
|
||||
);
|
||||
|
||||
const deleteTransaction = useCallback(
|
||||
@@ -217,22 +222,23 @@ export function useTransactionMutations({
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(
|
||||
errorData.error || `Failed to delete transaction: ${response.status}`
|
||||
errorData.error ||
|
||||
`Failed to delete transaction: ${response.status}`
|
||||
);
|
||||
}
|
||||
|
||||
// Invalidate related queries
|
||||
queryClient.invalidateQueries({ queryKey: ["banking-metadata"] });
|
||||
// TOUJOURS revalider après succès pour garantir la cohérence
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} catch (error) {
|
||||
console.error("Failed to delete transaction:", error);
|
||||
// Rollback on error
|
||||
if (previousData) {
|
||||
queryClient.setQueryData(queryKey, previousData);
|
||||
}
|
||||
invalidateTransactions();
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
}
|
||||
},
|
||||
[transactionsData, transactionParams, queryClient, invalidateTransactions]
|
||||
[transactionsData, transactionParams, queryClient]
|
||||
);
|
||||
|
||||
const bulkReconcile = useCallback(
|
||||
@@ -272,21 +278,19 @@ export function useTransactionMutations({
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
// TOUJOURS revalider après succès pour garantir la cohérence
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} catch (error) {
|
||||
console.error("Failed to update transactions:", error);
|
||||
// Rollback on error
|
||||
if (previousData) {
|
||||
queryClient.setQueryData(queryKey, previousData);
|
||||
}
|
||||
invalidateTransactions();
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
}
|
||||
},
|
||||
[
|
||||
transactionsData,
|
||||
transactionParams,
|
||||
queryClient,
|
||||
invalidateTransactions,
|
||||
]
|
||||
[transactionsData, transactionParams, queryClient]
|
||||
);
|
||||
|
||||
const bulkSetCategory = useCallback(
|
||||
@@ -304,6 +308,21 @@ export function useTransactionMutations({
|
||||
return next;
|
||||
});
|
||||
|
||||
// Optimistic cache update
|
||||
const queryKey = getTransactionsQueryKey(transactionParams);
|
||||
const previousData =
|
||||
queryClient.getQueryData<typeof transactionsData>(queryKey);
|
||||
|
||||
queryClient.setQueryData<typeof transactionsData>(queryKey, (oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
return {
|
||||
...oldData,
|
||||
transactions: oldData.transactions.map((t) =>
|
||||
transactionIds.includes(t.id) ? { ...t, categoryId } : t
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
try {
|
||||
await Promise.all(
|
||||
transactionsToUpdate.map((t) =>
|
||||
@@ -315,20 +334,15 @@ export function useTransactionMutations({
|
||||
)
|
||||
);
|
||||
|
||||
// Optimistic cache update
|
||||
const queryKey = getTransactionsQueryKey(transactionParams);
|
||||
queryClient.setQueryData<typeof transactionsData>(queryKey, (oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
return {
|
||||
...oldData,
|
||||
transactions: oldData.transactions.map((t) =>
|
||||
transactionIds.includes(t.id) ? { ...t, categoryId } : t
|
||||
),
|
||||
};
|
||||
});
|
||||
// TOUJOURS revalider après succès pour garantir la cohérence
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} catch (error) {
|
||||
console.error("Failed to update transactions:", error);
|
||||
invalidateTransactions();
|
||||
// Rollback on error
|
||||
if (previousData) {
|
||||
queryClient.setQueryData(queryKey, previousData);
|
||||
}
|
||||
invalidateAllTransactionQueries(queryClient);
|
||||
} finally {
|
||||
setUpdatingTransactionIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
@@ -337,7 +351,7 @@ export function useTransactionMutations({
|
||||
});
|
||||
}
|
||||
},
|
||||
[transactionsData, transactionParams, queryClient, invalidateTransactions]
|
||||
[transactionsData, transactionParams, queryClient]
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -350,4 +364,3 @@ export function useTransactionMutations({
|
||||
updatingTransactionIds,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user