import { z } from 'zod'; import { db } from '../../utils/db'; import { createSession, hashPassword } from '../../utils/auth'; import { recordAudit } from '../../utils/audit'; import { sendEmail } from '../../utils/email'; const schema = z.object({ email: z.string().email().max(200), password: z.string().min(8).max(200), name: z.string().max(120).optional(), }); export default defineEventHandler(async (event) => { const parsed = schema.safeParse(await readBody(event).catch(() => ({}))); if (!parsed.success) { throw createError({ statusCode: 400, statusMessage: 'Invalid email or password (min 8 characters).' }); } const email = parsed.data.email.toLowerCase(); if (await db.user.findUnique({ where: { email } })) { throw createError({ statusCode: 409, statusMessage: 'An account with this email already exists.' }); } const user = await db.user.create({ data: { email, name: parsed.data.name || null, role: 'user', passwordHash: await hashPassword(parsed.data.password), subscription: { create: { plan: 'free', status: 'active', provider: 'mock' } }, }, }); await recordAudit({ actorId: user.id, action: 'user.register', target: user.email }); await sendEmail(event, { to: user.email, subject: 'Welcome', html: '

Your account is ready. Sign in to get started.

', }).catch((e) => console.error('[email] register', e)); await createSession(event, user.id); setResponseStatus(event, 201); return { user: { id: user.id, email: user.email, name: user.name, role: user.role } }; });