Files
frontend/src/entities/bank-card/api/mutations.ts
T
ksv741 f9f0f6921e
Frontend verify / commits (pull_request) Failing after 1m19s
Frontend verify / security (pull_request) Skipped
Frontend verify / verify (pull_request) Skipped
refactor: clarify frontend module ownership
2026-09-29 07:07:36 +03:00

163 lines
3.6 KiB
TypeScript

import { useMutation, useQueryClient } from "@tanstack/react-query";
import {
apiClient,
ApiErrorCode,
apiErrorCode,
isApiErrorCode,
} from "@/shared/api";
import type {
CreateBankCard,
CreateBankOperation,
CreateExpenseCategory,
UpdateBankCard,
UpdateBankOperation,
UpdateExpenseCategory,
} from "./types";
async function mutationData<T>(
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 useBankMutationOptions() {
const queryClient = useQueryClient();
const invalidate = () =>
queryClient.invalidateQueries({
predicate: ({ queryKey }) => {
const [method, path] = queryKey;
return (
method === "get"
&& typeof path === "string"
&& (path === "/api/v1/bank-cards"
|| path.startsWith("/api/v1/bank-cards/"))
);
},
});
return {
onError: (error: unknown) => {
const errorCode = apiErrorCode(error);
return [
ApiErrorCode.BankDependentRefunds,
ApiErrorCode.BankIntentConflict,
ApiErrorCode.BankRefundLimit,
ApiErrorCode.BankVersionConflict,
ApiErrorCode.BankWriteConflict,
].some(code => isApiErrorCode(errorCode, code))
? invalidate()
: undefined;
},
onSuccess: invalidate,
retry: false,
} as const;
}
function useCreateBankCard() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: (body: CreateBankCard) =>
mutationData(apiClient.POST("/api/v1/bank-cards", { body })),
});
}
function useCreateBankOperation() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: (body: CreateBankOperation) =>
mutationData(apiClient.POST("/api/v1/bank-cards/operations", { body })),
});
}
function useCreateExpenseCategory() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: (body: CreateExpenseCategory) =>
mutationData(apiClient.POST("/api/v1/bank-cards/categories", { body })),
});
}
function useDeleteBankOperation() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: ({ id, version }: { id: string; version: number }) =>
mutationData(
apiClient.DELETE("/api/v1/bank-cards/operations/{id}", {
params: { path: { id }, query: { version } },
}),
),
});
}
function useUpdateBankCard() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: ({ body, id }: { body: UpdateBankCard; id: string }) =>
mutationData(
apiClient.PATCH("/api/v1/bank-cards/{id}", {
body,
params: { path: { id } },
}),
),
});
}
function useUpdateBankOperation() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: ({ body, id }: { body: UpdateBankOperation; id: string }) =>
mutationData(
apiClient.PATCH("/api/v1/bank-cards/operations/{id}", {
body,
params: { path: { id } },
}),
),
});
}
function useUpdateExpenseCategory() {
const options = useBankMutationOptions();
return useMutation({
...options,
mutationFn: ({ body, id }: { body: UpdateExpenseCategory; id: string }) =>
mutationData(
apiClient.PATCH("/api/v1/bank-cards/categories/{id}", {
body,
params: { path: { id } },
}),
),
});
}
export {
useCreateBankCard,
useCreateBankOperation,
useCreateExpenseCategory,
useDeleteBankOperation,
useUpdateBankCard,
useUpdateBankOperation,
useUpdateExpenseCategory,
};