fix(web): replace actor_id self-event filtering with idempotent cache updates

actor_id identifies the user, not the browser tab. Filtering WS events
by actor_id broke multi-tab sync — other tabs of the same user would
silently miss updates. Instead, make all WS cache handlers idempotent
(dedup checks on add, no-op on duplicate merge/filter) so mutations and
WS events coexist safely without filtering.

- WSClient: pass actor_id to event handlers for future per-handler use
- use-realtime-sync: remove isSelf() gating from onAny and specific handlers
- useCreateIssue: add .some() dedup guard + onSettled invalidation
- use-issue-reactions: remove payload-level self-filter (dedup already present)
- use-issue-timeline: remove payload-level self-filter on comment:created,
  reaction:added, reaction:removed (dedup already present)
- Clean up useCallback deps that no longer reference userId

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Naiyuan Qing 2026-04-08 13:57:24 +08:00
parent 88c2f4ddc4
commit d58f6cdb33
7 changed files with 20 additions and 32 deletions

View file

@ -21,11 +21,14 @@ export function useCreateIssue() {
mutationFn: (data: CreateIssueRequest) => api.createIssue(data),
onSuccess: (newIssue) => {
qc.setQueryData<ListIssuesResponse>(issueKeys.list(wsId), (old) =>
old
old && !old.issues.some((i) => i.id === newIssue.id)
? { ...old, issues: [...old.issues, newIssue], total: old.total + 1 }
: old,
);
},
onSettled: () => {
qc.invalidateQueries({ queryKey: issueKeys.list(wsId) });
},
});
}
@ -204,6 +207,9 @@ export function useCreateComment(issueId: string) {
},
);
},
onSettled: () => {
qc.invalidateQueries({ queryKey: issueKeys.timeline(issueId) });
},
});
}