fix(cluster): update cached resetPassword before navigating after admin setup - #1599
fix(cluster): update cached resetPassword before navigating after admin setup#1599Devin-Holland wants to merge 1 commit into
Conversation
…in setup The reset-password mutation PATCHes central-manager, but nothing updated the react-query cluster cache — router.invalidate() only re-runs route loaders. Navigating to ClusterHome then read the same [clusterId] query with a stale resetPassword: true (10s poll), and its guard bounced the user straight back to finish-setup. Intermittent by poll timing. Set the cached flag synchronously in onSuccess (not optimistic: the CM write is awaited inside the mutation before it succeeds).
There was a problem hiding this comment.
Code Review
This pull request introduces a markClusterPasswordSet utility to synchronously update the cached cluster's resetPassword state to false upon successful setup completion, preventing navigation bounces caused by stale polling data. Unit tests have been added to verify this cache update behavior. The feedback suggests explicitly typing the setQueryData call with the Cluster generic to maintain strict type safety and prevent potential TypeScript compilation errors.
| queryClient.setQueryData( | ||
| getClusterInfoQueryOptions(clusterId).queryKey, | ||
| (cluster) => cluster && { ...cluster, resetPassword: false }, | ||
| ); |
There was a problem hiding this comment.
To preserve type safety and prevent TypeScript from inferring cluster as unknown (which can cause compilation errors under strict mode when spreading or accessing properties), explicitly type the setQueryData call with the Cluster generic.
| queryClient.setQueryData( | |
| getClusterInfoQueryOptions(clusterId).queryKey, | |
| (cluster) => cluster && { ...cluster, resetPassword: false }, | |
| ); | |
| queryClient.setQueryData<Cluster>( | |
| getClusterInfoQueryOptions(clusterId).queryKey, | |
| (cluster) => cluster && { ...cluster, resetPassword: false }, | |
| ); |
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||
kriszyp
left a comment
There was a problem hiding this comment.
One codex suggestion
🤖 Reviewed with Codex
| * finish-setup bounces straight back to it. | ||
| */ | ||
| export function markClusterPasswordSet(queryClient: QueryClient, clusterId: string) { | ||
| queryClient.setQueryData( |
There was a problem hiding this comment.
An already-running 10-second poll can still complete after setQueryData and replace this value with its stale resetPassword: true response. That recreates the redirect loop when ClusterHome renders. Please cancel the exact cluster query before applying the cache update (make this helper async and await queryClient.cancelQueries({ queryKey, exact: true }), then call setQueryData) and await the helper before navigating. A deferred-query test where the old response resolves after the update would cover the failure scenario.
— KrAIs
What
After creating the initial admin user, FinishSetup showed the "Login successful" toast but sometimes never left the setup page.
Why
The reset-password mutation PATCHes central-manager's
resetPasswordflag (awaited, so the server write is confirmed), but nothing updated the react-query cluster cache —router.invalidate()only re-runs route loaders. The subsequentnavigate('../')landed on ClusterHome, which routes oncluster.resetPasswordfrom the same[clusterId]query — still cachedtrueuntil the next 10s poll tick — so its guard bounced the user straight back tofinish-setup. Intermittent by poll timing, which is why it reproduced only sometimes.Change
New
markClusterPasswordSet(queryClient, clusterId)helper next to the query flipsresetPasswordoff in the cache; FinishSetup'sonSuccesscalls it before navigating. Not an optimistic update — the CM write has already succeeded by the timeonSuccessruns.Verification
tsc -bclean.!resetPasswordguard: both possible destinations (../and../sign-in) resolve to the cluster home for a now-connected user, so no new dead-end.— devain (Claude)