Files
pad/web/src
xarmian 3d191017ed fix(web): fence ordinary attachment loads against in-flight deletes
U2 (TASK-2511) added the ref-counted `inFlightDeletes` marker but applied
it only to `revalidateAfterRestore`'s merge. The ordinary list-load
reconciliation paths still filtered on `deletedIds` alone, and that set is
latched only AFTER a delete's API await (via the deletion bus self-
broadcast). In the gap between an optimistic removal and that broadcast a
row is gone from `attachments` but not yet tombstoned, so an ordinary
list() response issued (or in flight) across that window — a mount/retry
load, or the restore path deferring to an in-flight same-view load — could
carry the row and repaint the tile the user just removed.

Honor `isDeleting(id)` on every ordinary-load reconciliation path, exactly
as the restore merge already does: the response row filter, the pending-
upload merge, and the load-failure repaint. The settle-time rollback stays
a direct write into `attachments` (the marker is cleared in performDelete's
`finally`, after the catch re-inserts the row), so a genuinely failed
delete still rolls its row back into view. Continuation-count math is
unchanged in spirit — `rows`/`missed` simply exclude the same ids the
restore path already excludes.

Tests (jsdom, each mutation-verified): the P1 flow via a retry load, the
pending-upload merge leg, the load-failure repaint, and the rollback-
after-failure discipline surviving a list response that landed mid-delete.

Claude-Session: https://claude.ai/code/session_01WFBYxdBuSZs2tjipATxAZu
2026-08-11 05:17:26 +00:00
..