44 lines
2.0 KiB
TypeScript
44 lines
2.0 KiB
TypeScript
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()
|
|
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 }
|
|
})
|