import { and, eq } from 'drizzle-orm'; import { useDb } from '~~/server/database/client'; import { expenseParticipants, expenses } from '~~/server/database/schema'; export default defineEventHandler(async (event) => { const slug = getRouterParam(event, 'slug')!; const id = Number(getRouterParam(event, 'id')); await getPotOrThrow(slug); const body = await readBody(event); const description = typeof body?.description === 'string' ? body.description.trim() : ''; const amountCents = Number(body?.amountCents); const payerId = Number(body?.payerId); const participantIds: number[] = Array.isArray(body?.participantIds) ? body.participantIds.map(Number) : []; if (!description) { throw createError({ statusCode: 400, statusMessage: 'description is required', }); } if (!Number.isInteger(amountCents) || amountCents <= 0) { throw createError({ statusCode: 400, statusMessage: 'amountCents must be a positive integer', }); } if (participantIds.length === 0) { throw createError({ statusCode: 400, statusMessage: 'at least one participant must be selected', }); } const potParticipants = await getParticipants(slug); const validIds = new Set(potParticipants.map((p) => p.id)); if ( !validIds.has(payerId) || participantIds.some((pid) => !validIds.has(pid)) ) { throw createError({ statusCode: 400, statusMessage: 'payerId and participantIds must reference participants of this Pot', }); } const db = useDb(event); const [existing] = await db .select() .from(expenses) .where(and(eq(expenses.id, id), eq(expenses.potSlug, slug))); if (!existing) { throw createError({ statusCode: 404, statusMessage: 'Expense not found' }); } await db .update(expenses) .set({ description, amountCents, payerId }) .where(eq(expenses.id, id)); await db .delete(expenseParticipants) .where(eq(expenseParticipants.expenseId, id)); await db .insert(expenseParticipants) .values( participantIds.map((participantId) => ({ expenseId: id, participantId })), ); return { id, description, amountCents, payerId, participantIds }; });