import { useDataSource } from "@erp/core/hooks"; import { UniqueID, ValidationErrorCollection } from "@repo/rdx-ddd"; import { DefaultError, useMutation, useQueryClient } from "@tanstack/react-query"; import { ZodError } from "zod/v4"; import { CreateCustomerRequestSchema } from "../../common"; import { Customer, CustomerFormData } from "../schemas"; import { CUSTOMERS_LIST_KEY, invalidateCustomerListCache } from "./use-customer-list-query"; import { getCustomerQueryKey } from "./use-customer-query"; export const CUSTOMER_CREATE_KEY = ["customers", "create"] as const; type CreateCustomerPayload = { data: CustomerFormData; }; // Helpers de validación a errores de dominio export function toValidationErrors(error: ZodError) { return error.issues.map((err) => ({ field: err.path.join("."), message: err.message, })); } export function useCreateCustomer() { const queryClient = useQueryClient(); const dataSource = useDataSource(); const schema = CreateCustomerRequestSchema; return useMutation({ mutationKey: CUSTOMER_CREATE_KEY, mutationFn: async (data) => { const id = UniqueID.generateNewID().toString(); const payload = { ...data, id }; console.log("payload => ", payload); const result = schema.safeParse(payload); result.error; if (!result.success) { const errorDetails = toValidationErrors(result.error); console.log(errorDetails); throw new ValidationErrorCollection("Validation failed", errorDetails); } const created = await dataSource.createOne("customers", payload); return created as Customer; }, onSuccess: (created) => { // Invalida el listado para refrescar desde servidor invalidateCustomerListCache(queryClient); // Sincroniza detalle queryClient.setQueryData(getCustomerQueryKey(created.id), created); }, onSettled: () => { // Refresca todos los listados invalidateCustomerListCache(queryClient); }, onMutate: async ({ data }) => { // Cancelar queries del listado para evitar overwrite await queryClient.cancelQueries({ queryKey: [CUSTOMERS_LIST_KEY] }); const optimisticId = UniqueID.generateNewID().toString(); const optimisticCustomer: Customer = { ...data, id: optimisticId } as Customer; // Snapshot previo const previous = queryClient.getQueryData([CUSTOMERS_LIST_KEY]); // Optimista: prepend queryClient.setQueryData([CUSTOMERS_LIST_KEY], (old) => [ optimisticCustomer, ...(old ?? []), ]); return { previous, optimisticId }; }, }); }