You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Purchase History now shows pending approvals with the approver email (32f9e4ffc, b44283746), but there's no UI path to cancel a pending execution from History. The approval-link cancel endpoint is gated by a one-time email token, and the plan-backed cancel endpoints reject plan-less executions.
User wants to cancel from the CUDly dashboard rather than dig through inbox.
No Cancel button on the pending row. Only the email token can cancel.
Planned-purchase pause/resume/delete endpoints reject plan-less executions: execution not found or execution cannot transition.
Steps to reproduce
From Recommendations, click Execute on any row to create a pending execution.
Open Purchase History. Row shows Pending badge + approver email.
Look for a Cancel action on the pending row — none.
curl -X POST /api/purchases/planned/{id}/delete with session auth → execution cannot transition (the endpoint expects plan_id != "").
Expected behaviour
A session-authed Cancel button on pending rows that calls a cancel endpoint not gated by the email token.
Proposed fix
Option A — add a new session-authed cancel endpoint (or broaden cancelPurchase to accept either token= or an authenticated admin session), then wire a Cancel button in frontend/src/history.ts:renderHistoryList:
Shows only for status=="pending" or status=="notified".
Gated by the same permission as Purchase History rendering.
On click: confirmDialog, POST to the new endpoint, reload history.
Why not fixed yet
The token-authed path is secure by design — the email token proves intent. A session-authed bypass widens blast radius and needs an RBAC review: does the existing delete purchases verb cover this, or do we add cancel:own_executions?
References
Commits: 32f9e4ffc (pending in history), b44283746 (failed + expired states).
Summary
Purchase History now shows pending approvals with the approver email (
32f9e4ffc,b44283746), but there's no UI path to cancel a pending execution from History. The approval-link cancel endpoint is gated by a one-time email token, and the plan-backed cancel endpoints reject plan-less executions.Captured in:
known_issues/30_history_pending_cancel_ui.mdCurrent behaviour
plan_id = "").pause/resume/deleteendpoints reject plan-less executions:execution not foundorexecution cannot transition.Steps to reproduce
curl -X POST /api/purchases/planned/{id}/deletewith session auth →execution cannot transition(the endpoint expectsplan_id != "").Expected behaviour
A session-authed Cancel button on pending rows that calls a cancel endpoint not gated by the email token.
Proposed fix
Option A — add a new session-authed cancel endpoint (or broaden
cancelPurchaseto accept eithertoken=or an authenticated admin session), then wire a Cancel button infrontend/src/history.ts:renderHistoryList:status=="pending"orstatus=="notified".confirmDialog,POSTto the new endpoint, reload history.Why not fixed yet
The token-authed path is secure by design — the email token proves intent. A session-authed bypass widens blast radius and needs an RBAC review: does the existing
delete purchasesverb cover this, or do we addcancel:own_executions?References
32f9e4ffc(pending in history),b44283746(failed + expired states).internal/api/handler_purchases.go::cancelPurchase,frontend/src/history.ts::renderHistoryList.known_issues/30_history_pending_cancel_ui.md.Severity
Medium — users can still cancel via email, but the dashboard showing state without an action feels broken.