Files
frontend/src/entities/bank-card/api/mutations.ts
T
ksv741 851457e03c
Frontend security / security (push) Successful in 9s
Frontend verify / verify (push) Failing after 17m37s
Conventional commits / commits (pull_request) Successful in 26s
Frontend security / security (pull_request) Successful in 9s
Frontend verify / verify (pull_request) Failing after 22m42s
chore: add typed ESLint checks #18
Refs WealthLedger/main#18. Keep Biome; add no Prettier dependencies.
2026-09-28 05:52:29 +03:00

113 lines
2.9 KiB
TypeScript

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<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 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 };