feat: add unified Person+User creation backend

This commit is contained in:
2026-06-16 21:21:17 +02:00
parent 68c2983d36
commit e5717461cf
11 changed files with 772 additions and 1 deletions
+82
View File
@@ -1,9 +1,12 @@
import { Prisma } from "@/generated/prisma/client"
import prisma from "@/lib/prisma"
import { getPasswordHash } from "@/lib/security"
import type {
CreatePersonFormType,
UpdatePersonFormType,
} from "@/schemas/person.schema"
import type { UnifiedCreateFormType } from "@/schemas/user.schema"
import { getUserByEmail } from "@/services/user.service"
import { PersonService } from "@/services/person.service"
type FieldErrors = Record<string, string[]>
@@ -127,3 +130,82 @@ export async function updatePersonUseCase(
throw error
}
}
export async function createPersonUserUseCase(
input: UnifiedCreateFormType,
): Promise<PersonUseCaseResult> {
const { firstName, lastName, department, email, phone, role, password, isActive } =
input
try {
return await prisma.$transaction(async (tx) => {
// Cross-table email uniqueness: check both Person and User tables
const existingPersonEmail = await PersonService.findByEmail(email, tx)
if (existingPersonEmail) {
return personError({ email: ["Email already exists"] })
}
const existingUserEmail = await getUserByEmail(email, tx)
if (existingUserEmail) {
return personError({ email: ["Email already exists"] })
}
if (role === "NO_USER") {
// Person-only creation — no User record
await PersonService.create(
{
firstName,
lastName,
department,
email,
phone: phone ?? null,
},
tx,
)
return { success: true }
}
// Person + User creation
const person = await PersonService.create(
{
firstName,
lastName,
department,
email,
phone: phone ?? null,
},
tx,
)
const userName = `${firstName} ${lastName}`
const hashedPassword = await getPasswordHash(password!)
const user = await tx.user.create({
data: {
name: userName,
email,
password: hashedPassword,
role,
isActive,
},
})
await PersonService.update(
person.id,
{ user: { connect: { id: user.id } } },
tx,
)
return { success: true }
})
} catch (error) {
const errors = uniqueErrorFor(error)
if (errors) {
return personError(errors)
}
throw error
}
}