Files
vibn-frontend/app/api/workspaces/delete/route.ts
Mark Henderson c862104e35 feat(ux): empty-state prompt nudges + workspace delete
- Plan/Product/Infrastructure: empty states now suggest a concrete AI
  prompt so non-technical users know exactly what to type rather than
  staring at a blank category ("Try: Add a Postgres database…")
- Workspace settings danger zone: wired Delete Workspace to a new
  POST /api/workspaces/delete endpoint (deletes projects + chat
  threads; Coolify resources intentionally untouched)

Made-with: Cursor
2026-04-30 17:17:22 -07:00

72 lines
2.1 KiB
TypeScript

import { NextResponse } from "next/server";
import { authSession } from "@/lib/auth/session-server";
import { query } from "@/lib/db-postgres";
/**
* POST /api/workspaces/delete
* Body: { slug: string }
*
* Deletes the workspace record and all associated projects/threads.
* Coolify resources (services, databases) are NOT deleted — the user
* must clean those up manually or via the AI. This only removes Vibn's
* knowledge of the workspace.
*
* Ownership check: the workspace's owner_user_id must match the
* authenticated user.
*/
export async function POST(request: Request) {
try {
const session = await authSession();
if (!session?.user?.email) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const { slug } = await request.json();
if (!slug) {
return NextResponse.json({ error: "slug is required" }, { status: 400 });
}
// Find the workspace and verify ownership
const wsRows = await query<{ id: string; slug: string }>(
`SELECT vw.id, vw.slug
FROM vibn_workspaces vw
JOIN fs_users u ON u.id = vw.owner_user_id
WHERE vw.slug = $1 AND u.data->>'email' = $2
LIMIT 1`,
[slug, session.user.email],
);
if (!wsRows.length) {
return NextResponse.json({ error: "Workspace not found or unauthorized" }, { status: 404 });
}
const workspaceId = wsRows[0].id;
// Delete all chat threads scoped to the workspace
await query(
`DELETE FROM fs_chat_threads WHERE workspace = $1`,
[slug],
);
// Delete all projects in the workspace
await query(
`DELETE FROM fs_projects WHERE workspace = $1`,
[slug],
);
// Delete the workspace itself
await query(
`DELETE FROM vibn_workspaces WHERE id = $1`,
[workspaceId],
);
return NextResponse.json({ success: true, message: "Workspace deleted" });
} catch (error) {
console.error("[POST /api/workspaces/delete]", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Delete failed" },
{ status: 500 },
);
}
}