diff --git a/app/api.py b/app/api.py index 86a3e12..ccbefd1 100644 --- a/app/api.py +++ b/app/api.py @@ -134,28 +134,32 @@ def delete_undo(): if not _last_action: raise HTTPException(404, "No action to undo") action = _last_action - _last_action = None - item = action["item"] # always the original clean queue item + # Perform file operations FIRST — only clear _last_action on success if action["type"] == "label": - # Remove last entry from score file records = _read_jsonl(_score_file()) + if not records: + raise HTTPException(409, "Score file is empty — cannot undo label") _write_jsonl(_score_file(), records[:-1]) - elif action["type"] == "discard": - # Remove last entry from discarded file - records = _read_jsonl(_discarded_file()) - _write_jsonl(_discarded_file(), records[:-1]) - elif action["type"] == "skip": - # Item is at back of queue — move it to front items = _read_jsonl(_queue_file()) - reordered = [item] + [x for x in items if x["id"] != item["id"]] - _write_jsonl(_queue_file(), reordered) - return {"undone": {"type": action["type"], "item": item}} + _write_jsonl(_queue_file(), [item] + items) + elif action["type"] == "discard": + records = _read_jsonl(_discarded_file()) + if not records: + raise HTTPException(409, "Discarded file is empty — cannot undo discard") + _write_jsonl(_discarded_file(), records[:-1]) + items = _read_jsonl(_queue_file()) + _write_jsonl(_queue_file(), [item] + items) + elif action["type"] == "skip": + items = _read_jsonl(_queue_file()) + # Remove the item wherever it sits (guards against duplicate insertion), + # then prepend it to the front — restoring it to position 0. + items = [item] + [x for x in items if x["id"] != item["id"]] + _write_jsonl(_queue_file(), items) - # For label and discard: restore item to front of queue - items = _read_jsonl(_queue_file()) - _write_jsonl(_queue_file(), [item] + items) + # Clear AFTER all file operations succeed + _last_action = None return {"undone": {"type": action["type"], "item": item}} diff --git a/tests/test_api.py b/tests/test_api.py index 0a9ea23..2d5b8bc 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -116,6 +116,9 @@ def test_undo_label_removes_from_score(client, queue_with_items): assert data["undone"]["type"] == "label" score = api_module._read_jsonl(api_module._score_file()) assert score == [] + # Item should be restored to front of queue + queue = api_module._read_jsonl(api_module._queue_file()) + assert queue[0]["id"] == "id0" def test_undo_discard_removes_from_discarded(client, queue_with_items): from app import api as api_module