Files
pieced-portal/src/app/api/admin/tenants/[name]/delete/route.ts
admin 22fd5fb2cc
All checks were successful
Build and Push / build (push) Successful in 1m23s
TenantAssignment and readside filtering
2026-04-26 22:58:30 +02:00

63 lines
1.9 KiB
TypeScript

import { NextResponse } from "next/server";
import { requirePlatformRole } from "@/lib/session";
import { getTenant, deleteTenant } from "@/lib/k8s";
import {
markTenantRequestDeletedByTenantName,
removeAllAssignmentsForTenant,
} from "@/lib/db";
import { safeError } from "@/lib/errors";
/**
* POST /api/admin/tenants/[name]/delete
* Delete a PiecedTenant CR. The operator handles cleanup
* (namespace, vault, litellm team, etc.).
*
* Slice 6: also cascades the tenant_user_assignments rows so a
* future tenant with the same name (won't happen given UUID-suffix
* naming, but defense in depth) doesn't inherit stale assignments.
*
* Also marks the associated tenant_request as "deleted" so the
* customer can re-submit the onboarding wizard.
*/
export async function POST(
_request: Request,
{ params }: { params: Promise<{ name: string }> }
) {
try {
await requirePlatformRole();
} catch {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
const { name } = await params;
const tenant = await getTenant(name);
if (!tenant) {
return NextResponse.json({ error: "Tenant not found" }, { status: 404 });
}
try {
await deleteTenant(name);
// Best-effort DB cleanups. Both errors are logged but not surfaced —
// the K8s deletion has already started, and the row state is just
// for portal display.
await markTenantRequestDeletedByTenantName(name).catch((e) =>
console.error("Failed to mark tenant request deleted:", e)
);
await removeAllAssignmentsForTenant(name).catch((e) =>
console.error("Failed to clean up tenant assignments:", e)
);
return NextResponse.json({
message: "Tenant deletion initiated. The operator will clean up all resources.",
});
} catch (e: any) {
console.error("Failed to delete tenant:", e);
return NextResponse.json(
{ error: safeError(e, "Failed to delete tenant") },
{ status: 500 }
);
}
}