refactor(categories): move mutations into use cases
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import { Prisma } from "@/generated/prisma/client"
|
||||
import prisma from "@/lib/prisma"
|
||||
import type {
|
||||
CreateCategoryFormType,
|
||||
UpdateCategoryFormType,
|
||||
} from "@/schemas/category.schema"
|
||||
import { CategoryService } from "@/services/category.service"
|
||||
|
||||
type FieldErrors = Record<string, string[]>
|
||||
|
||||
type CategoryUseCaseResult =
|
||||
| {
|
||||
success: true
|
||||
}
|
||||
| {
|
||||
success: false
|
||||
errors: FieldErrors
|
||||
}
|
||||
|
||||
function categoryError(errors: FieldErrors): CategoryUseCaseResult {
|
||||
return {
|
||||
success: false,
|
||||
errors,
|
||||
}
|
||||
}
|
||||
|
||||
function isUniqueConstraintError(error: unknown) {
|
||||
return (
|
||||
error instanceof Prisma.PrismaClientKnownRequestError &&
|
||||
error.code === "P2002"
|
||||
)
|
||||
}
|
||||
|
||||
export async function createCategoryUseCase(
|
||||
input: CreateCategoryFormType,
|
||||
): Promise<CategoryUseCaseResult> {
|
||||
try {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
const existingCategory = await CategoryService.findByName(input.name, tx)
|
||||
|
||||
if (existingCategory) {
|
||||
return categoryError({ name: ["Category already exists"] })
|
||||
}
|
||||
|
||||
await CategoryService.create(input, tx)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
if (isUniqueConstraintError(error)) {
|
||||
return categoryError({ name: ["Category already exists"] })
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateCategoryUseCase(
|
||||
input: UpdateCategoryFormType,
|
||||
): Promise<CategoryUseCaseResult> {
|
||||
const { id, name } = input
|
||||
|
||||
try {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
const existingCategory = await CategoryService.findById(id, tx)
|
||||
|
||||
if (!existingCategory) {
|
||||
return categoryError({ id: ["Category not found"] })
|
||||
}
|
||||
|
||||
if (existingCategory.name === name) {
|
||||
return categoryError({
|
||||
name: ["Category name is the same as the old one"],
|
||||
})
|
||||
}
|
||||
|
||||
const categoryWithName = await CategoryService.findByName(name, tx)
|
||||
|
||||
if (categoryWithName) {
|
||||
return categoryError({ name: ["Category already exists"] })
|
||||
}
|
||||
|
||||
await CategoryService.update(id, { name }, tx)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
if (isUniqueConstraintError(error)) {
|
||||
return categoryError({ name: ["Category already exists"] })
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteCategoryUseCase(
|
||||
id: string,
|
||||
): Promise<CategoryUseCaseResult> {
|
||||
return prisma.$transaction(async (tx) => {
|
||||
const category = await CategoryService.findByIdWithItemsCount(id, tx)
|
||||
|
||||
if (!category) {
|
||||
return categoryError({ id: ["Category not found"] })
|
||||
}
|
||||
|
||||
if (category._count.items && category._count.items > 0) {
|
||||
return categoryError({ id: ["Category has items"] })
|
||||
}
|
||||
|
||||
await CategoryService.delete(id, tx)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user