From c65e9136667f0826aebabdd1515459958fc9bb27 Mon Sep 17 00:00:00 2001 From: Himanshu Dongre Date: Tue, 19 May 2026 20:41:33 +0530 Subject: [PATCH] Pass force=true from the web UI space-delete confirmation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backend now refuses DELETE /api/v2/repos/{id} with 409 for a space that still holds checkpoints unless force=true is passed. The web UI's delete-space request did not send it, so deleting a non-empty space from the browser failed (it failed safe — nothing was deleted). deleteRepo() gains an optional { force } argument, mirroring the sibling deleteCommit()'s { cascade }. WorkspaceOverviewPage passes force=true from the ConfirmDeleteModal's onConfirm — the point where the user has already acknowledged the irreversible "this cannot be undone" confirmation. No modal or UX change; only the request now carries the flag the backend requires. --- frontend/src/api/client.ts | 15 ++++++++++++--- frontend/src/pages/WorkspaceOverviewPage.tsx | 5 ++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index bbbc35d..3a71857 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -431,9 +431,18 @@ export async function reviewCheckpoint(checkpointId: string): Promise { - return requestV2(`/repos/${repoId}`, { method: 'DELETE' }); +/** + * Delete a space and cascade to all its checkpoints, sessions, and turns. + * The backend refuses with 409 unless force=true is passed for a space that + * still holds checkpoints, so callers must confirm with the user first, then + * pass { force: true }. + */ +export async function deleteRepo( + repoId: string, + opts?: { force?: boolean }, +): Promise { + const qs = opts?.force ? '?force=true' : ''; + return requestV2(`/repos/${repoId}${qs}`, { method: 'DELETE' }); } /** diff --git a/frontend/src/pages/WorkspaceOverviewPage.tsx b/frontend/src/pages/WorkspaceOverviewPage.tsx index aa19270..981f471 100644 --- a/frontend/src/pages/WorkspaceOverviewPage.tsx +++ b/frontend/src/pages/WorkspaceOverviewPage.tsx @@ -430,7 +430,10 @@ export function WorkspaceOverviewPage() { body="This will permanently delete the space, all of its checkpoints, sessions, and turns. This cannot be undone." onClose={() => setDeleteTarget(null)} onConfirm={async () => { - await deleteRepo(deleteTarget.id); + // force=true: the ConfirmDeleteModal above is the user's + // explicit confirmation, which the backend's non-empty + // delete guard requires. + await deleteRepo(deleteTarget.id, { force: true }); setDeleteTarget(null); await refreshWorkspace(); }}