import { DEFAULT_USER_PASSWORD, USERNAME_PATTERN, isValidPhoneNumber, normalizePhoneNumber, type UserRole } from '~~/shared/auth' import { normalizeUsername, requireRole } from '../../utils/auth' import { hashPassword } from '../../utils/password' import { createUser } from '../../utils/user-repository' export default defineEventHandler(async (event) => { const auth = await requireRole(event, 'super_admin') const body = await readBody<{ username?: string fullName?: string phoneNumber?: string role?: UserRole }>(event) const username = normalizeUsername(body.username || '') const fullName = body.fullName?.trim() || '' const phoneNumber = normalizePhoneNumber(body.phoneNumber || '') const role = body.role === 'super_admin' ? 'super_admin' : 'staff' if (!USERNAME_PATTERN.test(username)) { throw createError({ statusCode: 400, statusMessage: 'Username must be 3 to 32 characters using lowercase letters, numbers, dot, dash, or underscore' }) } if (fullName.length < 2) { throw createError({ statusCode: 400, statusMessage: 'Full name must be at least 2 characters' }) } if (!isValidPhoneNumber(phoneNumber)) { throw createError({ statusCode: 400, statusMessage: 'Phone number must contain 8 to 15 digits' }) } const passwordHash = await hashPassword(DEFAULT_USER_PASSWORD) try { const user = await createUser({ username, fullName, phoneNumber, role, passwordHash, createdBy: auth.user.id }) return { user, defaultPassword: DEFAULT_USER_PASSWORD } } catch (error: any) { if (error?.code === '23505') { throw createError({ statusCode: 409, statusMessage: 'Username already exists' }) } throw error } })