import { ok, err } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { InvalidEmailError, MissingRequiredFieldError, UserAlreadyExistsError, } from "../lib/errors.generated"; interface CreateUserInput { email: string; name: string; } const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; /** * Function: createUser * * Creates a new user account in PENDING status. * Validates email format and uniqueness. */ export async function run>( db: Transaction, input: CreateUserInput & CF, ) { const { email, name, ...customFields } = input; if (!email || email.trim() === "") { return err(new MissingRequiredFieldError("email")); } if (!name || name.trim() === "") { return err(new MissingRequiredFieldError("name")); } if (!EMAIL_PATTERN.test(email)) { return err(new InvalidEmailError(email)); } const existingUser = await db .selectFrom("User") .selectAll() .where("email", "=", email) .forUpdate() .executeTakeFirst(); if (existingUser) { return err(new UserAlreadyExistsError(email)); } const user = await db .insertInto("User") .values({ ...(customFields as Record), email, name, status: "PENDING", }) .returningAll() .executeTakeFirstOrThrow(); return ok({ user }); }