Pass force=true from the web UI space-delete confirmation

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.
This commit is contained in:
Himanshu Dongre 2026-05-19 20:41:33 +05:30
parent e303f7a547
commit c65e913666
2 changed files with 16 additions and 4 deletions

View file

@ -431,9 +431,18 @@ export async function reviewCheckpoint(checkpointId: string): Promise<import('..
// ── Delete endpoints ─────────────────────────────────────────────────────────
/** Delete a space and cascade to all its checkpoints, sessions, and turns. */
export async function deleteRepo(repoId: string): Promise<void> {
return requestV2<void>(`/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<void> {
const qs = opts?.force ? '?force=true' : '';
return requestV2<void>(`/repos/${repoId}${qs}`, { method: 'DELETE' });
}
/**

View file

@ -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();
}}