From e18bc8fbdab606f0dfea361b71141fe0dcb8b5b8 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Tue, 19 May 2026 10:11:55 +0200 Subject: [PATCH] fix(security): block deletion of categories and product types in use Return 409 Conflict if any products reference the entity being deleted, preventing accidental data corruption from orphaned foreign keys. --- app/src/app/api/admin/categories/route.ts | 8 ++++++++ app/src/app/api/admin/product-types/route.ts | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/app/src/app/api/admin/categories/route.ts b/app/src/app/api/admin/categories/route.ts index 9d55acf..a31f3e8 100644 --- a/app/src/app/api/admin/categories/route.ts +++ b/app/src/app/api/admin/categories/route.ts @@ -72,6 +72,14 @@ export async function DELETE(request: NextRequest) { const id = searchParams.get('id') if (!id) return NextResponse.json({ error: 'ID required' }, { status: 400 }) + const productCount = await prisma.productCategory.count({ where: { categoryId: id } }) + if (productCount > 0) { + return NextResponse.json( + { error: `Cannot delete: ${productCount} product(s) use this category` }, + { status: 409 } + ) + } + await prisma.category.delete({ where: { id } }) return NextResponse.json({ success: true }) diff --git a/app/src/app/api/admin/product-types/route.ts b/app/src/app/api/admin/product-types/route.ts index c602d67..f1bb44b 100644 --- a/app/src/app/api/admin/product-types/route.ts +++ b/app/src/app/api/admin/product-types/route.ts @@ -73,6 +73,14 @@ export async function DELETE(request: NextRequest) { const id = searchParams.get('id') if (!id) return NextResponse.json({ error: 'ID required' }, { status: 400 }) + const productCount = await prisma.product.count({ where: { typeId: id } }) + if (productCount > 0) { + return NextResponse.json( + { error: `Cannot delete: ${productCount} product(s) use this product type` }, + { status: 409 } + ) + } + await prisma.productType.delete({ where: { id } }) return NextResponse.json({ success: true })