import { NextResponse } from 'next/server' import { z } from 'zod' import { auth } from '@/lib/auth' import { prisma } from '@/lib/prisma' const bulkSchema = z.discriminatedUnion('action', [ z.object({ action: z.literal('delete'), ids: z.array(z.string()).min(1), }), z.object({ action: z.literal('assignBudget'), ids: z.array(z.string()).min(1), budgetId: z.string().nullable(), }), z.object({ action: z.literal('addNotes'), ids: z.array(z.string()).min(1), notes: z.string().max(500), }), ]) export async function POST(req: Request) { const session = await auth() if (!session?.user?.id) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) const body = await req.json() const result = bulkSchema.safeParse(body) if (!result.success) return NextResponse.json({ error: result.error.flatten() }, { status: 400 }) const { action, ids } = result.data const userId = session.user.id // Verify all transaction IDs belong to this user const owned = await prisma.transaction.findMany({ where: { id: { in: ids }, account: { userId } }, select: { id: true, accountId: true }, }) if (owned.length !== ids.length) { return NextResponse.json({ error: 'One or more transactions not found' }, { status: 404 }) } if (action === 'delete') { const accountIds = [...new Set(owned.map((t) => t.accountId))] await prisma.transaction.deleteMany({ where: { id: { in: ids } } }) // Recompute currentBalanceCents for each affected account for (const accountId of accountIds) { const [balRow] = await prisma.$queryRaw<[{ balance: bigint }]>` SELECT COALESCE(SUM( CASE WHEN type = 'CREDIT' THEN "amountCents" ELSE -"amountCents" END ), 0)::bigint AS balance FROM "Transaction" WHERE "accountId" = ${accountId} ` await prisma.account.update({ where: { id: accountId }, data: { currentBalanceCents: Number(balRow.balance) }, }) } return NextResponse.json({ deleted: ids.length }) } if (action === 'assignBudget') { const { budgetId } = result.data if (budgetId !== null) { const budget = await prisma.budget.findFirst({ where: { id: budgetId, userId } }) if (!budget) return NextResponse.json({ error: 'Budget not found' }, { status: 404 }) } await prisma.transaction.updateMany({ where: { id: { in: ids } }, data: { budgetId }, }) return NextResponse.json({ updated: ids.length }) } // addNotes const { notes } = result.data await prisma.transaction.updateMany({ where: { id: { in: ids } }, data: { notes: notes || null }, }) return NextResponse.json({ updated: ids.length }) }