Skip to content

fix(chat): invalidate deployment queries after a chat mutation - #6223

Merged
waleedlatif1 merged 1 commit into
stagingfrom
fix/chat-update-deployment-invalidation
Aug 3, 2026
Merged

fix(chat): invalidate deployment queries after a chat mutation#6223
waleedlatif1 merged 1 commit into
stagingfrom
fix/chat-update-deployment-invalidation

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • PATCH /api/chat/manage/[id] calls performFullDeploy when the workflow has drifted from its active deployment (route.ts:183-190), so editing a chat can mint a new deployment version.
  • useUpdateChat invalidated only chatStatus and chatDetail, so deploymentKeys.info / versions / deployedState went stale. The deployment panel kept showing the previous version and a stale "needs redeployment" indicator until the 30s/5min staleTime expired or the window refocused.
  • Both chat mutations now route through invalidateDeploymentQueries, the shared helper the rest of the deployment surface uses (useUndeployWorkflow follows the same pattern).
  • That also picks up deployedState, which useCreateChat's hand-rolled list omitted even though performChatDeploy replaces the deployed workflow state — so the deployed-state diff viewer could show stale content after deploying a chat.

Failure scenario

Edit a chat's welcome message while the workflow draft has drifted → the PATCH redeploys to v4 → the deployment panel still shows v3 as latest, with the redeploy prompt still visible.

Type of Change

  • Bug fix

Testing

New hooks/queries/chats.test.tsx covers both mutations, following the mcp.test.tsx render-hook pattern. Verified to fail against the previous invalidation (reverting useUpdateChat turns the test red). 115 tests pass across hooks/queries; typecheck and lint clean.

Not exercised in a live browser — the assertion is on which query keys get invalidated.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

PATCH /api/chat/manage/[id] calls performFullDeploy when the workflow has
drifted from its active deployment, so editing a chat can mint a new
deployment version. useUpdateChat invalidated only chatStatus and
chatDetail, leaving the deployment panel showing the previous version and
a stale "needs redeployment" indicator until the staleTime expired.

Both mutations now route through invalidateDeploymentQueries, the shared
helper the rest of the deployment surface uses. That also picks up
deployedState, which useCreateChat's hand-rolled list had omitted even
though performChatDeploy replaces the deployed workflow state.

Tests cover both mutations and were verified to fail against the previous
invalidation.
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 3, 2026 7:48pm

Request Review

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Client-side cache invalidation only; no API or auth changes. Low risk of incorrect UI refresh behavior if the helper’s key set is wrong.

Overview
Chat create/update mutations can trigger a full redeploy when the workflow draft has drifted, but React Query cache invalidation only refreshed chat status/detail—so the deployment panel could keep showing an old version and a stale “needs redeployment” state until staleTime or refocus.

useCreateChat and useUpdateChat now call invalidateDeploymentQueries (the same helper used elsewhere on the deployment surface) instead of hand-picking keys. That also refreshes deployedState, which create’s previous invalidation list omitted.

useUpdateChat still invalidates chatDetail for the edited chat, then runs the shared deployment invalidation for the workflow.

Adds chats.test.tsx with hook tests asserting both mutations invoke invalidateDeploymentQueries with the workflow id.

Reviewed by Cursor Bugbot for commit e2dc391. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR routes chat creation and update cache reconciliation through the shared deployment invalidation helper, ensuring deployment information, versions, deployed state, and chat status are refreshed after either mutation.

  • Replaces hand-written deployment invalidations in useCreateChat.
  • Expands useUpdateChat invalidation while preserving chat-detail reconciliation.
  • Adds mutation-hook tests confirming both paths invoke the shared helper with the workflow ID.

Confidence Score: 5/5

The PR appears safe to merge, with the intended deployment cache refresh covered by both integration-level hook tests and direct helper key-coverage tests.

The shared helper preserves every deployment query previously invalidated by these mutations, adds the missing deployed-state and update-related deployment keys, and retains update-chat detail invalidation.

Important Files Changed

Filename Overview
apps/sim/hooks/queries/chats.ts Both chat mutations now use the shared, independently tested deployment invalidation boundary without dropping their prior cache invalidations.
apps/sim/hooks/queries/chats.test.tsx New hook tests verify that create and update mutations invoke deployment invalidation for the affected workflow.

Reviews (1): Last reviewed commit: "fix(chat): invalidate deployment queries..." | Re-trigger Greptile

@waleedlatif1
waleedlatif1 merged commit b0491f1 into staging Aug 3, 2026
21 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/chat-update-deployment-invalidation branch August 3, 2026 19:52
waleedlatif1 added a commit that referenced this pull request Aug 3, 2026
renderHookWithClient created a React root per test but never tore it
down, so trees stayed mounted with live QueryClient observers until
worker teardown and async notifications could cross test boundaries.

Audited every test in the repo using createRoot: 51 of 53 already
unmount. The two that did not were both mine — voice.test.tsx here and
chats.test.tsx from #6223 — so both are fixed and the pattern is now
uniform.
waleedlatif1 added a commit that referenced this pull request Aug 3, 2026
* refactor(voice): load STT availability through React Query

useSpeechToText fetched `/api/settings/voice` inside an effect and stored
the result in useState behind a hand-rolled mountedRef guard: no cache, no
dedupe across mounts, and no AbortSignal, so the response was fetched and
parsed even after unmount. Two simultaneously mounted consumers issued two
requests. It also bypassed hooks/queries/**, which is where every other
server read in the app lives — and it escaped `check:react-query`, whose
audit only covers useQuery/useMutation call sites.

The value is server env read at request time, so it cannot change within a
session; the new hook uses an infinite staleTime and a caller-controlled
`enabled` so clients without the audio APIs never issue the request.

Hydration is unchanged: SSR renders unavailable, and the first client
render still resolves unavailable because `data` is undefined until the
fetch settles. No initialData, deliberately — adding it would break that.

mountedRef stays; it is still load-bearing for the streaming lifecycle.

* test(queries): unmount rendered roots between tests

renderHookWithClient created a React root per test but never tore it
down, so trees stayed mounted with live QueryClient observers until
worker teardown and async notifications could cross test boundaries.

Audited every test in the repo using createRoot: 51 of 53 already
unmount. The two that did not were both mine — voice.test.tsx here and
chats.test.tsx from #6223 — so both are fixed and the pattern is now
uniform.

* fix(voice): let a failed STT probe recover on a later mount

The app QueryClient sets retryOnMount: false and retry: 1, and
refetchOnWindowFocus only refetches stale queries — which an infinite
staleTime never becomes. So one transient failure cached the error for
the life of the client and hid the mic until a full page reload.

The effect this replaced refetched on every run, so retryOnMount: true
restores parity: no refetch after success, a retry per mount after
failure. Test asserts recovery under the app's real query defaults and
fails without the override.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant