feat: enhance transaction deletion process with optimistic updates, improved error handling, and restore previous data on failure

This commit is contained in:
Julien Froidefond
2025-12-08 08:52:47 +01:00
parent 4224c8aa83
commit 28baf9aa9e
4 changed files with 48 additions and 6 deletions

View File

@@ -123,8 +123,10 @@ export async function DELETE(request: Request) {
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error deleting transaction:", error);
const errorMessage =
error instanceof Error ? error.message : "Failed to delete transaction";
return NextResponse.json(
{ error: "Failed to delete transaction" },
{ error: errorMessage },
{ status: 500 },
);
}

View File

@@ -1,5 +1,6 @@
@import "tailwindcss";
@import "tw-animate-css";
@import "react-day-picker/style.css";
@custom-variant dark (&:is(.dark *));

View File

@@ -480,6 +480,23 @@ export default function TransactionsPage() {
newSelected.delete(transactionId);
setSelectedTransactions(newSelected);
// Sauvegarder les données actuelles pour pouvoir les restaurer en cas d'erreur
const queryKey = getTransactionsQueryKey(transactionParams);
const previousData =
queryClient.getQueryData<typeof transactionsData>(queryKey);
// Mise à jour optimiste du cache
queryClient.setQueryData<typeof transactionsData>(queryKey, (oldData) => {
if (!oldData) return oldData;
return {
...oldData,
transactions: oldData.transactions.filter(
(t) => t.id !== transactionId
),
total: oldData.total - 1,
};
});
try {
const response = await fetch(
`/api/banking/transactions?id=${transactionId}`,
@@ -487,10 +504,25 @@ export default function TransactionsPage() {
method: "DELETE",
}
);
if (!response.ok) throw new Error("Failed to delete transaction");
invalidateTransactions();
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(
errorData.error || `Failed to delete transaction: ${response.status}`
);
}
// Ne pas invalider immédiatement - la mise à jour optimiste est déjà correcte
// On invalide seulement les autres queries qui pourraient être affectées (métadonnées, stats)
queryClient.invalidateQueries({ queryKey: ["banking-metadata"] });
} catch (error) {
console.error("Failed to delete transaction:", error);
// Restaurer les données précédentes en cas d'erreur
if (previousData) {
queryClient.setQueryData(queryKey, previousData);
}
// Invalider pour récupérer les données correctes du serveur
invalidateTransactions();
}
};

View File

@@ -119,9 +119,16 @@ export const transactionService = {
},
async delete(id: string): Promise<void> {
try {
await prisma.transaction.delete({
where: { id },
});
} catch (error: any) {
if (error.code === "P2025") {
throw new Error(`Transaction with id ${id} not found`);
}
throw error;
}
},
async deduplicate(): Promise<{