Skip to content

Commit 59a7bb5

Browse files
committed
merge: integrate TanStack Query migration and refactor template library
Resolve merge conflict with main (PR #298 TanStack Query migration). Refactor TemplateLibraryPage from Zustand useTemplateStore to TanStack Query hooks with staleTime: Infinity for static template data. Add template query keys, idle prefetch, and route chunk prefetch. Signed-off-by: Krishna Mohan <krishanmohank974@gmail.com>
2 parents deb4294 + cf77e6d commit 59a7bb5

112 files changed

Lines changed: 7559 additions & 4145 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
name: performance-review
3+
description: Review frontend code changes for performance anti-patterns and guideline compliance. Checks query hooks, stale times, bundle impact, rendering patterns, and Zustand selectors.
4+
user_invocable: true
5+
---
6+
7+
# Frontend Performance Review
8+
9+
**Reference:** `frontend/docs/performance.md`
10+
11+
---
12+
13+
## When to Invoke
14+
15+
- Before submitting a PR that adds or modifies query hooks, page components, Zustand stores, or real-time features
16+
- When the user asks for a "performance review" or "perf check"
17+
- As part of the component-development workflow for new pages
18+
19+
## Agent Instructions
20+
21+
When invoked, perform the following checks in order. Report PASS/FAIL/WARN for each. Group failures by severity: **CRITICAL** (must fix before merge), **WARNING** (should fix), **INFO** (consider).
22+
23+
### Step 1: Identify Scope
24+
25+
Read the diff or the files specified by the user. If no files specified, use `git diff --name-only` to find changed frontend files. Identify which categories apply: query hooks, page routes, stores, real-time, bundle.
26+
27+
### Step 2: Query Hook Checks
28+
29+
1. Search for `useState` + `useEffect` + `api.` within 20 lines of each other in changed files. If found: **CRITICAL** — should be a TanStack Query hook.
30+
2. Check that new `useQuery` calls reference a key from `queryKeys.ts`, not an inline array. If inline: **CRITICAL**.
31+
3. Check that new query hook files are named `use<Domain>Queries.ts` and placed in `src/hooks/queries/`. If misplaced: **WARNING**.
32+
4. Check that `useMutation` calls include `onSuccess` with `queryClient.invalidateQueries()`. If missing: **WARNING**.
33+
5. Check for `skipToken` usage on conditional queries vs. `enabled: false`. Flag `enabled: false` without `skipToken` as **WARNING**.
34+
35+
### Step 3: Stale Time Audit
36+
37+
1. For each new `useQuery`, check if `staleTime` is set explicitly or inherits the 30s default appropriately.
38+
2. Cross-reference the data type: if the query fetches components, templates, or providers — flag missing `staleTime: Infinity` as **CRITICAL**.
39+
3. For execution queries, verify they use `executionQueryOptions.ts` factories rather than inline values. Flag inconsistency as **WARNING**.
40+
4. For queries on terminal runs, verify `terminalStaleTime()` is used rather than a hardcoded number.
41+
42+
### Step 4: Bundle Impact
43+
44+
1. For each new page added to `App.tsx`: verify it uses `React.lazy(() => import(...))`. Static imports are **CRITICAL**.
45+
2. Verify new sidebar pages are added to `routePrefetchMap` in `src/lib/prefetch-routes.ts`. Missing entry is **WARNING**.
46+
3. If a new conditionally-visible component imports a library > 100KB (check for `@xterm`, `posthog-js`, `lucide-react` barrel imports): flag as **WARNING** — consider deferred load pattern.
47+
48+
### Step 5: Rendering Checks
49+
50+
1. Search for `const [*, set*] = useState` followed by `set*` inside a `useEffect` that references query data — **CRITICAL** (should use `useMemo`).
51+
2. Look for derived data calculations inline in JSX without `useMemo` involving array operations (filter, sort, reduce) — **WARNING**.
52+
3. Check for `React.memo` usage on new components in `timeline/` or `workflow/` directories that re-render frequently — **INFO** if missing.
53+
54+
### Step 6: Zustand Store Checks
55+
56+
1. Search for `const store = use<X>Store()` or destructuring from `use<X>Store()` without a selector — full store subscription. **WARNING**.
57+
2. For new stores using `persist`, verify `partialize` is present. Missing is **WARNING**.
58+
3. For new `persist` stores, verify action functions are excluded from `partialize`.
59+
60+
### Step 7: Generate Report
61+
62+
Format the output as follows:
63+
64+
```
65+
## Performance Review: [description of scope]
66+
67+
### Critical (must fix before merge)
68+
- [file:line] Description of issue. See: performance.md § [section]
69+
70+
### Warnings (should fix)
71+
- [file:line] Description of issue. See: performance.md § [section]
72+
73+
### Info (consider)
74+
- [file:line] Description. See: performance.md § [section]
75+
76+
### Passed Checks
77+
- [n] query hooks using TanStack Query correctly
78+
- [n] page routes using React.lazy
79+
- [n] Zustand selectors properly scoped
80+
- staleTime: appropriate tiers applied
81+
82+
### Summary
83+
[1-2 sentences on overall performance hygiene of the change]
84+
```
85+
86+
## Rules
87+
88+
- This is a **review only** — do NOT make code changes unless the user explicitly asks
89+
- Always cite the file and line number for each finding
90+
- Always reference `frontend/docs/performance.md` for the relevant pattern section
91+
- If no frontend files are in the diff, report "No frontend changes detected" and exit
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
name: stress-test-frontend
3+
description: Run a frontend load testing audit. Seeds data, tests all pages via Chrome DevTools MCP, records network calls, TanStack queries, DOM sizes, and generates a timestamped report.
4+
user_invocable: true
5+
---
6+
7+
# Frontend Load Testing Audit
8+
9+
**Testing plan:** `frontend/docs/load-testing-plan.md`
10+
**Previous reports:** `frontend/docs/audits/`
11+
12+
---
13+
14+
## Agent Instructions
15+
16+
When the user invokes `/stress-test-frontend`, perform a full frontend load testing audit:
17+
18+
### 1. Setup
19+
20+
1. Read the testing plan at `frontend/docs/load-testing-plan.md` for the full methodology
21+
2. Seed data: `bun backend/scripts/seed-stress-test.ts --tier medium`
22+
3. Verify nginx is responding on `localhost` (not the direct Vite port)
23+
24+
### 2. Discover Routes
25+
26+
1. Read `frontend/src/App.tsx` and extract all `<Route path="...">` entries
27+
2. Compare against the **Known Pages** table in the testing plan
28+
3. Add any new routes to the audit list; skip removed routes and note them in the report
29+
4. For parameterized routes (e.g., `/workflows/:id`), use real entities from seeded data
30+
31+
### 3. Audit Every Page
32+
33+
Follow the discovered route list (Known Pages + any new routes). For each page:
34+
35+
1. Navigate via `localhost` (nginx reverse proxy) — **never use the direct Vite dev server port**
36+
2. Wait for data to load (spinners gone, tables populated)
37+
3. Take a screenshot and save to `.context/`
38+
4. Record all fetch/XHR network requests with timing
39+
5. Extract TanStack Query cache state using the snippet in the testing plan
40+
6. Measure DOM element count: `document.querySelectorAll('*').length`
41+
7. Note anomalies: ghost queries, duplicate calls, missing pagination, large payloads
42+
43+
For Page 1 (Workflow List), also run a Chrome performance trace to get LCP, CLS, TTFB.
44+
45+
### 4. Generate Report
46+
47+
1. Compile all per-page data into a report following the format of previous reports in `frontend/docs/audits/`
48+
2. Include cross-page analysis: DOM comparison, API call counts, shared queries, pagination gaps
49+
3. Summarize findings with severity ratings (MEDIUM/LOW/INFO)
50+
4. Save the report as `frontend/docs/audits/load-audit-<YYYY-MM-DDTHH-MM>.md` using the current datetime
51+
5. If a previous report exists, note any improvements or regressions compared to the most recent one
52+
53+
### 5. Important Rules
54+
55+
- This is an **audit only** — do NOT make any code changes or fixes
56+
- All testing must go through `localhost` (nginx), not the direct Vite dev server port
57+
- Use Chrome DevTools MCP tools for all browser interaction
58+
- Save screenshots to `.context/` directory

AGENTS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,35 @@ bun --cwd backend run db:studio # View data
9898
4. **E2E Tests**: Mandatory for significant features. Place in `e2e-tests/` folder.
9999
5. **GitHub CLI**: Use `gh` for all GitHub operations (issues, PRs, actions, releases). Never use browser automation for GitHub tasks.
100100

101+
### Frontend: Read Before Writing Code
102+
103+
Before writing ANY frontend code that fetches data or adds a page, you MUST read these files first:
104+
105+
1. `frontend/docs/state.md` — Decision guide: TanStack Query vs Zustand, hook patterns, anti-patterns
106+
2. `frontend/docs/performance.md` — Stale time tiers, bundle splitting, prefetch patterns, query key architecture
107+
3. `frontend/src/lib/queryKeys.ts` — Existing query key factories (add new keys here, never inline)
108+
4. Browse `frontend/src/hooks/queries/` — Follow existing hook naming conventions (`use<Domain>Queries.ts`)
109+
110+
### Frontend Data Fetching (Mandatory)
111+
112+
6. **All API data must use TanStack Query hooks** in `frontend/src/hooks/queries/`. Never use `useState` + `useEffect` to fetch backend data — this is the single most important frontend rule.
113+
7. **Query keys** go in `frontend/src/lib/queryKeys.ts` (org-scoped, factory functions).
114+
8. **After mutations**, invalidate the relevant query cache via `queryClient.invalidateQueries()` — do not manually update local state.
115+
9. **Derive data** from query results using `useMemo`, not by copying into separate `useState`.
116+
10. **Zustand stores** are for client-only UI state (canvas, timeline, auth). Never store API data in Zustand.
117+
118+
See `frontend/docs/state.md` for patterns, anti-patterns, and the full decision guide.
119+
120+
### Frontend Performance (Mandatory)
121+
122+
See `frontend/docs/performance.md` for the complete reference with code examples.
123+
124+
11. **Every new page must use `React.lazy()`** in `App.tsx`. Add the route to `routePrefetchMap` in `src/lib/prefetch-routes.ts`.
125+
12. **Set `staleTime: Infinity` for static/reference data** (components, templates, providers). The 30s default is wrong for them.
126+
13. **Use `skipToken` for conditional queries** instead of `enabled: false` alone. See `useRunQueries.ts`.
127+
14. **Granular Zustand selectors**: `useStore((s) => s.field)`, never `const store = useStore()`.
128+
15. **No N+1 queries**: never call a query hook inside `.map()`. Use a batched endpoint (see `useMcpGroupsWithServers`).
129+
101130
---
102131

103132
## Architecture
@@ -140,6 +169,16 @@ When tasks match a skill, load it: `cat .claude/skills/<name>/SKILL.md`
140169
<description>Creating components (inline/docker). Dynamic ports, retry policies, PTY patterns, IsolatedContainerVolume.</description>
141170
<location>project</location>
142171
</skill>
172+
<skill>
173+
<name>performance-review</name>
174+
<description>Review code changes for frontend performance anti-patterns. Checks stale times, bundle splitting, Zustand selectors, N+1 queries, and React rendering.</description>
175+
<location>project</location>
176+
</skill>
177+
<skill>
178+
<name>stress-test-frontend</name>
179+
<description>Run a frontend load testing audit. Seeds data, tests all pages via Chrome DevTools MCP, records network calls, TanStack queries, DOM sizes, and generates a timestamped report.</description>
180+
<location>project</location>
181+
</skill>
143182
</available_skills>
144183

145184
</skills_system>

0 commit comments

Comments
 (0)