test: lock in task-delete cache ordering, and fix project-delete ordering
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- csharp, react, typescript
Hướng nghiên cứu
Đọc TaskFlow.Web/src/hooks/useTasks.ts và kiểm tra useDeleteTaskMutation.onSuccess; issue xác định thứ tự vô hiệu hóa và xóa làm phát sinh các request. Bắt đầu với bài kiểm tra hook được đề xuất, sau đó chạy các bài kiểm tra xóa hiện có của trang chi tiết. Hoàn tất khi việc xóa một tác vụ không tạo thêm request nào cho các truy vấn tác vụ, ghi chú hoặc lịch sử của tác vụ đó, trong khi danh sách tác vụ và số lượng dự án vẫn được cập nhật; nếu xóa thất bại, trang và các truy vấn phải được giữ nguyên.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Groomed 2026-10-30 — ready for implementation.
Original Description
Found during the /ux-test run for #320 / PR #333. Not caused by that PR; the delete handler is unchanged there.
Problem
Deleting a task from its detail page (/tasks/:id) succeeds and redirects to /tasks, but the browser console logs five 404 errors for the task that was just deleted:
GET /api/v1/TaskItems/<id> 404 (x2)
GET /api/v1/TaskItems/<id>/notes 404 (x2)
GET /api/v1/TaskItems/<id>/history 404 (x1)
No user-visible effect was observed (the redirect wins), but it is wasted requests, console noise that hides real errors, and a possible brief not-found flash if the redirect is ever slower.
Cause
useDeleteTaskMutation (TaskFlow.Web/src/hooks/useTasks.ts) runs, in onSuccess:
qc.invalidateQueries({ queryKey: taskKeys.all }) // ['tasks']
qc.invalidateQueries({ queryKey: projectKeys.all })
qc.removeQueries({ queryKey: taskKeys.detail(id) }) // ['tasks', id]
invalidateQueries matches by key prefix, so ['tasks'] also matches the deleted task's own queries, which are all still mounted and active on the detail page: ['tasks', id] (task), ['tasks', id, 'notes'] and ['tasks', id, 'history']. Invalidation refetches active queries immediately, so they fire (and retry once, retry: 1 in main.tsx) before removeQueries runs and before TaskDetailPage navigates in its own onSuccess. removeQueries does not cancel a fetch already in flight.
The deleted task's queries should never be refetched, only dropped.
Suggested fix
In useDeleteTaskMutation.onSuccess, remove the deleted task's queries first (removeQueries({ queryKey: taskKeys.detail(id) }) already covers detail, notes and history by prefix), then invalidate the rest. Alternatively invalidate with a predicate that skips keys whose second element is id.
Acceptance criteria
- Given a task detail page, when I delete the task and confirm, then I land on
/tasksand no request is made to/TaskItems/<id>,/notesor/historyafter the DELETE. - Given the delete succeeds, then the task list and project counts still refresh (the list and project queries are still invalidated).
- Given a failed delete, then the page stays as is and nothing is removed.
Notes
- Test: a hook test on
useDeleteTaskMutationasserting the deleted task's queries are not refetched, plus the existing detail-page delete tests staying green. - Overlaps with #321 (Undo toast for Tasks-page deletes), which also changes the delete hooks. Fix this in the same place, or land this first.
useDeleteProjectMutationhas the same invalidate-then-remove order, but it has no UI yet, so it is not hit today. Worth fixing the same way while there.
User Story
As a developer maintaining TaskFlow, I want a regression test that proves deleting a task never refetches its own queries, and the same remove-before-invalidate ordering applied to project deletion, so that deletes produce no wasted requests or 404 console noise, and the ordering can't silently regress.
Scope note (2026-10-30): the task-side fix has already landed. invalidateAfterTaskDelete in hooks/useTasks.ts (lines 205-226) removes the deleted task's queries first, and TaskDetailPage now deletes through useDeleteTaskUndoable (#321), which navigates to /tasks before the DELETE is sent. The description above is kept for history. The remaining work is a regression test for the task side and the ordering fix for projects (hooks/useProjects.ts, lines 91-103). Paths are relative to TaskFlow.Web/src.
Acceptance Criteria
Task delete (lock in existing behavior, test only)
- Given a real query client with the deleted task's detail, notes and history queries mounted, when the task-delete invalidation runs after a successful DELETE, then no further request is made for that task's detail, notes or history.
- Given that same test, when the code is changed to invalidate before removing, then the test fails.
- Given a successful task delete, when invalidation completes, then the task list, project and journal queries are still invalidated.
- Given a DELETE that fails when the Undo window ends, when the commit settles, then the task's cached queries are kept. This replaces the original "page stays as is" criterion, because the user has already been taken to
/tasks. The existinguseDeleteTaskUndoabletest (hooks/useDeleteTaskUndoable.test.tsx, lines 78-85) already covers it and must stay green.
Project delete (fix and test)
- Given a successful project delete, when
useDeleteProjectMutationsucceeds, then the project's detail and tasks queries are removed beforeprojectKeys.allandtaskKeys.allare invalidated. - Given a real query client with an active
['projects', id]query, when the delete succeeds, then no request is made for that project after the DELETE. This test fails against the current order. - Given a successful project delete, when it completes, then the project list and task queries are still refreshed.
- Given a failed project delete, when the mutation errors, then nothing is removed from the cache.
Edge Cases
- The new tests need a real query client with mounted observers and call counts on the SDK mocks. Spies on
invalidateQueries/removeQueries, like the existing order-insensitive check athooks/useProjects.test.tslines 151-159, can't show refetches. - TanStack v5 may rebuild a removed query if an observer stays mounted. The tests should confirm this does not happen for the task and project cases. This was unverified in the research.
pages/TaskDetailPage.test.tsxmocksuseDeleteTaskUndoableentirely, so the real delete-and-navigate sequence still has no integration coverage. This story does not add it.taskKeys.allstays invalidated after a project delete, because that project's tasks may have changed. Only the order changes.
Out of Scope
- The Undo toast (#321), which is already implemented.
- Adding UI for deleting projects.
useDeleteProjectMutationanduseDeleteTaskMutationhave no production callers. - Changing the Undo window timing, toast behavior, or the query client defaults (
staleTime30_000,retry1). - Browser-based verification that the 404s are gone. The tests are sufficient.
- Auditing the invalidation order of other mutations.
- Rewriting the original issue body.
- Ngôn ngữ chính
- C#
- Star
- 1
- Fork
- 0
- Merge trung bình
- 2 giờ 2 phút
- Pull request đã merge (30 ngày)
- 98
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của nevridge/TaskFlow
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của nevridge/TaskFlow
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
juandresrodca/AdminForge#54 ·
-
[辞書] C/C++のプリプロセッサ指令名を英字のままにするĐang mở要トリアージ 辞書
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 86/100
yksr-melt/Meltype#1625 · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Docs typoĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
MonoGame/docs.monogame.github.io#328 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
space-wizards/RobustToolbox#7197 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
documentation high priority
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
lachydotmcg/capri-desktop#201 ·
Maintainer thường phản hồi trong vòng 1 ngày