refactor(recipients): move mutations into use cases
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import { Prisma } from "@/generated/prisma/client"
|
||||
import prisma from "@/lib/prisma"
|
||||
import type {
|
||||
CreateRecipientFormType,
|
||||
UpdateRecipientFormType,
|
||||
} from "@/schemas/recipient.schema"
|
||||
import { RecipientService } from "@/services/recipient.service"
|
||||
|
||||
type FieldErrors = Record<string, string[]>
|
||||
|
||||
type RecipientUseCaseResult =
|
||||
| {
|
||||
success: true
|
||||
}
|
||||
| {
|
||||
success: false
|
||||
errors: FieldErrors
|
||||
}
|
||||
|
||||
function recipientError(errors: FieldErrors): RecipientUseCaseResult {
|
||||
return {
|
||||
success: false,
|
||||
errors,
|
||||
}
|
||||
}
|
||||
|
||||
function uniqueErrorFor(error: unknown): FieldErrors | null {
|
||||
if (
|
||||
!(error instanceof Prisma.PrismaClientKnownRequestError) ||
|
||||
error.code !== "P2002"
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const target = Array.isArray(error.meta?.target) ? error.meta.target : []
|
||||
|
||||
if (target.includes("username")) {
|
||||
return { username: ["Username already exists"] }
|
||||
}
|
||||
|
||||
if (target.includes("email")) {
|
||||
return { email: ["Email already exists"] }
|
||||
}
|
||||
|
||||
return { username: ["Username already exists"] }
|
||||
}
|
||||
|
||||
export async function createRecipientUseCase(
|
||||
input: CreateRecipientFormType,
|
||||
): Promise<RecipientUseCaseResult> {
|
||||
const { username, firstName, lastName, department, email, phone } = input
|
||||
|
||||
try {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
const existingRecipientUsername = await RecipientService.findByUsername(
|
||||
username,
|
||||
tx,
|
||||
)
|
||||
|
||||
if (existingRecipientUsername) {
|
||||
return recipientError({ username: ["Username already exists"] })
|
||||
}
|
||||
|
||||
if (email) {
|
||||
const existingRecipientEmail = await RecipientService.findByEmail(
|
||||
email,
|
||||
tx,
|
||||
)
|
||||
|
||||
if (existingRecipientEmail) {
|
||||
return recipientError({ email: ["Email already exists"] })
|
||||
}
|
||||
}
|
||||
|
||||
await RecipientService.create(
|
||||
{
|
||||
username: username || (firstName[0] + lastName).toLowerCase(),
|
||||
firstName,
|
||||
lastName,
|
||||
department,
|
||||
email: email || null,
|
||||
phone: phone || null,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
const errors = uniqueErrorFor(error)
|
||||
|
||||
if (errors) {
|
||||
return recipientError(errors)
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateRecipientUseCase(
|
||||
input: UpdateRecipientFormType,
|
||||
): Promise<RecipientUseCaseResult> {
|
||||
const { id, username, firstName, lastName, department, email, phone } = input
|
||||
|
||||
try {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
const existingRecipient = await RecipientService.findByUsername(
|
||||
username,
|
||||
tx,
|
||||
)
|
||||
|
||||
if (existingRecipient && existingRecipient.id !== id) {
|
||||
return recipientError({ username: ["Username already exists"] })
|
||||
}
|
||||
|
||||
if (email) {
|
||||
const existingRecipientEmail = await RecipientService.findByEmail(
|
||||
email,
|
||||
tx,
|
||||
)
|
||||
|
||||
if (existingRecipientEmail && existingRecipientEmail.id !== id) {
|
||||
return recipientError({ email: ["Email already exists"] })
|
||||
}
|
||||
}
|
||||
|
||||
await RecipientService.update(
|
||||
id,
|
||||
{
|
||||
username,
|
||||
firstName,
|
||||
lastName,
|
||||
department,
|
||||
email: email || null,
|
||||
phone: phone || null,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
const errors = uniqueErrorFor(error)
|
||||
|
||||
if (errors) {
|
||||
return recipientError(errors)
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user