87 lines
2.2 KiB
TypeScript
87 lines
2.2 KiB
TypeScript
"use server";
|
|
|
|
import { prisma } from "@/lib/prisma";
|
|
import { s3 } from "@/lib/s3";
|
|
import { DeleteObjectCommand } from "@aws-sdk/client-s3";
|
|
|
|
// Deletes an artwork and all related assets and records.
|
|
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 };
|
|
}
|