Files
multica/packages/core/workspace
Naiyuan Qing 93aa959239 fix(workspace): await delete before navigating; suppress self-initiated realtime relocate (MUL-4129) (#4983)
* fix(workspace): drop workspace from list cache while delete is pending (MUL-4129)

The delete-workspace flow navigates away before awaiting the DELETE
(required ordering — see navigateAwayFromCurrentWorkspace's
CancelledError notes), but useDeleteWorkspace left the workspace in the
list cache until onSettled. During the pending window any list refetch
re-presented the deleting workspace as a selectable/current option.

Optimistically remove it in onMutate (after cancelling in-flight list
fetches), roll the snapshot back in onError so a failed delete restores
the workspace alongside the existing error toast, and keep the
onSettled invalidate as the server-truth reconcile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* fix(workspace): own storage cleanup on delete success and tombstone pending deletes (MUL-4129)

Address final-review blockers on #4980:

1. The realtime workspace:deleted handler reverse-looks-up the slug from
   the list cache to clear the ${key}:${slug} persisted namespace; the
   optimistic removal empties that row on the initiating client, so the
   lookup misses and cleanup was silently skipped. Capture the slug in
   onMutate before removal and clear storage in onSuccess only — a
   failed DELETE rolls back and must not touch persisted state.

2. cancelQueries only covered fetches already in flight at onMutate.
   Add a pending-delete tombstone (marked onMutate, lifted onSettled
   before the reconcile invalidate) filtered inside workspaceListOptions'
   queryFn, so invalidation/reconnect/fetchQuery refetches that land
   mid-pending cannot write the not-yet-committed row back into cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>

* docs(claude-md): scope optimistic updates to same-screen field patches

Replace the blanket "mutations optimistic by default" state rule with
three scoped rules: optimistic only for predictable same-screen field
patches; navigating/confirming flows (create/delete/leave) await the
server first; chat send uses the pending-message pattern.

Aligned with TanStack Query maintainer guidance and React Router's
pending-UI criteria; the old blanket rule is what steered the original
MUL-4129 fix toward optimistic entity removal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(workspace): await delete before navigating; drop optimistic removal (MUL-4129)

Rework of the previous approach on this branch. The optimistic removal
emptied the workspace list cache at click time, while the settings page
was still mounted on the old slug — useWorkspaceId (URL slug + list
lookup) then threw 'no workspace selected'. Root cause of the original
navigate-first ordering was dual ownership of delete handling between
the initiating flow and the realtime workspace:deleted handler.

- useDeleteWorkspace: no optimistic removal, no rollback; onMutate only
  marks the delete self-initiated and captures the slug; onSuccess owns
  storage cleanup; onSettled invalidates.
- pending-delete.ts: repurposed from tombstone filter to self-initiated
  marker; kept on success (suppresses the WS echo), lifted on failure.
- use-realtime-sync: workspace:deleted no-ops for self-initiated
  deletes; it now only serves deletes initiated elsewhere.
- workspace-tab: confirm dialog stays open in loading state, navigate
  only after the DELETE succeeds; failure leaves the user in place with
  nothing to roll back. Replace throwing useWorkspaceId with
  workspace?.id + enabled gating (independent crash on external
  deletes of the current workspace).

Known debt: useLeaveWorkspace still navigates before awaiting
(member:removed has no self-initiated marker yet).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-07-07 13:45:49 +08:00
..