import { NextRequest, NextResponse } from "next/server"; import { getStatementById } from "@/lib/queries"; import { getCurrentUser } from "@/lib/auth"; import { prisma, queryRaw } from "@/lib/db"; export async function GET( req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const user = await getCurrentUser(req); if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 403 }); const { id } = await params; const stmt = await getStatementById(Number(id)); if (!stmt || stmt.owner_id !== user.id) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } return NextResponse.json(stmt); } /** * Reassign a statement — whose account it is. * * The statements page has had an owner dropdown since it was built, wired to * `useUpdateStatement`, which PATCHed a route that had no PATCH handler. Every * change 405'd, and because the hook never checked `res.ok` the failure was * silent: the select snapped back on refetch and looked like a UI glitch. * * Both tables are written because both carry the owner. The effective owner is * `COALESCE(t.owner_id, s.owner_id)`, and 2,194 statement rows carry their own * copy against 1,803 that inherit — so updating `statements` alone would move * less than half the rows and split one account's history between two people. * All 2,194 agree with their statement today; a row that disagrees was set * deliberately and is left alone rather than swept up. */ export async function PATCH( req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const user = await getCurrentUser(req); if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 403 }); const { id } = await params; const statementId = Number(id); const stmt = await getStatementById(statementId); // Only the current owner reassigns. A statement is an account, not a shared // expense — there is no split that grants a second person a say in it. if (!stmt || stmt.owner_id !== user.id) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } const { owner_id } = (await req.json()) as { owner_id?: number }; if (typeof owner_id !== "number" || !Number.isInteger(owner_id)) { return NextResponse.json({ error: "owner_id must be a participant id" }, { status: 400 }); } const known = await queryRaw(`SELECT id FROM participants WHERE id = $1`, [owner_id]); if (!known.length) { return NextResponse.json({ error: "Unknown participant" }, { status: 400 }); } if (owner_id === stmt.owner_id) { return NextResponse.json({ ok: true, statement_id: statementId, rows_moved: 0 }); } const [, rowsMoved] = await prisma.$transaction([ prisma.$executeRawUnsafe(`UPDATE statements SET owner_id = $1 WHERE id = $2`, owner_id, statementId), prisma.$executeRawUnsafe( `UPDATE transactions SET owner_id = $1 WHERE statement_id = $2 AND owner_id = $3`, owner_id, statementId, stmt.owner_id ), ]); return NextResponse.json({ ok: true, statement_id: statementId, rows_moved: rowsMoved }); }