Files
v2.admin.gaertan.art/src/actions/artworks/deleteArtwork.ts

86 lines
2.1 KiB
TypeScript

"use server";
import { prisma } from "@/lib/prisma";
import { s3 } from "@/lib/s3";
import { DeleteObjectCommand } from "@aws-sdk/client-s3";
export async function deleteArtwork(artworkId: string) {
const artwork = await prisma.artwork.findUnique({
where: { id: artworkId },
include: {
variants: true,
timelapse: true,
colors: true,
metadata: true,
tags: true,
categories: true,
},
});
if (!artwork) throw new Error("Artwork not found");
// Delete S3 objects
for (const variant of artwork.variants) {
try {
await s3.send(
new DeleteObjectCommand({
Bucket: `${process.env.BUCKET_NAME}`,
Key: variant.s3Key,
})
);
} catch (err) {
console.warn("Failed to delete S3 object: " + variant.s3Key + ". " + err);
}
}
// Delete timelapse S3 object (if present)
if (artwork.timelapse?.s3Key) {
try {
await s3.send(
new DeleteObjectCommand({
Bucket: `${process.env.BUCKET_NAME}`,
Key: artwork.timelapse.s3Key,
})
);
} catch (err) {
console.warn(`Failed to delete timelapse S3 object: ${artwork.timelapse.s3Key}. ${err}`);
}
}
// Step 1: Delete join entries
await prisma.artworkColor.deleteMany({ where: { artworkId } });
// Colors
for (const color of artwork.colors) {
const count = await prisma.artworkColor.count({
where: { colorId: color.colorId },
});
if (count === 0) {
await prisma.color.delete({ where: { id: color.colorId } });
}
}
// Delete variants
await prisma.fileVariant.deleteMany({ where: { artworkId } });
// Delete timelapse DB row (relation also cascades, but be explicit)
await prisma.artworkTimelapse.deleteMany({ where: { artworkId } });
// Delete metadata
await prisma.artworkMetadata.deleteMany({ where: { artworkId } });
// Clean many-to-many tag/category joins
await prisma.artwork.update({
where: { id: artworkId },
data: {
tags: { set: [] },
categories: { set: [] },
},
});
// Finally delete the image
await prisma.artwork.delete({ where: { id: artworkId } });
return { success: true };
}