lomavuokraus/app/api/listings/[id]/images/[imageId]/route.ts
Tero Halla-aho 0bb709d9c5
Some checks failed
CI / checks (push) Has been cancelled
chore: fix audit alerts and formatting
2026-02-04 12:43:03 +02:00

95 lines
2.7 KiB
TypeScript

import { Role } from "@prisma/client";
import { NextResponse } from "next/server";
import { prisma } from "../../../../../../lib/prisma";
import { requireAuth } from "../../../../../../lib/jwt";
export async function DELETE(
req: Request,
{ params }: { params: { id: string; imageId: string } },
) {
try {
const auth = await requireAuth(req);
const listing = await prisma.listing.findUnique({
where: { id: params.id, removedAt: null },
select: {
id: true,
ownerId: true,
status: true,
images: {
orderBy: { order: "asc" },
select: { id: true, isCover: true, order: true },
},
},
});
if (!listing) {
return NextResponse.json({ error: "Listing not found" }, { status: 404 });
}
const isOwner = listing.ownerId === auth.userId;
const isAdmin = auth.role === Role.ADMIN;
if (!isOwner && !isAdmin) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
const targetImage = listing.images.find((img) => img.id === params.imageId);
if (!targetImage) {
return NextResponse.json({ error: "Image not found" }, { status: 404 });
}
if (listing.images.length <= 1) {
return NextResponse.json(
{ error: "At least one image is required" },
{ status: 400 },
);
}
const remaining = listing.images.filter((img) => img.id !== params.imageId);
const newCoverId =
remaining.find((img) => img.isCover)?.id ?? remaining[0]?.id ?? null;
await prisma.$transaction([
prisma.listingImage.delete({ where: { id: params.imageId } }),
...remaining.map((img, idx) =>
prisma.listingImage.update({
where: { id: img.id },
data: {
order: idx + 1,
isCover: newCoverId ? img.id === newCoverId : img.isCover,
},
}),
),
]);
const updated = await prisma.listing.findUnique({
where: { id: listing.id },
select: {
images: {
orderBy: { order: "asc" },
select: {
id: true,
url: true,
altText: true,
order: true,
isCover: true,
size: true,
mimeType: true,
},
},
},
});
return NextResponse.json({ ok: true, images: updated?.images ?? [] });
} catch (error: any) {
console.error("Delete listing image error", error);
if (String(error).includes("Unauthorized")) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
return NextResponse.json(
{ error: "Failed to delete image" },
{ status: 500 },
);
}
}
export const dynamic = "force-dynamic";