import { useMutation, useQueryClient } from "@tanstack/react-query"; import { apiClient, apiErrorCode } from "@/shared/api"; import type { CreateBankCard, CreateBankOperation, CreateExpenseCategory, UpdateBankCard, UpdateBankOperation, UpdateExpenseCategory, } from "./queries"; async function mutationData( request: Promise<{ data?: T; error?: unknown }>, ) { const { data, error } = await request; // eslint-disable-next-line @typescript-eslint/only-throw-error -- Preserve generated ProblemDetails for apiErrorCode and field-error consumers. if (error) throw error; return data; } function useBankMutations() { const queryClient = useQueryClient(); const invalidate = () => queryClient.invalidateQueries({ predicate: ({ queryKey: [method, path] }) => method === "get" && typeof path === "string" && (path === "/api/v1/bank-cards" || path.startsWith("/api/v1/bank-cards/")), }); const options = { retry: false, onSuccess: invalidate, onError: (error: unknown) => { if ( [ "BANK_VERSION_CONFLICT", "BANK_WRITE_CONFLICT", "BANK_INTENT_CONFLICT", "BANK_REFUND_LIMIT", "BANK_DEPENDENT_REFUNDS", ].includes(apiErrorCode(error) ?? "") ) return invalidate(); }, } as const; const createCard = useMutation({ ...options, mutationFn: (body: CreateBankCard) => mutationData(apiClient.POST("/api/v1/bank-cards", { body })), }); const updateCard = useMutation({ ...options, mutationFn: ({ id, body }: { id: string; body: UpdateBankCard }) => mutationData( apiClient.PATCH("/api/v1/bank-cards/{id}", { params: { path: { id } }, body, }), ), }); const createOperation = useMutation({ ...options, mutationFn: (body: CreateBankOperation) => mutationData(apiClient.POST("/api/v1/bank-cards/operations", { body })), }); const updateOperation = useMutation({ ...options, mutationFn: ({ id, body }: { id: string; body: UpdateBankOperation }) => mutationData( apiClient.PATCH("/api/v1/bank-cards/operations/{id}", { params: { path: { id } }, body, }), ), }); const deleteOperation = useMutation({ ...options, mutationFn: ({ id, version }: { id: string; version: number }) => mutationData( apiClient.DELETE("/api/v1/bank-cards/operations/{id}", { params: { path: { id }, query: { version } }, }), ), }); const createCategory = useMutation({ ...options, mutationFn: (body: CreateExpenseCategory) => mutationData(apiClient.POST("/api/v1/bank-cards/categories", { body })), }); const updateCategory = useMutation({ ...options, mutationFn: ({ id, body }: { id: string; body: UpdateExpenseCategory }) => mutationData( apiClient.PATCH("/api/v1/bank-cards/categories/{id}", { params: { path: { id } }, body, }), ), }); return { createCard, updateCard, createOperation, updateOperation, deleteOperation, createCategory, updateCategory, }; } export { useBankMutations };