Skip to content

Commit eb1009d

Browse files
authored
improvement(react-query): codebase-wide audit — server-state hooks, webhook coherence, resume migration (#5024)
* improvement(react-query): codebase-wide audit — server-state hooks, webhook coherence, resume migration * chore(react-query): add static pattern linter + address review feedback - add scripts/check-react-query-patterns.ts (staleTime/signal/key-factory/inline-key enforcement) wired into CI as check:react-query; strict zone hooks/queries/**, ratchet elsewhere - fix(resume): use same-origin relative path for resume POST (getBaseUrl could cross origin on whitelabel/preview hosts and drop session cookies) — Cursor Bugbot - remove explanatory inline comments in favor of TSDoc per repo convention
1 parent 51733b8 commit eb1009d

46 files changed

Lines changed: 1048 additions & 642 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/rules/sim-queries.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,7 @@ const handler = useCallback(() => {
137137
- **Query hooks**: `useEntity`, `useEntityList`
138138
- **Mutation hooks**: `useCreateEntity`, `useUpdateEntity`, `useDeleteEntity`
139139
- **Fetch functions**: `fetchEntity`, `fetchEntities` (private)
140+
141+
## Enforcement
142+
143+
`scripts/check-react-query-patterns.ts` (`bun run check:react-query`, run in CI) statically enforces these conventions: every `useQuery`/`useInfiniteQuery`/`useSuspenseQuery` declares an explicit `staleTime`, inline `queryFn`s destructure `signal`, `queryKey`s reference a colocated factory rather than an inline literal, and every `*Keys` factory in `hooks/queries/**` exposes an `all` root key. `hooks/queries/**` is a zero-tolerance zone; the rest of `apps/sim/**` is ratcheted against `scripts/check-react-query-patterns.baseline.json`. For a genuine exception, put `// rq-lint-allow: <reason>` on the line directly above the flagged construct.

.github/workflows/test-build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ jobs:
112112
- name: Zustand v5 selector audit
113113
run: bun run check:zustand-v5
114114

115+
- name: React Query pattern audit
116+
run: bun run check:react-query
117+
115118
- name: Verify realtime prune graph
116119
run: bun run check:realtime-prune
117120

apps/sim/app/(landing)/components/demo-request/demo-request-modal.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client'
22

33
import { useState } from 'react'
4+
import { getErrorMessage } from '@sim/utils/errors'
45
import { useMutation } from '@tanstack/react-query'
56
import {
67
ChipCombobox,
@@ -128,9 +129,7 @@ export function DemoRequestModal({ children, theme = 'dark' }: DemoRequestModalP
128129
}
129130

130131
const submitError = demoMutation.isError
131-
? demoMutation.error instanceof Error
132-
? demoMutation.error.message
133-
: 'Failed to submit demo request. Please try again.'
132+
? getErrorMessage(demoMutation.error, 'Failed to submit demo request. Please try again.')
134133
: null
135134

136135
return (

apps/sim/app/api/resume/[workflowId]/[executionId]/[contextId]/route.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { createLogger } from '@sim/logger'
22
import { toError } from '@sim/utils/errors'
33
import { generateId } from '@sim/utils/id'
44
import { type NextRequest, NextResponse } from 'next/server'
5-
import { resumeWorkflowExecutionContextContract } from '@/lib/api/contracts/workflows'
5+
import {
6+
getPauseContextDetailContract,
7+
resumeWorkflowExecutionContextContract,
8+
} from '@/lib/api/contracts/workflows'
69
import { parseRequest } from '@/lib/api/server'
710
import { AuthType } from '@/lib/auth/hybrid'
811
import { getJobQueue } from '@/lib/core/async-jobs'
@@ -310,7 +313,7 @@ export const GET = withRouteHandler(
310313
params: Promise<{ workflowId: string; executionId: string; contextId: string }>
311314
}
312315
) => {
313-
const parsed = await parseRequest(resumeWorkflowExecutionContextContract, request, context)
316+
const parsed = await parseRequest(getPauseContextDetailContract, request, context)
314317
if (!parsed.success) return parsed.response
315318
const { workflowId, executionId, contextId } = parsed.data.params
316319

0 commit comments

Comments
 (0)