Add admin request deletion with soft delete and cleanup

Implements admin ability to delete requests with soft delete, media file cleanup, and seeding-aware torrent management. Adds new API endpoint, frontend confirmation dialog, and request actions dropdown. Updates database schema with deletedAt and deletedBy fields, and ensures all queries filter out deleted requests. Documentation added for feature and user flow.
This commit is contained in:
kikootwo
2025-12-22 20:24:43 -05:00
parent bba4af7398
commit 174e9f05b6
26 changed files with 1936 additions and 200 deletions
+21 -9
View File
@@ -26,8 +26,11 @@ export async function GET(
const { id } = await params;
const requestRecord = await prisma.request.findUnique({
where: { id },
const requestRecord = await prisma.request.findFirst({
where: {
id,
deletedAt: null, // Only show active requests
},
include: {
audiobook: true,
user: {
@@ -100,13 +103,16 @@ export async function PATCH(
const body = await req.json();
const { action } = body;
const requestRecord = await prisma.request.findUnique({
where: { id },
const requestRecord = await prisma.request.findFirst({
where: {
id,
deletedAt: null, // Only allow updates to active requests
},
});
if (!requestRecord) {
return NextResponse.json(
{ error: 'NotFound', message: 'Request not found' },
{ error: 'NotFound', message: 'Request not found or already deleted' },
{ status: 404 }
);
}
@@ -161,8 +167,11 @@ export async function PATCH(
if (requestRecord.status === 'warn' || requestRecord.status === 'awaiting_import') {
// Retry import
const requestWithData = await prisma.request.findUnique({
where: { id },
const requestWithData = await prisma.request.findFirst({
where: {
id,
deletedAt: null,
},
include: {
audiobook: true,
downloadHistory: {
@@ -213,8 +222,11 @@ export async function PATCH(
jobType = 'import';
} else {
// Retry search
const requestWithData = await prisma.request.findUnique({
where: { id },
const requestWithData = await prisma.request.findFirst({
where: {
id,
deletedAt: null,
},
include: {
audiobook: true,
},