feat(site/src): reconcile chats-by-workspace cache across archive and watch paths - #27901
Conversation
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
e7b7c15 to
ab5794a
Compare
ab5794a to
9474956
Compare
| queryKey: chatListFamilyKey, | ||
| }); | ||
|
|
||
| // Watch events that can reorder which chat is the newest for a |
There was a problem hiding this comment.
Shortened in 4a7cea4. The production comment is now one line stating the Set purpose, and the near-duplicate rationale moved into the exhaustive-kind test comment (created/deleted have their own watch branches; title/summary/diff/context do not move updated_at ordering). Net 6 lines removed.
Reply generated by Coder Agents.
Implements Phase 2 item 5 of the chats query architecture: by-workspace cache reconciliation. Stacked on #27892; base branch
feat/chat-search-invalidation.Problem
chatsByWorkspacemappings (flatRecord<workspaceId, chatId>, IDs only, archived chats filtered server-side) go stale on archive/unarchive, workspace binding changes, and watch events (FINDINGS 2.3). Because the client cannot re-derive archived state from the cached map, the only correct repair for a stale mapping is synchronous removal plus family invalidation.Fix
removeChatFromChatsByWorkspace(queryClient, chatId)insite/src/api/queries/chats.ts: value-match removal across the by-workspace family, reference-preserving when nothing is removed (mirrors thepatchChatMessagesno-op pattern).archiveChat.onSuccessand the AgentsPageLayout archive-and-deleteonSuccesssynchronously remove the mapping; the existingonSettled/explicit invalidations then reconverge.deletedbranch removes then invalidates (remove-before-invalidate ordering);createdroot branch invalidates; merge path invalidates behind a newshouldInvalidateChatsByWorkspacepredicate (status_change,action_requiredonly;created/deletedhave their own branches, title/summary/diff/context events do not moveupdated_atordering);onOpenreconnect invalidates for convergence.useChatToolInvalidations: workspace-binding tool completion (create_workspace) also invalidates by-workspace; this is the only reconciliation path on the embed route.Confirmed exclusions
updateChatWorkspace.onMutate; the awaitedonSettledinvalidation already converges.createChatchange (already invalidates); no ACL or pin changes.Known constraints
deletedevents plus family invalidation repair the rest.patchChatworkspace-rebind branch publishes no watch event server-side, so cross-session manual rebinds converge only via the acting session'sonSettledor a WorkspacesPage remount; not fixable client-side.Testing
chats.test.ts: removal scoping and reference-preservation tests;it.eachwiring tests (archiveChat/unarchiveChat/updateChatWorkspace onSettled, createChat onSuccess invalidate by-workspace); synchronous-removal assertion forarchiveChat.onSuccess; negative assertions forupdateChatTitleandcreateChatMessage.AgentsPageLayout.test.ts: exhaustiveChatWatchEventKindtable forshouldInvalidateChatsByWorkspace.useChatToolInvalidations.test.tsx: create_workspace regression test extended with a seeded by-workspace bystander.PR generated by Coder Agents.