import type { FastifyPluginAsync } from 'fastify'; import { ZodError, z } from 'zod'; import { requireAuth } from '../auth/middleware.js'; import { getDbPool } from '../db/pool.js'; import { buildAccountPageData, ensureWorkspaceForUser, updateUserProfile, updateWorkspaceName } from '../account/repository.js'; const updateAccountSchema = z.object({ displayName: z.string().trim().min(1).max(120).optional(), avatarUrl: z.string().trim().url().nullable().optional().or(z.literal('')), workspaceName: z.string().trim().min(1).max(160).optional(), }); export const accountRoutes: FastifyPluginAsync = async (app) => { app.get('/account/me', { preHandler: requireAuth }, async (request, reply) => { try { const account = await buildAccountPageData(getDbPool(), request.authUser!); return { account }; } catch (error) { request.log.error(error); return reply.code(500).send({ error: 'Failed to load account page.' }); } }); app.patch('/account/me', { preHandler: requireAuth }, async (request, reply) => { try { const payload = updateAccountSchema.parse(request.body); const db = getDbPool(); const workspace = await ensureWorkspaceForUser(db, request.authUser!); if (!workspace) { return reply.code(500).send({ error: 'Failed to load workspace.' }); } if (payload.workspaceName && workspace.role !== 'owner') { return reply.code(403).send({ error: 'You do not have permission to update this workspace.' }); } const profile = await updateUserProfile(db, request.authUser!.id, { displayName: payload.displayName, avatarUrl: payload.avatarUrl === '' ? null : payload.avatarUrl, }); if (payload.workspaceName) { await updateWorkspaceName(db, workspace.id, payload.workspaceName); } const account = await buildAccountPageData(db, profile); return { account }; } catch (error) { if (error instanceof ZodError) { return reply.code(400).send({ error: error.issues[0]?.message || 'Invalid account payload.' }); } request.log.error(error); return reply.code(500).send({ error: 'Failed to update account.' }); } }); };