29 lines
941 B
TypeScript
29 lines
941 B
TypeScript
|
|
import { NextResponse } from 'next/server';
|
||
|
|
import { z } from 'zod';
|
||
|
|
|
||
|
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||
|
|
import { parseBody } from '@/lib/api/route-helpers';
|
||
|
|
import { errorResponse } from '@/lib/errors';
|
||
|
|
import { mergeDuplicate } from '@/lib/services/expense-dedup.service';
|
||
|
|
|
||
|
|
const mergeSchema = z.object({
|
||
|
|
/** Surviving expense id — typically the row's existing `duplicateOf` pointer. */
|
||
|
|
targetId: z.string().min(1),
|
||
|
|
});
|
||
|
|
|
||
|
|
export const POST = withAuth(
|
||
|
|
withPermission('expenses', 'edit', async (req, ctx, params) => {
|
||
|
|
try {
|
||
|
|
const sourceId = params.id;
|
||
|
|
if (!sourceId) {
|
||
|
|
return NextResponse.json({ error: 'Missing id' }, { status: 400 });
|
||
|
|
}
|
||
|
|
const body = await parseBody(req, mergeSchema);
|
||
|
|
await mergeDuplicate(sourceId, body.targetId, ctx.portId);
|
||
|
|
return NextResponse.json({ ok: true });
|
||
|
|
} catch (error) {
|
||
|
|
return errorResponse(error);
|
||
|
|
}
|
||
|
|
}),
|
||
|
|
);
|