ginskill-init 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -0
- package/agents/developer.md +56 -0
- package/agents/frontend-design.md +69 -0
- package/agents/mobile-reviewer.md +36 -0
- package/agents/review-code.md +49 -0
- package/agents/security-scanner.md +50 -0
- package/agents/tester.md +72 -0
- package/bin/cli.js +226 -0
- package/package.json +20 -0
- package/skills/ai-asset-generator/SKILL.md +255 -0
- package/skills/ai-asset-generator/docs/gen-image.md +274 -0
- package/skills/ai-asset-generator/docs/genvideo.md +341 -0
- package/skills/ai-asset-generator/docs/remove-background.md +19 -0
- package/skills/ai-asset-generator/generate-credit-assets.mjs +180 -0
- package/skills/ai-asset-generator/generate-ginbrowser-assets.mjs +242 -0
- package/skills/ai-asset-generator/generate-sty-icon.mjs +149 -0
- package/skills/ai-asset-generator/lib/bg-remove.mjs +34 -0
- package/skills/ai-asset-generator/lib/env.mjs +38 -0
- package/skills/ai-asset-generator/lib/kie-client.mjs +88 -0
- package/skills/ai-asset-generator/scripts/scaffold-generator.mjs +203 -0
- package/skills/ai-build-ai/SKILL.md +124 -0
- package/skills/ai-build-ai/docs/agent-teams.md +293 -0
- package/skills/ai-build-ai/docs/checkpointing.md +161 -0
- package/skills/ai-build-ai/docs/create-agent.md +399 -0
- package/skills/ai-build-ai/docs/create-mcp.md +395 -0
- package/skills/ai-build-ai/docs/create-skill.md +299 -0
- package/skills/ai-build-ai/docs/headless-mode.md +614 -0
- package/skills/ai-build-ai/docs/hooks.md +578 -0
- package/skills/ai-build-ai/docs/memory-claude-md.md +375 -0
- package/skills/ai-build-ai/docs/output-styles.md +208 -0
- package/skills/ai-build-ai/docs/overview.md +162 -0
- package/skills/ai-build-ai/docs/permissions.md +391 -0
- package/skills/ai-build-ai/docs/plugins.md +396 -0
- package/skills/ai-build-ai/docs/sandbox.md +262 -0
- package/skills/ai-build-ai/scripts/load-tutorial.sh +54 -0
- package/skills/icon-generator/SKILL.md +270 -0
- package/skills/mobile-app-review/SKILL.md +321 -0
- package/skills/mobile-app-review/references/apple-review.md +132 -0
- package/skills/mobile-app-review/references/google-play-review.md +203 -0
- package/skills/mongodb/SKILL.md +667 -0
- package/skills/mongodb/references/mongoose-patterns.md +368 -0
- package/skills/nestjs-architecture/SKILL.md +1086 -0
- package/skills/nestjs-architecture/references/advanced-patterns.md +590 -0
- package/skills/performance/SKILL.md +509 -0
- package/skills/react-fsd-architecture/SKILL.md +693 -0
- package/skills/react-fsd-architecture/references/fsd-patterns.md +747 -0
- package/skills/react-query/SKILL.md +685 -0
- package/skills/react-query/references/query-patterns.md +365 -0
- package/skills/review-code/SKILL.md +321 -0
- package/skills/review-code/references/clean-code-principles.md +395 -0
- package/skills/review-code/references/frontend-patterns.md +136 -0
- package/skills/review-code/references/nestjs-patterns.md +184 -0
- package/skills/review-code/scripts/check-module.sh +201 -0
- package/skills/review-code/scripts/deep-scan.sh +604 -0
- package/skills/review-code/scripts/dep-check.sh +522 -0
- package/skills/review-code/scripts/detect-duplicates.sh +466 -0
- package/skills/review-code/scripts/format-check.sh +577 -0
- package/skills/review-code/scripts/run-review.sh +167 -0
- package/skills/review-code/scripts/scan-codebase.sh +152 -0
- package/skills/security-scanner/SKILL.md +327 -0
- package/skills/security-scanner/references/nestjs-security.md +260 -0
- package/skills/security-scanner/references/nextjs-security.md +201 -0
- package/skills/security-scanner/references/react-native-security.md +199 -0
- package/skills/security-scanner/scripts/security-scan.sh +478 -0
- package/skills/ui-ux-pro-max/SKILL.md +377 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/skills/ui-ux-pro-max/scripts/search.py +114 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Advanced React Query Patterns
|
|
2
|
+
|
|
3
|
+
Detailed reference for advanced patterns beyond the main SKILL.md. Load this when the user is working on specific advanced scenarios.
|
|
4
|
+
|
|
5
|
+
## Parallel Queries
|
|
6
|
+
|
|
7
|
+
### Independent queries in a component
|
|
8
|
+
|
|
9
|
+
Simply call multiple `useQuery` hooks — React Query fetches them in parallel:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const { data: users } = useUsers()
|
|
13
|
+
const { data: projects } = useProjects()
|
|
14
|
+
const { data: notifications } = useNotifications()
|
|
15
|
+
// All three fire simultaneously
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Dynamic parallel queries with `useQueries`
|
|
19
|
+
|
|
20
|
+
When the number of queries is dynamic (e.g., fetch details for a list of IDs):
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
const todoQueries = useQueries({
|
|
24
|
+
queries: todoIds.map(id => ({
|
|
25
|
+
queryKey: todoKeys.detail(id),
|
|
26
|
+
queryFn: () => fetchTodoById(id),
|
|
27
|
+
staleTime: 1000 * 60 * 5,
|
|
28
|
+
})),
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const allLoaded = todoQueries.every(q => q.isSuccess)
|
|
32
|
+
const allData = todoQueries.map(q => q.data).filter(Boolean)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Combine results with `combine`
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const todoQueries = useQueries({
|
|
39
|
+
queries: todoIds.map(id => ({
|
|
40
|
+
queryKey: todoKeys.detail(id),
|
|
41
|
+
queryFn: () => fetchTodoById(id),
|
|
42
|
+
})),
|
|
43
|
+
combine: (results) => ({
|
|
44
|
+
data: results.map(r => r.data).filter(Boolean),
|
|
45
|
+
isLoading: results.some(r => r.isLoading),
|
|
46
|
+
isError: results.some(r => r.isError),
|
|
47
|
+
}),
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Polling / Auto-Refetch
|
|
52
|
+
|
|
53
|
+
### Interval-based polling
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const { data } = useQuery({
|
|
57
|
+
queryKey: ['job-status', jobId],
|
|
58
|
+
queryFn: () => fetchJobStatus(jobId),
|
|
59
|
+
refetchInterval: 3000, // poll every 3 seconds
|
|
60
|
+
refetchIntervalInBackground: false, // stop when tab is hidden
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Conditional polling (stop when done)
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
const { data } = useQuery({
|
|
68
|
+
queryKey: ['job-status', jobId],
|
|
69
|
+
queryFn: () => fetchJobStatus(jobId),
|
|
70
|
+
refetchInterval: (query) => {
|
|
71
|
+
return query.state.data?.status === 'completed' ? false : 3000
|
|
72
|
+
},
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Pagination
|
|
77
|
+
|
|
78
|
+
### Basic pagination with placeholderData
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { keepPreviousData } from '@tanstack/react-query'
|
|
82
|
+
|
|
83
|
+
const [page, setPage] = useState(1)
|
|
84
|
+
|
|
85
|
+
const { data, isPlaceholderData } = useQuery({
|
|
86
|
+
queryKey: ['todos', page],
|
|
87
|
+
queryFn: () => fetchTodos(page),
|
|
88
|
+
placeholderData: keepPreviousData, // keep showing old data while new page loads
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
<Button
|
|
92
|
+
disabled={isPlaceholderData || !data?.hasNextPage}
|
|
93
|
+
onPress={() => setPage(p => p + 1)}
|
|
94
|
+
/>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Prefetch next page
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (data?.hasNextPage) {
|
|
102
|
+
queryClient.prefetchQuery({
|
|
103
|
+
queryKey: ['todos', page + 1],
|
|
104
|
+
queryFn: () => fetchTodos(page + 1),
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
}, [data, page])
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Cursor-Based Infinite Queries
|
|
111
|
+
|
|
112
|
+
### Bi-directional infinite query
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const {
|
|
116
|
+
data,
|
|
117
|
+
fetchNextPage,
|
|
118
|
+
fetchPreviousPage,
|
|
119
|
+
hasNextPage,
|
|
120
|
+
hasPreviousPage,
|
|
121
|
+
} = useInfiniteQuery({
|
|
122
|
+
queryKey: ['messages', chatId],
|
|
123
|
+
queryFn: ({ pageParam }) => fetchMessages(chatId, pageParam),
|
|
124
|
+
initialPageParam: { cursor: undefined, direction: 'forward' },
|
|
125
|
+
getNextPageParam: (lastPage) =>
|
|
126
|
+
lastPage.nextCursor ? { cursor: lastPage.nextCursor, direction: 'forward' } : undefined,
|
|
127
|
+
getPreviousPageParam: (firstPage) =>
|
|
128
|
+
firstPage.prevCursor ? { cursor: firstPage.prevCursor, direction: 'backward' } : undefined,
|
|
129
|
+
maxPages: 20, // limit stored pages
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## SSR / Hydration (Next.js)
|
|
134
|
+
|
|
135
|
+
### Prefetch on server, hydrate on client
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// app/todos/page.tsx (Server Component)
|
|
139
|
+
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'
|
|
140
|
+
|
|
141
|
+
export default async function TodosPage() {
|
|
142
|
+
const queryClient = new QueryClient()
|
|
143
|
+
|
|
144
|
+
await queryClient.prefetchQuery({
|
|
145
|
+
queryKey: todoKeys.lists(),
|
|
146
|
+
queryFn: fetchTodos,
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<HydrationBoundary state={dehydrate(queryClient)}>
|
|
151
|
+
<TodoList />
|
|
152
|
+
</HydrationBoundary>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// components/TodoList.tsx (Client Component)
|
|
157
|
+
'use client'
|
|
158
|
+
|
|
159
|
+
export function TodoList() {
|
|
160
|
+
// This will use the prefetched data — no loading state on first render
|
|
161
|
+
const { data } = useTodos()
|
|
162
|
+
return <div>{data?.map(todo => ...)}</div>
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Placeholder & Initial Data
|
|
167
|
+
|
|
168
|
+
### initialData — counted as "real" data
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// Pre-fill detail from list cache
|
|
172
|
+
useQuery({
|
|
173
|
+
queryKey: todoKeys.detail(id),
|
|
174
|
+
queryFn: () => fetchTodoById(id),
|
|
175
|
+
initialData: () => {
|
|
176
|
+
return queryClient
|
|
177
|
+
.getQueryData<Todo[]>(todoKeys.lists())
|
|
178
|
+
?.find(t => t.id === id)
|
|
179
|
+
},
|
|
180
|
+
initialDataUpdatedAt: () => {
|
|
181
|
+
return queryClient.getQueryState(todoKeys.lists())?.dataUpdatedAt
|
|
182
|
+
},
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### placeholderData — shown while loading, not cached
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
useQuery({
|
|
190
|
+
queryKey: todoKeys.detail(id),
|
|
191
|
+
queryFn: () => fetchTodoById(id),
|
|
192
|
+
placeholderData: { id, title: 'Loading...', completed: false },
|
|
193
|
+
})
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Key difference:
|
|
197
|
+
- `initialData` is persisted in cache, respects `staleTime`, counts as "real"
|
|
198
|
+
- `placeholderData` is temporary, always triggers a fetch, never cached
|
|
199
|
+
|
|
200
|
+
## Request Deduplication
|
|
201
|
+
|
|
202
|
+
React Query automatically dedupes identical queries. If 10 components call `useTodos()`, only one network request fires. All 10 share the same cache entry and re-render together.
|
|
203
|
+
|
|
204
|
+
This is automatic — no configuration needed. Just use the same query key.
|
|
205
|
+
|
|
206
|
+
## Retry & Backoff
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const queryClient = new QueryClient({
|
|
210
|
+
defaultOptions: {
|
|
211
|
+
queries: {
|
|
212
|
+
retry: 3, // retry 3 times (default)
|
|
213
|
+
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), // exponential backoff
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Disable retry for specific queries
|
|
219
|
+
useQuery({
|
|
220
|
+
queryKey: ['login'],
|
|
221
|
+
queryFn: login,
|
|
222
|
+
retry: false, // don't retry auth failures
|
|
223
|
+
})
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Query Cancellation
|
|
227
|
+
|
|
228
|
+
React Query automatically cancels queries when components unmount using `AbortSignal`:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
const { data } = useQuery({
|
|
232
|
+
queryKey: ['todos'],
|
|
233
|
+
queryFn: ({ signal }) => {
|
|
234
|
+
return fetch('/api/todos', { signal }).then(r => r.json())
|
|
235
|
+
},
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
For Axios:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
queryFn: ({ signal }) => {
|
|
243
|
+
return axios.get('/api/todos', { signal }).then(r => r.data)
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Mutation Side Effects Chain
|
|
248
|
+
|
|
249
|
+
The full lifecycle of a mutation:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
mutate() called
|
|
253
|
+
→ onMutate (optimistic update, return rollback context)
|
|
254
|
+
→ mutationFn (actual API call)
|
|
255
|
+
→ onSuccess / onError
|
|
256
|
+
→ onSettled (runs regardless of success/error)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Coordinating mutation callbacks
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// Hook-level callbacks (always run)
|
|
263
|
+
useMutation({
|
|
264
|
+
mutationFn: updateTodo,
|
|
265
|
+
onSuccess: () => { /* runs for every call */ },
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// Call-site callbacks (run for this specific call only)
|
|
269
|
+
mutation.mutate(data, {
|
|
270
|
+
onSuccess: () => { /* runs only for this call */ },
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
// Execution order: hook onSuccess → call-site onSuccess
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Testing React Query
|
|
277
|
+
|
|
278
|
+
### Setup test wrapper
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const createWrapper = () => {
|
|
282
|
+
const queryClient = new QueryClient({
|
|
283
|
+
defaultOptions: {
|
|
284
|
+
queries: {
|
|
285
|
+
retry: false, // don't retry in tests
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
return ({ children }) => (
|
|
291
|
+
<QueryClientProvider client={queryClient}>
|
|
292
|
+
{children}
|
|
293
|
+
</QueryClientProvider>
|
|
294
|
+
)
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Test a custom hook
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { renderHook, waitFor } from '@testing-library/react'
|
|
302
|
+
|
|
303
|
+
it('fetches todos', async () => {
|
|
304
|
+
const { result } = renderHook(() => useTodos(), {
|
|
305
|
+
wrapper: createWrapper(),
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
|
309
|
+
|
|
310
|
+
expect(result.current.data).toHaveLength(3)
|
|
311
|
+
})
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Mock at the network level
|
|
315
|
+
|
|
316
|
+
Prefer MSW (Mock Service Worker) over mocking `queryFn` directly — it tests the full request pipeline:
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { http, HttpResponse } from 'msw'
|
|
320
|
+
import { setupServer } from 'msw/node'
|
|
321
|
+
|
|
322
|
+
const server = setupServer(
|
|
323
|
+
http.get('/api/todos', () => {
|
|
324
|
+
return HttpResponse.json([
|
|
325
|
+
{ id: 1, title: 'Test', completed: false },
|
|
326
|
+
])
|
|
327
|
+
})
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
beforeAll(() => server.listen())
|
|
331
|
+
afterEach(() => server.resetHandlers())
|
|
332
|
+
afterAll(() => server.close())
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Performance Optimization
|
|
336
|
+
|
|
337
|
+
### Tracked queries (v5 default)
|
|
338
|
+
|
|
339
|
+
React Query v5 tracks which fields you access from the query result. If you only use `data`, the component won't re-render when `isFetching` changes. This is automatic.
|
|
340
|
+
|
|
341
|
+
### `notifyOnChangeProps`
|
|
342
|
+
|
|
343
|
+
For fine-grained control:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
useQuery({
|
|
347
|
+
queryKey: ['todos'],
|
|
348
|
+
queryFn: fetchTodos,
|
|
349
|
+
notifyOnChangeProps: ['data', 'error'], // ignore isFetching changes
|
|
350
|
+
})
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### `structuralSharing`
|
|
354
|
+
|
|
355
|
+
Enabled by default. React Query compares old and new data structurally and reuses unchanged references, preventing unnecessary re-renders in components that depend on specific parts of the data.
|
|
356
|
+
|
|
357
|
+
Disable only for very large datasets where comparison is expensive:
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
useQuery({
|
|
361
|
+
queryKey: ['huge-data'],
|
|
362
|
+
queryFn: fetchHugeData,
|
|
363
|
+
structuralSharing: false,
|
|
364
|
+
})
|
|
365
|
+
```
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-code
|
|
3
|
+
description: |
|
|
4
|
+
**Code Review**: Comprehensive code review and quality analysis for fullstack monorepos (NestJS backend, Next.js frontend, React Native mobile).
|
|
5
|
+
- MANDATORY TRIGGERS: code review, review code, review PR, review my code, check code quality, code audit, review this feature, review module, review service, review controller, find bugs, code smell, refactor suggestions, review backend, review frontend, review NestJS, review Next.js, lint check, architecture review, security review, performance review
|
|
6
|
+
- Use this skill whenever the user wants to review, audit, or analyze code quality in any part of the project, even if they just say "review this" or "check this file". Also trigger when the user mentions improving code quality, finding issues, or wants a second pair of eyes on their implementation.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Code Review Skill
|
|
10
|
+
|
|
11
|
+
Review code across fullstack monorepos with deep awareness of architecture, conventions, and tech stack. This skill understands how modern NestJS + Next.js + React Native projects are structured and what "good code" looks like — not just generic best practices.
|
|
12
|
+
|
|
13
|
+
## Project Context
|
|
14
|
+
|
|
15
|
+
Before reviewing, identify the project's structure. A typical monorepo layout:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
project-root/
|
|
19
|
+
├── backend/ # NestJS backend (MongoDB, Bull, Redis)
|
|
20
|
+
├── frontend/ # Next.js frontend (Tailwind, Zustand, React Query)
|
|
21
|
+
├── mobile/ # React Native mobile app
|
|
22
|
+
└── shared/ # Shared libraries/packages
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> **First step:** Read the project root to discover the actual directory names and structure. Don't assume — check what exists.
|
|
26
|
+
|
|
27
|
+
### Backend Architecture (NestJS)
|
|
28
|
+
|
|
29
|
+
Look for these path aliases in `tsconfig.json`:
|
|
30
|
+
- `@/*` → `src/*`
|
|
31
|
+
- `@shared/*` → `src/shared/*`
|
|
32
|
+
- `@features/*` → `src/features/*`
|
|
33
|
+
- `@core/*` → `src/core/*`
|
|
34
|
+
|
|
35
|
+
Module organization:
|
|
36
|
+
- `src/core/` — Infrastructure (config, database, logger, redis, queue, health, scheduler, exception handling)
|
|
37
|
+
- `src/features/` — Feature modules (each with controller, service, DTOs, entities)
|
|
38
|
+
- `src/shared/` — Shared utilities, DTOs, decorators, pipes, guards
|
|
39
|
+
- `src/types/` — Global type definitions
|
|
40
|
+
|
|
41
|
+
Common stack: MongoDB + Mongoose ODM, Bull queues, Redis caching, Pino logger, LangChain/LangGraph (AI agents), vector DBs, AWS S3
|
|
42
|
+
|
|
43
|
+
### Frontend Architecture (Next.js)
|
|
44
|
+
|
|
45
|
+
- Next.js 14/15 App Router with route groups for public and authenticated sections
|
|
46
|
+
- Radix UI + shadcn/ui component library
|
|
47
|
+
- Zustand stores for state, React Query for data fetching
|
|
48
|
+
- Zod validation with React Hook Form
|
|
49
|
+
|
|
50
|
+
## Review Process
|
|
51
|
+
|
|
52
|
+
When asked to review code, follow this order:
|
|
53
|
+
|
|
54
|
+
### 1. Understand Scope
|
|
55
|
+
|
|
56
|
+
Determine what the user wants reviewed:
|
|
57
|
+
- **Specific file(s)** — Focus review on those files, but check related imports/dependencies
|
|
58
|
+
- **Feature module** — Review the entire module directory (controller, service, schema, DTOs, tests)
|
|
59
|
+
- **PR/changeset** — Review the diff, focusing on what changed and its impact
|
|
60
|
+
- **General audit** — Scan for high-impact issues across the codebase
|
|
61
|
+
|
|
62
|
+
### 2. Read the Code
|
|
63
|
+
|
|
64
|
+
Read the target files thoroughly. For a NestJS module, that typically means:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
features/<module>/
|
|
68
|
+
├── <module>.module.ts # Module declaration, imports, providers
|
|
69
|
+
├── <module>.controller.ts # Route handlers, decorators, swagger docs
|
|
70
|
+
├── <module>.service.ts # Business logic
|
|
71
|
+
├── dto/ # Request/response DTOs (class-validator)
|
|
72
|
+
├── entities/ # Mongoose schemas
|
|
73
|
+
├── interfaces/ # TypeScript interfaces
|
|
74
|
+
└── __tests__/ # Unit tests (if they exist)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For AI agent modules, also look at:
|
|
78
|
+
```
|
|
79
|
+
ai-agents/core/
|
|
80
|
+
├── llm/services/ # LLM provider abstraction
|
|
81
|
+
├── providers/ # Provider configs (OpenAI, Gemini, etc.)
|
|
82
|
+
├── graph/ # LangGraph state machine
|
|
83
|
+
├── tools/ # Custom agent tools
|
|
84
|
+
├── knowledge/ # Knowledge base (embeddings)
|
|
85
|
+
└── config/ # System prompts, tool configs
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Analyze Against These Categories
|
|
89
|
+
|
|
90
|
+
Review each piece of code against these categories, prioritized from most to least impactful:
|
|
91
|
+
|
|
92
|
+
#### Critical Issues (must fix)
|
|
93
|
+
- **Security vulnerabilities**: Unsanitized inputs, SQL/NoSQL injection, exposed secrets, missing auth guards, insecure token handling
|
|
94
|
+
- **Data loss risks**: Missing error handling that could corrupt data, race conditions in concurrent operations
|
|
95
|
+
- **Production crashes**: Unhandled promise rejections, undefined access without null checks
|
|
96
|
+
|
|
97
|
+
#### Architecture & Design (SOLID Principles)
|
|
98
|
+
- **Single Responsibility (SRP)**: Each class/function should have one reason to change. Controllers validate + delegate. Services own business logic. Schemas define data shape. If a service handles both business logic AND email sending, it violates SRP.
|
|
99
|
+
- **Open/Closed (OCP)**: Code should be open for extension, closed for modification. Use strategy patterns, plugin architectures, and dependency injection instead of modifying existing classes for new behavior.
|
|
100
|
+
- **Liskov Substitution (LSP)**: Subtypes must be substitutable for their base types. If overriding a method changes expected behavior or throws unexpected errors, it violates LSP.
|
|
101
|
+
- **Interface Segregation (ISP)**: Don't force classes to implement interfaces they don't use. Prefer small, focused interfaces over fat ones. A `UserService` shouldn't implement methods for unrelated domains.
|
|
102
|
+
- **Dependency Inversion (DIP)**: Depend on abstractions, not concretions. NestJS DI naturally supports this — services should inject interfaces/tokens, not concrete implementations directly.
|
|
103
|
+
- **Circular dependencies**: Watch for modules that import each other — this is a common NestJS pitfall
|
|
104
|
+
- **Module coupling**: Features should communicate through well-defined interfaces, not reach into each other's internals
|
|
105
|
+
|
|
106
|
+
#### Clean Code & Design Principles
|
|
107
|
+
- **DRY (Don't Repeat Yourself)**: Every piece of knowledge should have a single, unambiguous representation. Flag duplicated logic across services, repeated validation patterns, copy-pasted query builders, and similar DTO structures that could share a base class.
|
|
108
|
+
- **KISS (Keep It Simple, Stupid)**: Prefer simple, readable solutions over clever ones. Flag over-engineered abstractions, unnecessary design patterns, and complex generics when a simple function would suffice.
|
|
109
|
+
- **YAGNI (You Ain't Gonna Need It)**: Flag speculative features, unused abstractions, premature optimizations, and configuration for scenarios that don't exist yet. Code should solve today's problems, not tomorrow's hypotheticals.
|
|
110
|
+
- **Meaningful naming**: Variables, functions, and classes should reveal intent. `processData()` is bad — `calculateMonthlyRevenue()` is good. Avoid abbreviations, single-letter variables (except loop counters), and names that require comments to explain.
|
|
111
|
+
- **Function size**: Functions should do one thing well. Flag functions longer than ~30 lines or with more than 3 levels of nesting. If you need comments to separate sections within a function, it should be split.
|
|
112
|
+
- **Parameter count**: Functions with more than 3 parameters should use an options object or DTO. Long parameter lists are a code smell indicating the function does too much.
|
|
113
|
+
- **Magic numbers/strings**: Hardcoded values should be extracted to named constants. `if (status === 3)` is unreadable — `if (status === OrderStatus.SHIPPED)` is clear.
|
|
114
|
+
- **Comments**: Code should be self-documenting. Comments should explain *why*, not *what*. Flag commented-out code (delete it — git has history), TODO comments without tickets, and comments that restate the code.
|
|
115
|
+
|
|
116
|
+
#### Code Smells to Flag
|
|
117
|
+
- **God classes/services**: Classes with too many responsibilities (>10 public methods, >200 lines). Split by domain concern.
|
|
118
|
+
- **Feature envy**: A method that uses more data from another class than its own. Move the method to where the data lives.
|
|
119
|
+
- **Shotgun surgery**: A single change requires editing many unrelated files. Indicates poor encapsulation — related logic is scattered.
|
|
120
|
+
- **Primitive obsession**: Using primitives (string, number) where a value object or enum would be clearer. E.g., passing `userId: string` everywhere instead of a typed `UserId`.
|
|
121
|
+
- **Long chains**: `user.getProfile().getAddress().getCity()` — violates Law of Demeter. Provide direct accessors.
|
|
122
|
+
- **Boolean blindness**: Functions with boolean parameters like `createUser(data, true, false)`. Use options objects or separate methods.
|
|
123
|
+
- **Dead code**: Unreachable code, unused imports, unexported functions that nothing calls. Remove it.
|
|
124
|
+
- **Inconsistent error handling**: Some functions throw, some return null, some return error objects. Pick one pattern per layer and stick with it.
|
|
125
|
+
|
|
126
|
+
#### Code Quality
|
|
127
|
+
- **TypeScript discipline**: Flag excessive `any` usage — encourage proper typing especially in DTOs, service return types, and public interfaces. Use `unknown` instead of `any` when the type is truly unknown, then narrow with type guards.
|
|
128
|
+
- **Error handling**: Are errors caught and handled meaningfully? Or silently swallowed? Are appropriate HTTP exceptions thrown? Follow the "fail fast" principle — detect and report errors as early as possible.
|
|
129
|
+
- **Immutability**: Prefer `const` over `let`, `readonly` properties, and immutable data patterns. Mutations make code harder to reason about and can cause subtle bugs.
|
|
130
|
+
- **Early returns**: Prefer guard clauses and early returns over deeply nested if/else chains. Flatten the happy path.
|
|
131
|
+
- **Duplication**: Identify repeated patterns that could be extracted to shared utilities, base classes, or generic helpers.
|
|
132
|
+
|
|
133
|
+
#### Performance
|
|
134
|
+
- **Database queries**: Missing indexes, N+1 query patterns, unbounded finds without pagination
|
|
135
|
+
- **Memory leaks**: Event listeners not cleaned up, streams not closed, Bull job processors not handling failures
|
|
136
|
+
- **Caching**: Is Redis caching used appropriately? Are cache keys consistent and invalidated correctly?
|
|
137
|
+
- **LLM usage**: Are token limits respected? Are retries and circuit breakers in place for AI provider calls?
|
|
138
|
+
- **Premature optimization vs. real bottlenecks**: Don't optimize code that isn't slow. But DO flag obvious O(n²) patterns, unnecessary database round-trips, and missing pagination on list endpoints.
|
|
139
|
+
|
|
140
|
+
#### Testing
|
|
141
|
+
- **Test coverage**: Does the code have tests? Are edge cases covered?
|
|
142
|
+
- **Test quality**: Are tests actually testing behavior (not just implementation details)? Each test should have a clear arrange-act-assert structure.
|
|
143
|
+
- **Mocking**: Are external dependencies properly mocked? Avoid mocking everything — test real behavior where possible.
|
|
144
|
+
- **Test naming**: Test names should describe the scenario and expected outcome: `should return 404 when item not found`, not `test1` or `createItem test`.
|
|
145
|
+
- **Test independence**: Tests should not depend on execution order or shared mutable state.
|
|
146
|
+
|
|
147
|
+
### 4. Present Findings
|
|
148
|
+
|
|
149
|
+
Structure the review as a conversation, not a laundry list. Group findings by severity and explain the reasoning behind each suggestion. For every issue raised, provide a concrete fix or improvement.
|
|
150
|
+
|
|
151
|
+
Use this format for each finding:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
**[SEVERITY] Short description**
|
|
155
|
+
File: path/to/file.ts:L42
|
|
156
|
+
|
|
157
|
+
What's happening: [explain the current code]
|
|
158
|
+
Why it matters: [explain the impact]
|
|
159
|
+
Suggested fix: [show the improved code]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Severity levels:
|
|
163
|
+
- `CRITICAL` — Security, data loss, crashes
|
|
164
|
+
- `WARNING` — Architecture issues, performance problems, missing error handling
|
|
165
|
+
- `SUGGESTION` — Code quality improvements, better patterns, readability
|
|
166
|
+
- `NITPICK` — Style, naming, minor cleanup (only include if the user wants thorough review)
|
|
167
|
+
|
|
168
|
+
### 5. Summarize
|
|
169
|
+
|
|
170
|
+
End with a brief summary:
|
|
171
|
+
- Overall health assessment (1-2 sentences)
|
|
172
|
+
- Top 3 priorities if there are many findings
|
|
173
|
+
- Any patterns that suggest systemic issues worth addressing project-wide
|
|
174
|
+
|
|
175
|
+
## Patterns to Watch For
|
|
176
|
+
|
|
177
|
+
These are common patterns and anti-patterns in NestJS/Next.js projects that deserve extra attention:
|
|
178
|
+
|
|
179
|
+
### Mongoose Schema Issues
|
|
180
|
+
- Missing `@Prop({ required: true })` on fields that shouldn't be null
|
|
181
|
+
- No `@Index()` decorators on fields used in queries
|
|
182
|
+
- Schema defaults that could cause silent data issues
|
|
183
|
+
- Using `Record<string, any>` instead of proper sub-document schemas
|
|
184
|
+
|
|
185
|
+
### NestJS Guards & Decorators
|
|
186
|
+
- Auth guards should be applied consistently (check for `@UseGuards()`)
|
|
187
|
+
- Custom decorators in shared modules should be used instead of reinventing
|
|
188
|
+
- Check that `@ApiTags()`, `@ApiOperation()` are present for Swagger docs
|
|
189
|
+
|
|
190
|
+
### AI Agent Specific
|
|
191
|
+
- LLM provider calls should use the abstraction layer, not direct SDK calls
|
|
192
|
+
- Tool definitions should follow the existing patterns
|
|
193
|
+
- System prompts should use reusable prompt section templates
|
|
194
|
+
- Knowledge base queries should go through dedicated services
|
|
195
|
+
|
|
196
|
+
### Common Anti-Patterns (All Layers)
|
|
197
|
+
- **Service locator**: Using `moduleRef.get()` or `app.get()` to grab services instead of proper constructor injection — breaks DI and makes testing harder
|
|
198
|
+
- **Anemic domain models**: DTOs/entities with only data and no behavior, while services contain all logic — consider if some logic belongs closer to the data
|
|
199
|
+
- **Catch-all error handlers**: `catch (e) { console.log(e) }` — silently swallowing errors. Errors should be logged with context and re-thrown or handled meaningfully
|
|
200
|
+
- **Barrel file bloat**: `index.ts` files that re-export everything from a module, causing circular dependencies and slow builds — only export the public API
|
|
201
|
+
- **Copy-paste inheritance**: Identical code blocks across services with minor tweaks — extract to a shared base class, generic utility, or composition pattern
|
|
202
|
+
- **Hardcoded configuration**: URLs, timeouts, limits, feature flags embedded in code instead of environment/config — use NestJS ConfigService or Next.js env
|
|
203
|
+
- **Tight coupling to external services**: Direct SDK calls scattered through business logic — wrap external services in an abstraction layer for testability and swappability
|
|
204
|
+
|
|
205
|
+
### Frontend (Next.js) Patterns
|
|
206
|
+
- Server components vs client components — `"use client"` should only be where needed
|
|
207
|
+
- API calls should go through the service layer, not directly in components
|
|
208
|
+
- Zustand stores should be small and focused, not god-stores
|
|
209
|
+
- React Query keys should follow a consistent namespace pattern
|
|
210
|
+
|
|
211
|
+
## Automated Scripts
|
|
212
|
+
|
|
213
|
+
The `scripts/` directory contains helper scripts for automated checks. These auto-detect project directories from the repository root.
|
|
214
|
+
|
|
215
|
+
### `scripts/run-review.sh` — Lint + Test Runner
|
|
216
|
+
Runs ESLint, TypeScript type-check, and test suites. Produces a JSON report.
|
|
217
|
+
```bash
|
|
218
|
+
./scripts/run-review.sh backend # lint + test backend
|
|
219
|
+
./scripts/run-review.sh frontend # lint + type-check + test frontend
|
|
220
|
+
./scripts/run-review.sh all # both
|
|
221
|
+
./scripts/run-review.sh backend --fix # auto-fix lint issues
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### `scripts/check-module.sh` — Single Module Health Check
|
|
225
|
+
Quick structural audit of a NestJS feature module — checks for module/controller/service files, DTOs, schemas, tests, Swagger docs, auth guards, and `any` usage.
|
|
226
|
+
```bash
|
|
227
|
+
./scripts/check-module.sh item
|
|
228
|
+
./scripts/check-module.sh auth
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### `scripts/scan-codebase.sh` — Full Codebase Scanner
|
|
232
|
+
Scans the entire monorepo for code quality indicators: `any` counts, TODO/FIXME, console.log usage, modules without tests, modules without Swagger docs, and the most any-heavy files.
|
|
233
|
+
```bash
|
|
234
|
+
./scripts/scan-codebase.sh
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### `scripts/detect-duplicates.sh` — Duplicate Code Detector
|
|
238
|
+
Finds DRY violations using pure bash + awk (no npm deps). Detects identical functions, similar file structures, repeated code blocks, copy-paste import patterns, and duplicate string literals. Outputs structured JSON for AI parsing.
|
|
239
|
+
```bash
|
|
240
|
+
./scripts/detect-duplicates.sh # scan all projects
|
|
241
|
+
./scripts/detect-duplicates.sh backend # scan backend only
|
|
242
|
+
./scripts/detect-duplicates.sh frontend # scan frontend only
|
|
243
|
+
./scripts/detect-duplicates.sh mobile # scan mobile only
|
|
244
|
+
./scripts/detect-duplicates.sh --min-lines 3 # minimum duplicate block size (default: 5)
|
|
245
|
+
./scripts/detect-duplicates.sh --min-repeats 2 # minimum string repetitions (default: 3)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Finding types:** `identical_function`, `similar_files`, `repeated_block`, `duplicate_imports`, `duplicate_string`
|
|
249
|
+
|
|
250
|
+
### `scripts/deep-scan.sh` — Clean Code Violations Scanner
|
|
251
|
+
Detects code smells, anti-patterns, SOLID violations, and bloaters. Pure bash — no npm install needed. Outputs structured JSON grouped by category and severity.
|
|
252
|
+
```bash
|
|
253
|
+
./scripts/deep-scan.sh # scan all projects
|
|
254
|
+
./scripts/deep-scan.sh backend # scan backend only
|
|
255
|
+
./scripts/deep-scan.sh frontend # scan frontend only
|
|
256
|
+
./scripts/deep-scan.sh mobile # scan mobile only
|
|
257
|
+
./scripts/deep-scan.sh --category bloaters # only bloater checks
|
|
258
|
+
./scripts/deep-scan.sh --category solid # only SOLID violations
|
|
259
|
+
./scripts/deep-scan.sh --category smells # only code smells
|
|
260
|
+
./scripts/deep-scan.sh --category naming # only naming issues
|
|
261
|
+
./scripts/deep-scan.sh --severity critical # only critical issues
|
|
262
|
+
./scripts/deep-scan.sh --summary # summary counts only
|
|
263
|
+
./scripts/deep-scan.sh --max-func-lines 50 # custom thresholds
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Categories & rules detected:**
|
|
267
|
+
- **Bloaters:** long files (>300 lines), long functions (>30 lines), too many parameters (>3), deep nesting (>3 levels), classes with >10 methods
|
|
268
|
+
- **SOLID:** fat controllers (DB in controllers), too many dependencies (>5), service locator (`moduleRef.get()`), manual instantiation (`new Service()`)
|
|
269
|
+
- **Smells:** empty catch blocks, console.log in production, magic numbers, hardcoded URLs/emails, `as any`, boolean params, TODO without ticket, commented-out code
|
|
270
|
+
- **Naming:** single-letter variables, generic names (`data`, `result`, `temp`, `info`, `item`)
|
|
271
|
+
|
|
272
|
+
**Exit codes:** 0 = clean, 1 = warnings found, 2 = critical issues found
|
|
273
|
+
|
|
274
|
+
### `scripts/dep-check.sh` — Dependency & Import Analyzer
|
|
275
|
+
Detects circular dependencies, unused exports, orphan files, and import boundary violations. Pure bash — no npm deps.
|
|
276
|
+
```bash
|
|
277
|
+
./scripts/dep-check.sh # scan all projects
|
|
278
|
+
./scripts/dep-check.sh backend # scan backend only
|
|
279
|
+
./scripts/dep-check.sh --check circular # only circular dependency detection
|
|
280
|
+
./scripts/dep-check.sh --check unused # only unused exports
|
|
281
|
+
./scripts/dep-check.sh --check orphans # only orphan files (never imported)
|
|
282
|
+
./scripts/dep-check.sh --check boundaries # only import boundary violations
|
|
283
|
+
./scripts/dep-check.sh --summary # summary counts only
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Check types:**
|
|
287
|
+
- **Circular:** mutual imports (A<->B), self-imports, cross-feature imports in NestJS modules
|
|
288
|
+
- **Unused:** exported symbols never imported by any other file
|
|
289
|
+
- **Orphans:** files never imported by anything (potential dead code)
|
|
290
|
+
- **Boundaries:** cross-project imports, test utilities in production, deep relative imports (4+ levels)
|
|
291
|
+
|
|
292
|
+
**Exit codes:** 0 = clean, 1 = issues found, 2 = critical issues (cross-project imports)
|
|
293
|
+
|
|
294
|
+
### `scripts/format-check.sh` — Format & Style Consistency Checker
|
|
295
|
+
Detects config drift, import ordering violations, file naming issues, and inconsistent patterns across the monorepo.
|
|
296
|
+
```bash
|
|
297
|
+
./scripts/format-check.sh # scan all projects
|
|
298
|
+
./scripts/format-check.sh backend # scan backend only
|
|
299
|
+
./scripts/format-check.sh --check configs # only config drift detection
|
|
300
|
+
./scripts/format-check.sh --check imports # only import ordering
|
|
301
|
+
./scripts/format-check.sh --check naming # only file naming conventions
|
|
302
|
+
./scripts/format-check.sh --check patterns # only pattern consistency
|
|
303
|
+
./scripts/format-check.sh --summary # summary counts only
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Check types:**
|
|
307
|
+
- **Configs:** ESLint format drift (legacy vs flat), Prettier inconsistencies (quotes, semi, width), TypeScript strict mode, missing configs
|
|
308
|
+
- **Imports:** external-after-relative ordering, wildcard imports (tree-shaking impact)
|
|
309
|
+
- **Naming:** camelCase files, PascalCase non-components, special characters, mixed test conventions (.spec vs .test)
|
|
310
|
+
- **Patterns:** mixed export styles, mixed async patterns (.then vs await), console.log over logger, string concatenation over templates
|
|
311
|
+
|
|
312
|
+
## References
|
|
313
|
+
|
|
314
|
+
For deeper review of specific areas, read these files:
|
|
315
|
+
|
|
316
|
+
**Architecture patterns (in `references/`):**
|
|
317
|
+
- `references/clean-code-principles.md` — SOLID, DRY, KISS, YAGNI with practical TypeScript examples, code smells catalog, anti-patterns, and refactoring recipes
|
|
318
|
+
- `references/nestjs-patterns.md` — NestJS module structure, controller/service conventions, Mongoose schemas, DTOs, error handling, auth guards, AI agent patterns
|
|
319
|
+
- `references/frontend-patterns.md` — Next.js App Router, component patterns, Zustand state, React Query data fetching, form handling, Tailwind styling
|
|
320
|
+
|
|
321
|
+
Read these reference files when doing an in-depth review of a specific area.
|