feat(plan): add hard-delete for categories (blocked when in use)
DELETE /plan/categories/:id now hard-deletes the row, guarded: refuses when any live entry/override uses the key (suggests hide instead) and keeps >=1 active category. Modal gains a per-row Smazat with inline confirm. Hiding stays via PATCH is_active. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -119,3 +119,47 @@ export async function deactivatePlanCategory(
|
||||
if ("error" in res) return res;
|
||||
return { data: { ok: true } };
|
||||
}
|
||||
|
||||
/**
|
||||
* Hard-delete a category. Blocked when the category is still used by any live
|
||||
* (non-soft-deleted) plan entry or override — those rows would otherwise lose
|
||||
* their label/color — in which case the caller should hide it instead. Also
|
||||
* refuses to remove the last active category so the create form is never empty.
|
||||
*/
|
||||
export async function deletePlanCategory(
|
||||
id: number,
|
||||
): Promise<CatResult<{ ok: true }>> {
|
||||
const existing = await prisma.plan_categories.findUnique({ where: { id } });
|
||||
if (!existing) return { error: "Kategorie nenalezena", status: 404 };
|
||||
|
||||
const [entryCount, overrideCount] = await Promise.all([
|
||||
prisma.work_plan_entries.count({
|
||||
where: { category: existing.key, is_deleted: false },
|
||||
}),
|
||||
prisma.work_plan_overrides.count({
|
||||
where: { category: existing.key, is_deleted: false },
|
||||
}),
|
||||
]);
|
||||
if (entryCount + overrideCount > 0) {
|
||||
return {
|
||||
error:
|
||||
"Kategorie je používána v plánu a nelze ji smazat. Můžete ji skrýt.",
|
||||
status: 409,
|
||||
};
|
||||
}
|
||||
|
||||
if (existing.is_active) {
|
||||
const activeCount = await prisma.plan_categories.count({
|
||||
where: { is_active: true },
|
||||
});
|
||||
if (activeCount <= 1) {
|
||||
return {
|
||||
error: "Musí zůstat alespoň jedna aktivní kategorie",
|
||||
status: 400,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
await prisma.plan_categories.delete({ where: { id } });
|
||||
return { data: { ok: true } };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user