Files
money.sori.studio/server/api/transactions/[id].patch.ts
2026-08-13 16:38:59 +09:00

55 lines
1.7 KiB
TypeScript

import { readBody, getRouterParam, createError } from 'h3'
import { prisma } from '../../utils/db'
import { requireUser } from '../../utils/auth'
export default defineEventHandler(async (event) => {
const user = await requireUser(event)
const id = getRouterParam(event, 'id')!
const body = await readBody<{
type: 'income' | 'expense'
occurredAt: string
assetId: string
categoryId: string
amount: number
title: string
memo?: string
latitude?: number | null
longitude?: number | null
}>(event)
const transaction = await prisma.transaction.findFirst({ where: { id, userId: user.id } })
if (!transaction) throw createError({ statusCode: 404, statusMessage: 'Transaction not found' })
if (!body.title?.trim() || !body.amount || body.amount < 1) {
throw createError({ statusCode: 400, statusMessage: 'Invalid transaction' })
}
const [asset, category] = await Promise.all([
prisma.asset.findFirst({ where: { id: body.assetId, userId: user.id, active: true } }),
prisma.category.findFirst({ where: { id: body.categoryId, userId: user.id, type: body.type, active: true } })
])
if (!asset || !category) {
throw createError({ statusCode: 400, statusMessage: 'Invalid asset or category' })
}
return prisma.transaction.update({
where: { id },
data: {
type: body.type,
occurredAt: new Date(body.occurredAt),
assetId: body.assetId,
categoryId: body.categoryId,
amount: Number(body.amount),
title: body.title.trim(),
memo: body.memo?.trim().slice(0, 60) || null,
latitude: body.latitude ?? null,
longitude: body.longitude ?? null
},
include: {
asset: true,
category: { include: { parent: true } }
}
})
})