@persistadev/mcp-server 3.3.7 → 3.3.8

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.
@@ -0,0 +1,1430 @@
1
+ "use strict";
2
+ /**
3
+ * PERSISTA KNOWLEDGE BASE v2.0
4
+ * ═══════════════════════════════════════════════════════════════
5
+ * A comprehensive collection of development knowledge including:
6
+ * - AI Prompts for every task
7
+ * - Design systems & tokens
8
+ * - Architecture patterns
9
+ * - Checklists for launch, security, a11y, code review
10
+ * - Code patterns & hooks
11
+ * - Boilerplates & templates
12
+ * - Workflows & processes
13
+ * - Best practices for every framework
14
+ * ═══════════════════════════════════════════════════════════════
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.KNOWLEDGE_BASE = void 0;
18
+ exports.KNOWLEDGE_BASE = [
19
+ // ═══════════════════════════════════════════════════════════════
20
+ // 🎯 AI PROMPTS - Elite development prompts
21
+ // ═══════════════════════════════════════════════════════════════
22
+ // React Prompts
23
+ { domain: 'prompts', topic: 'react', update_type: 'prompt', title: 'Generate React Component', content: `Create a React component called [ComponentName] that:
24
+ - Uses TypeScript with proper type definitions
25
+ - Follows single responsibility principle
26
+ - Includes JSDoc comments for props
27
+ - Uses CSS modules for styling
28
+ - Handles loading, error, and empty states
29
+ - Is accessible (ARIA labels, keyboard nav)
30
+ - Includes basic unit test file
31
+
32
+ Props needed: [describe]
33
+ Functionality: [describe]` },
34
+ { domain: 'prompts', topic: 'react', update_type: 'prompt', title: 'Refactor React Component', content: `Refactor this React component to:
35
+ 1. Extract reusable logic into custom hooks
36
+ 2. Memoize expensive computations with useMemo
37
+ 3. Optimize re-renders with React.memo
38
+ 4. Split into smaller components if over 150 lines
39
+ 5. Add proper TypeScript types (no 'any')
40
+ 6. Improve accessibility
41
+ 7. Add error boundaries if needed
42
+
43
+ Explain each change and why.` },
44
+ { domain: 'prompts', topic: 'react', update_type: 'prompt', title: 'Debug React Performance', content: `This React app is slow. Help debug:
45
+ 1. Identify unnecessary re-renders using React DevTools
46
+ 2. Find expensive computations to memoize
47
+ 3. Detect prop drilling that needs Context
48
+ 4. Spot missing keys in lists
49
+ 5. Find components to lazy load
50
+ 6. Check for memory leaks in useEffect
51
+
52
+ For each issue: problem, why it's slow, fix with code.` },
53
+ { domain: 'prompts', topic: 'react', update_type: 'prompt', title: 'Create Custom Hook', content: `Create a custom React hook called [useName] that:
54
+ - Follows the Rules of Hooks
55
+ - Has proper TypeScript types
56
+ - Handles cleanup in useEffect
57
+ - Is reusable across components
58
+ - Includes error handling
59
+ - Has JSDoc documentation
60
+
61
+ Purpose: [describe]
62
+ Inputs: [describe]
63
+ Returns: [describe]` },
64
+ { domain: 'prompts', topic: 'react', update_type: 'prompt', title: 'Convert Class to Function', content: `Convert this class component to a functional component:
65
+ 1. Replace state with useState
66
+ 2. Convert lifecycle methods to useEffect
67
+ 3. Move instance methods to useCallback
68
+ 4. Use useMemo for derived state
69
+ 5. Keep same external API
70
+ 6. Add TypeScript types
71
+ 7. Test behavior is identical` },
72
+ // TypeScript Prompts
73
+ { domain: 'prompts', topic: 'typescript', update_type: 'prompt', title: 'Type This JavaScript', content: `Convert this JavaScript to TypeScript:
74
+ 1. Add types for all variables, params, returns
75
+ 2. Create interfaces for complex objects
76
+ 3. Use generics where appropriate
77
+ 4. Add type guards for runtime checking
78
+ 5. Use strict null checks
79
+ 6. No 'any' - use 'unknown' if needed
80
+ 7. Export types consumers might need` },
81
+ { domain: 'prompts', topic: 'typescript', update_type: 'prompt', title: 'Create Type-Safe API', content: `Create a type-safe API client:
82
+ 1. Full TypeScript types for requests/responses
83
+ 2. Type-safe path params and query strings
84
+ 3. Proper error types and handling
85
+ 4. Generic fetch wrapper with JSON parsing
86
+ 5. Request/response interceptors
87
+ 6. Retry logic with exponential backoff
88
+ 7. Cancel token support` },
89
+ { domain: 'prompts', topic: 'typescript', update_type: 'prompt', title: 'Fix TypeScript Errors', content: `Fix these TypeScript errors:
90
+ 1. Explain what each error means
91
+ 2. Show the incorrect code
92
+ 3. Show the corrected code
93
+ 4. Explain why the fix works
94
+ 5. Suggest stricter types if applicable
95
+ 6. Check for potential runtime issues the types might miss` },
96
+ { domain: 'prompts', topic: 'typescript', update_type: 'prompt', title: 'Create Type Utilities', content: `Create TypeScript utility types for:
97
+ 1. DeepPartial<T> - all nested props optional
98
+ 2. DeepRequired<T> - all nested props required
99
+ 3. PickByType<T, U> - pick props of certain type
100
+ 4. Mutable<T> - remove readonly
101
+ 5. NonNullableProps<T> - remove null/undefined
102
+ 6. Include usage examples for each` },
103
+ // Next.js Prompts
104
+ { domain: 'prompts', topic: 'nextjs', update_type: 'prompt', title: 'Create Next.js Page', content: `Create a Next.js App Router page for [route]:
105
+ 1. Server Component by default
106
+ 2. Proper metadata export for SEO
107
+ 3. Loading state with loading.tsx
108
+ 4. Error handling with error.tsx
109
+ 5. generateStaticParams if dynamic
110
+ 6. Parallel data fetching
111
+ 7. Proper TypeScript types
112
+ 8. Accessible and responsive` },
113
+ { domain: 'prompts', topic: 'nextjs', update_type: 'prompt', title: 'Create Server Action', content: `Create a Next.js Server Action:
114
+ 1. 'use server' directive at top
115
+ 2. Zod validation for all inputs
116
+ 3. Proper error handling with try/catch
117
+ 4. Revalidate affected paths
118
+ 5. Return typed response
119
+ 6. Rate limiting consideration
120
+ 7. Auth check with getServerSession` },
121
+ { domain: 'prompts', topic: 'nextjs', update_type: 'prompt', title: 'Optimize Next.js App', content: `Optimize this Next.js app:
122
+ 1. Audit with next build --analyze
123
+ 2. Identify client vs server components
124
+ 3. Add dynamic imports for heavy components
125
+ 4. Optimize images with next/image
126
+ 5. Implement ISR where appropriate
127
+ 6. Add proper caching headers
128
+ 7. Check Core Web Vitals` },
129
+ // Database Prompts
130
+ { domain: 'prompts', topic: 'database', update_type: 'prompt', title: 'Design Database Schema', content: `Design a database schema for [feature]:
131
+ 1. Normalized (3NF unless justified)
132
+ 2. Proper foreign keys with ON DELETE
133
+ 3. Indexes for common queries
134
+ 4. Timestamps (created_at, updated_at)
135
+ 5. Soft delete if needed (deleted_at)
136
+ 6. UUID primary keys
137
+ 7. RLS policies for Supabase
138
+
139
+ Output as SQL CREATE statements with comments.` },
140
+ { domain: 'prompts', topic: 'database', update_type: 'prompt', title: 'Optimize SQL Query', content: `Optimize this SQL query:
141
+ 1. Analyze with EXPLAIN ANALYZE
142
+ 2. Check for missing indexes
143
+ 3. Identify N+1 patterns
144
+ 4. Consider denormalization trade-offs
145
+ 5. Suggest pagination if large result
146
+ 6. Check for proper JOIN types
147
+ 7. Show before/after performance` },
148
+ { domain: 'prompts', topic: 'database', update_type: 'prompt', title: 'Write Supabase RLS', content: `Write Row Level Security policies for [table]:
149
+ 1. Enable RLS first
150
+ 2. SELECT policy for read access
151
+ 3. INSERT policy with auth checks
152
+ 4. UPDATE policy scoped to owner
153
+ 5. DELETE policy if needed
154
+ 6. Consider service role bypass
155
+ 7. Test each policy` },
156
+ // Code Review Prompts
157
+ { domain: 'prompts', topic: 'review', update_type: 'prompt', title: 'Full Code Review', content: `Review this code thoroughly:
158
+
159
+ ## Security
160
+ - SQL injection, XSS, CSRF
161
+ - Data exposure, auth issues
162
+ - Secrets in code
163
+
164
+ ## Performance
165
+ - N+1 queries, missing indexes
166
+ - Memory leaks, bundle size
167
+ - Unnecessary re-renders
168
+
169
+ ## Maintainability
170
+ - Naming conventions
171
+ - Single responsibility
172
+ - DRY violations
173
+ - Code complexity (cyclomatic)
174
+
175
+ ## TypeScript
176
+ - No 'any' usage
177
+ - Proper null handling
178
+ - Correct generic usage
179
+
180
+ Provide specific line-by-line feedback with fixes.` },
181
+ { domain: 'prompts', topic: 'review', update_type: 'prompt', title: 'Security Audit', content: `Security audit this code:
182
+ 1. Authentication vulnerabilities
183
+ 2. Authorization bypass risks
184
+ 3. Input validation gaps
185
+ 4. Output encoding issues
186
+ 5. Sensitive data exposure
187
+ 6. Dependency vulnerabilities
188
+ 7. Error message information leaks
189
+
190
+ For each issue: severity, impact, fix.` },
191
+ // Debugging Prompts
192
+ { domain: 'prompts', topic: 'debugging', update_type: 'prompt', title: 'Debug This Error', content: `Debug this error:
193
+
194
+ Error: [paste error]
195
+ Context: [what you were doing]
196
+ Environment: [dev/prod, versions]
197
+
198
+ 1. Explain what this error means
199
+ 2. List most common causes (ranked by likelihood)
200
+ 3. Debugging steps to find root cause
201
+ 4. Give fix with code example
202
+ 5. How to prevent this in future` },
203
+ { domain: 'prompts', topic: 'debugging', update_type: 'prompt', title: 'Debug Memory Leak', content: `This app has a memory leak. Help find it:
204
+ 1. How to profile memory in Chrome DevTools
205
+ 2. Common React memory leak patterns
206
+ 3. Event listener cleanup
207
+ 4. Subscription cleanup
208
+ 5. Timer cleanup
209
+ 6. DOM reference cleanup
210
+ 7. Show fix for each pattern` },
211
+ { domain: 'prompts', topic: 'debugging', update_type: 'prompt', title: 'Debug Slow Page', content: `This page is slow. Diagnose:
212
+ 1. Run Lighthouse audit
213
+ 2. Check Network tab for slow requests
214
+ 3. Look for layout thrashing
215
+ 4. Find large JavaScript bundles
216
+ 5. Identify render-blocking resources
217
+ 6. Check for hydration issues
218
+ 7. Prioritize fixes by impact` },
219
+ // Testing Prompts
220
+ { domain: 'prompts', topic: 'testing', update_type: 'prompt', title: 'Write Unit Tests', content: `Write unit tests for this code:
221
+ 1. Test happy path
222
+ 2. Test edge cases
223
+ 3. Test error handling
224
+ 4. Mock external dependencies
225
+ 5. Use describe/it structure
226
+ 6. Aim for high coverage
227
+ 7. Use meaningful test names
228
+
229
+ Framework: Jest + React Testing Library` },
230
+ { domain: 'prompts', topic: 'testing', update_type: 'prompt', title: 'Write E2E Tests', content: `Write E2E tests for this feature:
231
+ 1. User flows to test
232
+ 2. Setup/teardown database state
233
+ 3. Mock external APIs
234
+ 4. Test happy path
235
+ 5. Test error states
236
+ 6. Test edge cases
237
+ 7. Keep tests independent
238
+
239
+ Framework: Playwright` },
240
+ // Architecture Prompts
241
+ { domain: 'prompts', topic: 'architecture', update_type: 'prompt', title: 'Design System Architecture', content: `Design the architecture for [system]:
242
+ 1. Requirements analysis
243
+ 2. Component breakdown
244
+ 3. Data flow diagram
245
+ 4. API design
246
+ 5. Database schema
247
+ 6. Deployment strategy
248
+ 7. Scalability considerations
249
+ 8. Security measures
250
+ 9. Monitoring plan` },
251
+ { domain: 'prompts', topic: 'architecture', update_type: 'prompt', title: 'Microservices Design', content: `Design microservices for [domain]:
252
+ 1. Service boundaries (DDD approach)
253
+ 2. Communication patterns (sync/async)
254
+ 3. Data ownership
255
+ 4. API contracts
256
+ 5. Event-driven patterns
257
+ 6. Service discovery
258
+ 7. Fault tolerance
259
+ 8. Deployment topology` },
260
+ // ═══════════════════════════════════════════════════════════════
261
+ // 🎨 DESIGN SYSTEMS
262
+ // ═══════════════════════════════════════════════════════════════
263
+ { domain: 'design', topic: 'colors', update_type: 'design_system', title: 'Modern SaaS Light Palette', content: `:root {
264
+ /* Primary */
265
+ --primary-50: #faf5ff;
266
+ --primary-100: #f3e8ff;
267
+ --primary-200: #e9d5ff;
268
+ --primary-500: #a855f7;
269
+ --primary-600: #9333ea;
270
+ --primary-700: #7e22ce;
271
+
272
+ /* Neutrals */
273
+ --gray-50: #f8fafc;
274
+ --gray-100: #f1f5f9;
275
+ --gray-200: #e2e8f0;
276
+ --gray-300: #cbd5e1;
277
+ --gray-400: #94a3b8;
278
+ --gray-500: #64748b;
279
+ --gray-600: #475569;
280
+ --gray-700: #334155;
281
+ --gray-800: #1e293b;
282
+ --gray-900: #0f172a;
283
+
284
+ /* Semantic */
285
+ --success: #10b981;
286
+ --warning: #f59e0b;
287
+ --error: #ef4444;
288
+ --info: #3b82f6;
289
+ }` },
290
+ { domain: 'design', topic: 'colors', update_type: 'design_system', title: 'Dark Mode Palette', content: `[data-theme="dark"] {
291
+ --bg-primary: #09090b;
292
+ --bg-secondary: #18181b;
293
+ --bg-tertiary: #27272a;
294
+ --bg-elevated: #3f3f46;
295
+
296
+ --text-primary: #fafafa;
297
+ --text-secondary: #a1a1aa;
298
+ --text-muted: #71717a;
299
+
300
+ --border-subtle: #27272a;
301
+ --border-default: #3f3f46;
302
+ --border-strong: #52525b;
303
+
304
+ --accent: #a855f7;
305
+ --accent-hover: #9333ea;
306
+
307
+ /* Adjust semantic colors for dark */
308
+ --success: #34d399;
309
+ --warning: #fbbf24;
310
+ --error: #f87171;
311
+ --info: #60a5fa;
312
+ }` },
313
+ { domain: 'design', topic: 'typography', update_type: 'design_system', title: 'Typography Scale', content: `:root {
314
+ /* Font Families */
315
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
316
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
317
+ --font-display: 'Cal Sans', 'Inter', sans-serif;
318
+
319
+ /* Size Scale (rem) */
320
+ --text-xs: 0.75rem; /* 12px */
321
+ --text-sm: 0.875rem; /* 14px */
322
+ --text-base: 1rem; /* 16px */
323
+ --text-lg: 1.125rem; /* 18px */
324
+ --text-xl: 1.25rem; /* 20px */
325
+ --text-2xl: 1.5rem; /* 24px */
326
+ --text-3xl: 1.875rem; /* 30px */
327
+ --text-4xl: 2.25rem; /* 36px */
328
+ --text-5xl: 3rem; /* 48px */
329
+
330
+ /* Line Heights */
331
+ --leading-none: 1;
332
+ --leading-tight: 1.25;
333
+ --leading-snug: 1.375;
334
+ --leading-normal: 1.5;
335
+ --leading-relaxed: 1.625;
336
+
337
+ /* Font Weights */
338
+ --font-normal: 400;
339
+ --font-medium: 500;
340
+ --font-semibold: 600;
341
+ --font-bold: 700;
342
+ }` },
343
+ { domain: 'design', topic: 'spacing', update_type: 'design_system', title: 'Spacing & Layout', content: `:root {
344
+ /* Spacing Scale */
345
+ --space-0: 0;
346
+ --space-1: 0.25rem; /* 4px */
347
+ --space-2: 0.5rem; /* 8px */
348
+ --space-3: 0.75rem; /* 12px */
349
+ --space-4: 1rem; /* 16px */
350
+ --space-5: 1.25rem; /* 20px */
351
+ --space-6: 1.5rem; /* 24px */
352
+ --space-8: 2rem; /* 32px */
353
+ --space-10: 2.5rem; /* 40px */
354
+ --space-12: 3rem; /* 48px */
355
+ --space-16: 4rem; /* 64px */
356
+ --space-20: 5rem; /* 80px */
357
+
358
+ /* Border Radius */
359
+ --radius-sm: 4px;
360
+ --radius-md: 8px;
361
+ --radius-lg: 12px;
362
+ --radius-xl: 16px;
363
+ --radius-2xl: 24px;
364
+ --radius-full: 9999px;
365
+
366
+ /* Shadows */
367
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
368
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
369
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
370
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
371
+ --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
372
+ }` },
373
+ { domain: 'design', topic: 'animations', update_type: 'design_system', title: 'Animation Tokens', content: `:root {
374
+ /* Durations */
375
+ --duration-fast: 150ms;
376
+ --duration-normal: 200ms;
377
+ --duration-slow: 300ms;
378
+ --duration-slower: 500ms;
379
+
380
+ /* Easings */
381
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
382
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
383
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
384
+ --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
385
+
386
+ /* Common Transitions */
387
+ --transition-colors: color var(--duration-fast) var(--ease-in-out),
388
+ background-color var(--duration-fast) var(--ease-in-out),
389
+ border-color var(--duration-fast) var(--ease-in-out);
390
+ --transition-transform: transform var(--duration-normal) var(--ease-out);
391
+ --transition-opacity: opacity var(--duration-normal) var(--ease-in-out);
392
+ --transition-all: all var(--duration-normal) var(--ease-in-out);
393
+ }
394
+
395
+ /* Keyframes */
396
+ @keyframes fadeIn {
397
+ from { opacity: 0; }
398
+ to { opacity: 1; }
399
+ }
400
+
401
+ @keyframes slideUp {
402
+ from { opacity: 0; transform: translateY(10px); }
403
+ to { opacity: 1; transform: translateY(0); }
404
+ }
405
+
406
+ @keyframes spin {
407
+ to { transform: rotate(360deg); }
408
+ }
409
+
410
+ @keyframes pulse {
411
+ 50% { opacity: 0.5; }
412
+ }` },
413
+ { domain: 'design', topic: 'components', update_type: 'design_system', title: 'Button Variants', content: `.btn {
414
+ display: inline-flex;
415
+ align-items: center;
416
+ justify-content: center;
417
+ gap: var(--space-2);
418
+ padding: var(--space-2) var(--space-4);
419
+ font-size: var(--text-sm);
420
+ font-weight: var(--font-medium);
421
+ border-radius: var(--radius-md);
422
+ transition: var(--transition-colors);
423
+ cursor: pointer;
424
+ }
425
+
426
+ .btn-primary {
427
+ background: var(--primary-600);
428
+ color: white;
429
+ border: none;
430
+ }
431
+ .btn-primary:hover { background: var(--primary-700); }
432
+
433
+ .btn-secondary {
434
+ background: transparent;
435
+ color: var(--gray-700);
436
+ border: 1px solid var(--gray-300);
437
+ }
438
+ .btn-secondary:hover { background: var(--gray-50); }
439
+
440
+ .btn-ghost {
441
+ background: transparent;
442
+ color: var(--gray-600);
443
+ border: none;
444
+ }
445
+ .btn-ghost:hover { background: var(--gray-100); }
446
+
447
+ .btn-danger {
448
+ background: var(--error);
449
+ color: white;
450
+ border: none;
451
+ }
452
+ .btn-danger:hover { background: #dc2626; }` },
453
+ // ═══════════════════════════════════════════════════════════════
454
+ // 📁 ARCHITECTURE
455
+ // ═══════════════════════════════════════════════════════════════
456
+ { domain: 'architecture', topic: 'react', update_type: 'architecture', title: 'React Project Structure', content: `src/
457
+ ├── components/
458
+ │ ├── ui/ # Reusable UI (Button, Input, Modal)
459
+ │ ├── features/ # Feature-specific components
460
+ │ ├── layouts/ # Layout components
461
+ │ └── providers/ # Context providers
462
+ ├── hooks/ # Custom hooks
463
+ ├── lib/
464
+ │ ├── api.ts # API client
465
+ │ ├── utils.ts # Utility functions
466
+ │ └── constants.ts # App constants
467
+ ├── stores/ # State management (Zustand/Jotai)
468
+ ├── types/ # TypeScript types
469
+ ├── styles/ # Global CSS, themes
470
+ └── app/ or pages/ # Routes` },
471
+ { domain: 'architecture', topic: 'nextjs', update_type: 'architecture', title: 'Next.js App Router Structure', content: `app/
472
+ ├── (marketing)/ # Marketing pages (landing, pricing)
473
+ │ ├── page.tsx
474
+ │ └── layout.tsx
475
+ ├── (auth)/ # Auth pages (login, register)
476
+ │ ├── login/
477
+ │ ├── register/
478
+ │ └── layout.tsx
479
+ ├── (dashboard)/ # Protected dashboard
480
+ │ ├── dashboard/
481
+ │ ├── settings/
482
+ │ └── layout.tsx # With auth check
483
+ ├── api/ # API routes
484
+ │ └── [...route]/
485
+ ├── globals.css
486
+ ├── layout.tsx # Root layout
487
+ └── not-found.tsx
488
+
489
+ Key Conventions:
490
+ (folder) = Route group (no URL impact)
491
+ [folder] = Dynamic route
492
+ @folder = Parallel route
493
+ loading.tsx = Suspense boundary
494
+ error.tsx = Error boundary
495
+ template.tsx = Re-render on nav` },
496
+ { domain: 'architecture', topic: 'api', update_type: 'architecture', title: 'REST API Design', content: `# Endpoints
497
+ GET /api/users # List (paginated)
498
+ POST /api/users # Create
499
+ GET /api/users/:id # Get one
500
+ PUT /api/users/:id # Replace
501
+ PATCH /api/users/:id # Partial update
502
+ DELETE /api/users/:id # Delete
503
+
504
+ # Query Parameters
505
+ ?page=1&limit=20 # Pagination
506
+ ?sort=-created_at # Sort (- = desc)
507
+ ?filter[status]=active # Filter
508
+ ?include=posts,comments # Relations
509
+ ?fields=id,name,email # Sparse fields
510
+
511
+ # Response Format
512
+ {
513
+ "data": [...],
514
+ "meta": {
515
+ "total": 100,
516
+ "page": 1,
517
+ "limit": 20,
518
+ "pages": 5
519
+ }
520
+ }
521
+
522
+ # Error Format
523
+ {
524
+ "error": {
525
+ "code": "VALIDATION_ERROR",
526
+ "message": "Invalid input",
527
+ "details": [...]
528
+ }
529
+ }` },
530
+ { domain: 'architecture', topic: 'monorepo', update_type: 'architecture', title: 'Monorepo Structure (Turborepo)', content: `monorepo/
531
+ ├── apps/
532
+ │ ├── web/ # Next.js frontend
533
+ │ ├── api/ # Backend service
534
+ │ ├── admin/ # Admin dashboard
535
+ │ └── docs/ # Documentation
536
+ ├── packages/
537
+ │ ├── ui/ # Shared UI components
538
+ │ ├── config/ # Shared configs (ESLint, TS)
539
+ │ ├── database/ # Prisma/Drizzle schema
540
+ │ └── utils/ # Shared utilities
541
+ ├── turbo.json # Turborepo config
542
+ ├── package.json # Root package.json
543
+ └── pnpm-workspace.yaml # Workspace config
544
+
545
+ Benefits:
546
+ - Shared code between apps
547
+ - Atomic changes across packages
548
+ - Consistent tooling
549
+ - Faster builds with caching` },
550
+ { domain: 'architecture', topic: 'clean', update_type: 'architecture', title: 'Clean Architecture Layers', content: `# Layer Structure
551
+
552
+ ## 1. Domain (innermost)
553
+ - Entities: Core business objects
554
+ - Value Objects: Immutable objects
555
+ - Domain Events: Business events
556
+ - No external dependencies
557
+
558
+ ## 2. Application
559
+ - Use Cases: Application-specific logic
560
+ - Interfaces: Ports for adapters
561
+ - DTOs: Data transfer objects
562
+ - Depends only on Domain
563
+
564
+ ## 3. Infrastructure (outermost)
565
+ - Repositories: Data access implementation
566
+ - External Services: APIs, email, etc.
567
+ - Framework Code: Express, Next.js
568
+ - Implements Application interfaces
569
+
570
+ ## 4. Presentation
571
+ - Controllers: HTTP handlers
572
+ - Views: UI components
573
+ - Presenters: Format data for views
574
+
575
+ # Dependency Rule
576
+ Dependencies point inward only.
577
+ Inner layers don't know about outer layers.` },
578
+ // ═══════════════════════════════════════════════════════════════
579
+ // ✅ CHECKLISTS
580
+ // ═══════════════════════════════════════════════════════════════
581
+ { domain: 'checklist', topic: 'launch', update_type: 'checklist', title: 'Production Launch Checklist', content: `## Performance
582
+ - [ ] Lighthouse score > 90
583
+ - [ ] Images optimized (WebP, lazy loading)
584
+ - [ ] Bundle size analyzed and optimized
585
+ - [ ] Core Web Vitals passing
586
+ - [ ] CDN configured
587
+
588
+ ## SEO
589
+ - [ ] Meta tags on all pages
590
+ - [ ] Open Graph tags for social
591
+ - [ ] Sitemap.xml generated
592
+ - [ ] robots.txt configured
593
+ - [ ] Canonical URLs set
594
+ - [ ] Schema.org markup
595
+
596
+ ## Security
597
+ - [ ] HTTPS enforced
598
+ - [ ] Security headers (CSP, HSTS)
599
+ - [ ] Rate limiting enabled
600
+ - [ ] Input validation everywhere
601
+ - [ ] SQL injection prevented
602
+ - [ ] XSS prevented
603
+
604
+ ## Monitoring
605
+ - [ ] Error tracking (Sentry)
606
+ - [ ] Analytics (Plausible/GA)
607
+ - [ ] Uptime monitoring
608
+ - [ ] Performance monitoring
609
+ - [ ] Log aggregation
610
+
611
+ ## Backups & Recovery
612
+ - [ ] Database backups automated
613
+ - [ ] Backup restore tested
614
+ - [ ] Disaster recovery plan
615
+
616
+ ## Legal
617
+ - [ ] Privacy Policy
618
+ - [ ] Terms of Service
619
+ - [ ] Cookie consent (GDPR)
620
+ - [ ] Accessibility statement` },
621
+ { domain: 'checklist', topic: 'security', update_type: 'checklist', title: 'Security Audit Checklist', content: `## Authentication
622
+ - [ ] Passwords hashed (bcrypt/argon2)
623
+ - [ ] MFA available
624
+ - [ ] Session timeout configured
625
+ - [ ] Account lockout after failed attempts
626
+ - [ ] Password strength requirements
627
+ - [ ] Secure password reset flow
628
+
629
+ ## Authorization
630
+ - [ ] Role-based access control
631
+ - [ ] Resource-level permissions
632
+ - [ ] JWT/session validation
633
+ - [ ] API key rotation
634
+
635
+ ## Data Protection
636
+ - [ ] Encryption at rest
637
+ - [ ] TLS 1.3 in transit
638
+ - [ ] PII handling compliant
639
+ - [ ] Data retention policy
640
+ - [ ] Audit logs enabled
641
+
642
+ ## Input/Output
643
+ - [ ] All input validated
644
+ - [ ] SQL injection prevented
645
+ - [ ] XSS prevented (output encoding)
646
+ - [ ] CSRF tokens implemented
647
+ - [ ] File upload restrictions
648
+
649
+ ## Infrastructure
650
+ - [ ] Secrets in env vars/vault
651
+ - [ ] Dependencies updated
652
+ - [ ] Vulnerability scanning (npm audit)
653
+ - [ ] Firewall configured
654
+ - [ ] DDoS protection` },
655
+ { domain: 'checklist', topic: 'a11y', update_type: 'checklist', title: 'Accessibility (WCAG 2.1)', content: `## Perceivable
656
+ - [ ] All images have alt text
657
+ - [ ] Videos have captions
658
+ - [ ] Audio has transcripts
659
+ - [ ] Color contrast ≥ 4.5:1 (AA)
660
+ - [ ] Text resizable to 200%
661
+ - [ ] Content reflows at 320px
662
+
663
+ ## Operable
664
+ - [ ] All functions keyboard accessible
665
+ - [ ] Focus indicators visible
666
+ - [ ] Skip to main content link
667
+ - [ ] Touch targets ≥ 44px
668
+ - [ ] No keyboard traps
669
+ - [ ] Page titles descriptive
670
+ - [ ] Focus order logical
671
+
672
+ ## Understandable
673
+ - [ ] Language attribute set
674
+ - [ ] Form labels associated
675
+ - [ ] Error messages descriptive
676
+ - [ ] Required fields indicated
677
+ - [ ] Consistent navigation
678
+
679
+ ## Robust
680
+ - [ ] Valid HTML
681
+ - [ ] ARIA used correctly
682
+ - [ ] Screen reader tested (NVDA/VoiceOver)
683
+ - [ ] Automated testing (axe)
684
+ - [ ] Manual testing completed` },
685
+ { domain: 'checklist', topic: 'code-review', update_type: 'checklist', title: 'Code Review Checklist', content: `## Functionality
686
+ - [ ] Code does what PR description says
687
+ - [ ] Edge cases handled
688
+ - [ ] Error handling appropriate
689
+ - [ ] No broken functionality elsewhere
690
+
691
+ ## Code Quality
692
+ - [ ] DRY - no duplication
693
+ - [ ] Single responsibility
694
+ - [ ] Meaningful names
695
+ - [ ] No magic numbers
696
+ - [ ] Comments explain "why", not "what"
697
+ - [ ] No console.log / debugger
698
+
699
+ ## TypeScript
700
+ - [ ] No any types
701
+ - [ ] Proper null/undefined handling
702
+ - [ ] Types exported for consumers
703
+ - [ ] Generics used appropriately
704
+
705
+ ## Testing
706
+ - [ ] Unit tests for new code
707
+ - [ ] Tests actually test behavior
708
+ - [ ] Edge cases tested
709
+ - [ ] No skipped tests
710
+
711
+ ## Security
712
+ - [ ] No secrets in code
713
+ - [ ] User input validated
714
+ - [ ] SQL injection prevented
715
+ - [ ] XSS prevented
716
+ - [ ] Auth checks present
717
+
718
+ ## Performance
719
+ - [ ] No N+1 queries
720
+ - [ ] Large lists paginated
721
+ - [ ] Expensive operations memoized
722
+ - [ ] Bundle impact considered` },
723
+ { domain: 'checklist', topic: 'pr', update_type: 'checklist', title: 'PR Submission Checklist', content: `## Before Opening PR
724
+ - [ ] Code compiles without errors
725
+ - [ ] All tests passing
726
+ - [ ] Linter passes
727
+ - [ ] Self-reviewed changes
728
+ - [ ] Removed debug code/console.logs
729
+ - [ ] Branch up to date with main
730
+
731
+ ## PR Description
732
+ - [ ] Clear title (type: description)
733
+ - [ ] Description explains WHAT changed
734
+ - [ ] Description explains WHY
735
+ - [ ] Screenshots/video for UI changes
736
+ - [ ] Breaking changes noted
737
+ - [ ] Migration steps if needed
738
+
739
+ ## Testing
740
+ - [ ] Tested locally
741
+ - [ ] Added/updated tests
742
+ - [ ] Tested edge cases
743
+ - [ ] Tested on mobile (if UI)
744
+
745
+ ## Documentation
746
+ - [ ] README updated if needed
747
+ - [ ] API docs updated if needed
748
+ - [ ] CHANGELOG updated
749
+ - [ ] Comments added for complex logic
750
+
751
+ ## Size
752
+ - [ ] PR is focused (one concern)
753
+ - [ ] < 400 lines (ideal)
754
+ - [ ] Large PRs split if possible` },
755
+ { domain: 'checklist', topic: 'api', update_type: 'checklist', title: 'API Endpoint Checklist', content: `## Design
756
+ - [ ] RESTful naming conventions
757
+ - [ ] Proper HTTP methods
758
+ - [ ] Consistent response format
759
+ - [ ] Pagination for lists
760
+ - [ ] Versioning strategy
761
+
762
+ ## Validation
763
+ - [ ] Request body validated
764
+ - [ ] Query params validated
765
+ - [ ] Path params validated
766
+ - [ ] File uploads restricted
767
+
768
+ ## Security
769
+ - [ ] Authentication required
770
+ - [ ] Authorization checked
771
+ - [ ] Rate limiting enabled
772
+ - [ ] Input sanitized
773
+ - [ ] Sensitive data filtered from logs
774
+
775
+ ## Error Handling
776
+ - [ ] Proper HTTP status codes
777
+ - [ ] Consistent error format
778
+ - [ ] No stack traces in production
779
+ - [ ] Errors logged server-side
780
+
781
+ ## Documentation
782
+ - [ ] OpenAPI/Swagger spec
783
+ - [ ] Request/response examples
784
+ - [ ] Error codes documented
785
+ - [ ] Rate limits documented
786
+
787
+ ## Testing
788
+ - [ ] Unit tests for logic
789
+ - [ ] Integration tests for API
790
+ - [ ] Load testing done
791
+ - [ ] Security testing done` },
792
+ // ═══════════════════════════════════════════════════════════════
793
+ // 🔧 CODE PATTERNS
794
+ // ═══════════════════════════════════════════════════════════════
795
+ { domain: 'patterns', topic: 'react', update_type: 'code_pattern', title: 'useAsync Hook', content: `import { useState, useCallback } from 'react';
796
+
797
+ interface AsyncState<T> {
798
+ data: T | null;
799
+ error: Error | null;
800
+ isLoading: boolean;
801
+ }
802
+
803
+ export function useAsync<T>() {
804
+ const [state, setState] = useState<AsyncState<T>>({
805
+ data: null,
806
+ error: null,
807
+ isLoading: false,
808
+ });
809
+
810
+ const execute = useCallback(async (promise: Promise<T>) => {
811
+ setState({ data: null, error: null, isLoading: true });
812
+ try {
813
+ const data = await promise;
814
+ setState({ data, error: null, isLoading: false });
815
+ return data;
816
+ } catch (error) {
817
+ setState({ data: null, error: error as Error, isLoading: false });
818
+ throw error;
819
+ }
820
+ }, []);
821
+
822
+ const reset = useCallback(() => {
823
+ setState({ data: null, error: null, isLoading: false });
824
+ }, []);
825
+
826
+ return { ...state, execute, reset };
827
+ }` },
828
+ { domain: 'patterns', topic: 'react', update_type: 'code_pattern', title: 'useDebounce Hook', content: `import { useState, useEffect } from 'react';
829
+
830
+ export function useDebounce<T>(value: T, delay: number): T {
831
+ const [debouncedValue, setDebouncedValue] = useState<T>(value);
832
+
833
+ useEffect(() => {
834
+ const timer = setTimeout(() => {
835
+ setDebouncedValue(value);
836
+ }, delay);
837
+
838
+ return () => {
839
+ clearTimeout(timer);
840
+ };
841
+ }, [value, delay]);
842
+
843
+ return debouncedValue;
844
+ }
845
+
846
+ // Usage
847
+ const [searchTerm, setSearchTerm] = useState('');
848
+ const debouncedSearch = useDebounce(searchTerm, 300);
849
+
850
+ useEffect(() => {
851
+ if (debouncedSearch) {
852
+ // Make API call
853
+ }
854
+ }, [debouncedSearch]);` },
855
+ { domain: 'patterns', topic: 'react', update_type: 'code_pattern', title: 'useLocalStorage Hook', content: `import { useState, useEffect } from 'react';
856
+
857
+ export function useLocalStorage<T>(
858
+ key: string,
859
+ initialValue: T
860
+ ): [T, (value: T | ((prev: T) => T)) => void] {
861
+ const [storedValue, setStoredValue] = useState<T>(() => {
862
+ if (typeof window === 'undefined') return initialValue;
863
+ try {
864
+ const item = window.localStorage.getItem(key);
865
+ return item ? JSON.parse(item) : initialValue;
866
+ } catch {
867
+ return initialValue;
868
+ }
869
+ });
870
+
871
+ const setValue = (value: T | ((prev: T) => T)) => {
872
+ try {
873
+ const valueToStore = value instanceof Function
874
+ ? value(storedValue)
875
+ : value;
876
+ setStoredValue(valueToStore);
877
+ if (typeof window !== 'undefined') {
878
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
879
+ }
880
+ } catch (error) {
881
+ console.error('useLocalStorage error:', error);
882
+ }
883
+ };
884
+
885
+ return [storedValue, setValue];
886
+ }` },
887
+ { domain: 'patterns', topic: 'typescript', update_type: 'code_pattern', title: 'Type-Safe Fetch', content: `type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
888
+
889
+ interface RequestConfig {
890
+ headers?: Record<string, string>;
891
+ params?: Record<string, string>;
892
+ }
893
+
894
+ async function request<T>(
895
+ method: HttpMethod,
896
+ url: string,
897
+ data?: unknown,
898
+ config?: RequestConfig
899
+ ): Promise<T> {
900
+ const headers: Record<string, string> = {
901
+ 'Content-Type': 'application/json',
902
+ ...config?.headers,
903
+ };
904
+
905
+ const queryString = config?.params
906
+ ? '?' + new URLSearchParams(config.params).toString()
907
+ : '';
908
+
909
+ const response = await fetch(url + queryString, {
910
+ method,
911
+ headers,
912
+ body: data ? JSON.stringify(data) : undefined,
913
+ });
914
+
915
+ if (!response.ok) {
916
+ const error = await response.json().catch(() => ({}));
917
+ throw new ApiError(response.status, error.message || response.statusText);
918
+ }
919
+
920
+ return response.json();
921
+ }
922
+
923
+ export const api = {
924
+ get: <T>(url: string, config?: RequestConfig) =>
925
+ request<T>('GET', url, undefined, config),
926
+ post: <T>(url: string, data: unknown, config?: RequestConfig) =>
927
+ request<T>('POST', url, data, config),
928
+ put: <T>(url: string, data: unknown, config?: RequestConfig) =>
929
+ request<T>('PUT', url, data, config),
930
+ delete: <T>(url: string, config?: RequestConfig) =>
931
+ request<T>('DELETE', url, undefined, config),
932
+ };` },
933
+ { domain: 'patterns', topic: 'typescript', update_type: 'code_pattern', title: 'Result Type (No Throws)', content: `type Result<T, E = Error> =
934
+ | { ok: true; value: T }
935
+ | { ok: false; error: E };
936
+
937
+ function Ok<T>(value: T): Result<T, never> {
938
+ return { ok: true, value };
939
+ }
940
+
941
+ function Err<E>(error: E): Result<never, E> {
942
+ return { ok: false, error };
943
+ }
944
+
945
+ // Usage
946
+ async function fetchUser(id: string): Promise<Result<User, string>> {
947
+ try {
948
+ const response = await fetch(\`/api/users/\${id}\`);
949
+ if (!response.ok) {
950
+ return Err('User not found');
951
+ }
952
+ const user = await response.json();
953
+ return Ok(user);
954
+ } catch {
955
+ return Err('Network error');
956
+ }
957
+ }
958
+
959
+ // Consuming
960
+ const result = await fetchUser('123');
961
+ if (result.ok) {
962
+ console.log(result.value); // User
963
+ } else {
964
+ console.error(result.error); // string
965
+ }` },
966
+ { domain: 'patterns', topic: 'react', update_type: 'code_pattern', title: 'Compound Component Pattern', content: `import { createContext, useContext, useState, ReactNode } from 'react';
967
+
968
+ // Context
969
+ interface TabsContextValue {
970
+ activeTab: string;
971
+ setActiveTab: (tab: string) => void;
972
+ }
973
+
974
+ const TabsContext = createContext<TabsContextValue | null>(null);
975
+
976
+ function useTabsContext() {
977
+ const context = useContext(TabsContext);
978
+ if (!context) throw new Error('Must be used within Tabs');
979
+ return context;
980
+ }
981
+
982
+ // Root
983
+ interface TabsProps {
984
+ defaultTab: string;
985
+ children: ReactNode;
986
+ }
987
+
988
+ function Tabs({ defaultTab, children }: TabsProps) {
989
+ const [activeTab, setActiveTab] = useState(defaultTab);
990
+ return (
991
+ <TabsContext.Provider value={{ activeTab, setActiveTab }}>
992
+ <div className="tabs">{children}</div>
993
+ </TabsContext.Provider>
994
+ );
995
+ }
996
+
997
+ // Tab Trigger
998
+ function TabTrigger({ value, children }: { value: string; children: ReactNode }) {
999
+ const { activeTab, setActiveTab } = useTabsContext();
1000
+ return (
1001
+ <button
1002
+ className={\`tab \${activeTab === value ? 'active' : ''}\`}
1003
+ onClick={() => setActiveTab(value)}
1004
+ >
1005
+ {children}
1006
+ </button>
1007
+ );
1008
+ }
1009
+
1010
+ // Tab Content
1011
+ function TabContent({ value, children }: { value: string; children: ReactNode }) {
1012
+ const { activeTab } = useTabsContext();
1013
+ if (activeTab !== value) return null;
1014
+ return <div className="tab-content">{children}</div>;
1015
+ }
1016
+
1017
+ // Attach components
1018
+ Tabs.Trigger = TabTrigger;
1019
+ Tabs.Content = TabContent;
1020
+
1021
+ export { Tabs };` },
1022
+ // ═══════════════════════════════════════════════════════════════
1023
+ // 🚀 BOILERPLATES
1024
+ // ═══════════════════════════════════════════════════════════════
1025
+ { domain: 'boilerplate', topic: 'react', update_type: 'boilerplate', title: 'React Component Template', content: `import { memo, forwardRef, ComponentPropsWithRef } from 'react';
1026
+ import styles from './ComponentName.module.css';
1027
+
1028
+ export interface ComponentNameProps extends ComponentPropsWithRef<'div'> {
1029
+ /** Description of the variant prop */
1030
+ variant?: 'default' | 'primary' | 'secondary';
1031
+ /** Whether the component is loading */
1032
+ isLoading?: boolean;
1033
+ }
1034
+
1035
+ /**
1036
+ * ComponentName - Brief description
1037
+ *
1038
+ * @example
1039
+ * <ComponentName variant="primary">Content</ComponentName>
1040
+ */
1041
+ export const ComponentName = memo(forwardRef<HTMLDivElement, ComponentNameProps>(
1042
+ function ComponentName(
1043
+ { variant = 'default', isLoading = false, className, children, ...props },
1044
+ ref
1045
+ ) {
1046
+ if (isLoading) {
1047
+ return <div className={styles.skeleton} />;
1048
+ }
1049
+
1050
+ return (
1051
+ <div
1052
+ ref={ref}
1053
+ className={\`\${styles.root} \${styles[variant]} \${className || ''}\`}
1054
+ {...props}
1055
+ >
1056
+ {children}
1057
+ </div>
1058
+ );
1059
+ }
1060
+ ));` },
1061
+ { domain: 'boilerplate', topic: 'nextjs', update_type: 'boilerplate', title: 'Next.js API Route Template', content: `import { NextRequest, NextResponse } from 'next/server';
1062
+ import { z } from 'zod';
1063
+ import { getServerSession } from 'next-auth';
1064
+ import { authOptions } from '@/lib/auth';
1065
+
1066
+ const RequestSchema = z.object({
1067
+ name: z.string().min(1).max(100),
1068
+ email: z.string().email(),
1069
+ });
1070
+
1071
+ export async function POST(request: NextRequest) {
1072
+ try {
1073
+ // Auth check
1074
+ const session = await getServerSession(authOptions);
1075
+ if (!session) {
1076
+ return NextResponse.json(
1077
+ { error: 'Unauthorized' },
1078
+ { status: 401 }
1079
+ );
1080
+ }
1081
+
1082
+ // Validate body
1083
+ const body = await request.json();
1084
+ const data = RequestSchema.parse(body);
1085
+
1086
+ // Business logic
1087
+ const result = await createSomething(data);
1088
+
1089
+ return NextResponse.json(result, { status: 201 });
1090
+ } catch (error) {
1091
+ if (error instanceof z.ZodError) {
1092
+ return NextResponse.json(
1093
+ { error: 'Validation error', details: error.errors },
1094
+ { status: 400 }
1095
+ );
1096
+ }
1097
+
1098
+ console.error('API Error:', error);
1099
+ return NextResponse.json(
1100
+ { error: 'Internal server error' },
1101
+ { status: 500 }
1102
+ );
1103
+ }
1104
+ }` },
1105
+ { domain: 'boilerplate', topic: 'nextjs', update_type: 'boilerplate', title: 'Next.js Server Action Template', content: `'use server';
1106
+
1107
+ import { z } from 'zod';
1108
+ import { revalidatePath } from 'next/cache';
1109
+ import { getServerSession } from 'next-auth';
1110
+ import { authOptions } from '@/lib/auth';
1111
+
1112
+ const FormSchema = z.object({
1113
+ title: z.string().min(1, 'Title is required').max(100),
1114
+ content: z.string().min(10, 'Content too short'),
1115
+ });
1116
+
1117
+ export type FormState = {
1118
+ errors?: {
1119
+ title?: string[];
1120
+ content?: string[];
1121
+ };
1122
+ message?: string;
1123
+ success?: boolean;
1124
+ };
1125
+
1126
+ export async function createPost(
1127
+ prevState: FormState,
1128
+ formData: FormData
1129
+ ): Promise<FormState> {
1130
+ // Auth
1131
+ const session = await getServerSession(authOptions);
1132
+ if (!session?.user?.id) {
1133
+ return { message: 'Unauthorized', success: false };
1134
+ }
1135
+
1136
+ // Validate
1137
+ const validatedFields = FormSchema.safeParse({
1138
+ title: formData.get('title'),
1139
+ content: formData.get('content'),
1140
+ });
1141
+
1142
+ if (!validatedFields.success) {
1143
+ return {
1144
+ errors: validatedFields.error.flatten().fieldErrors,
1145
+ message: 'Invalid fields',
1146
+ success: false,
1147
+ };
1148
+ }
1149
+
1150
+ try {
1151
+ // Create
1152
+ await db.post.create({
1153
+ data: {
1154
+ ...validatedFields.data,
1155
+ userId: session.user.id,
1156
+ },
1157
+ });
1158
+
1159
+ revalidatePath('/posts');
1160
+ return { message: 'Post created!', success: true };
1161
+ } catch {
1162
+ return { message: 'Database error', success: false };
1163
+ }
1164
+ }` },
1165
+ { domain: 'boilerplate', topic: 'testing', update_type: 'boilerplate', title: 'Jest Test Template', content: `import { render, screen, fireEvent, waitFor } from '@testing-library/react';
1166
+ import userEvent from '@testing-library/user-event';
1167
+ import { ComponentName } from './ComponentName';
1168
+
1169
+ describe('ComponentName', () => {
1170
+ const defaultProps = {
1171
+ onSubmit: jest.fn(),
1172
+ initialValue: 'test',
1173
+ };
1174
+
1175
+ beforeEach(() => {
1176
+ jest.clearAllMocks();
1177
+ });
1178
+
1179
+ it('renders correctly', () => {
1180
+ render(<ComponentName {...defaultProps} />);
1181
+ expect(screen.getByRole('button')).toBeInTheDocument();
1182
+ });
1183
+
1184
+ it('handles click events', async () => {
1185
+ const user = userEvent.setup();
1186
+ render(<ComponentName {...defaultProps} />);
1187
+
1188
+ await user.click(screen.getByRole('button'));
1189
+
1190
+ expect(defaultProps.onSubmit).toHaveBeenCalledTimes(1);
1191
+ });
1192
+
1193
+ it('shows error state', () => {
1194
+ render(<ComponentName {...defaultProps} error="Something went wrong" />);
1195
+ expect(screen.getByText(/something went wrong/i)).toBeInTheDocument();
1196
+ });
1197
+
1198
+ it('handles async operations', async () => {
1199
+ render(<ComponentName {...defaultProps} />);
1200
+
1201
+ fireEvent.click(screen.getByRole('button'));
1202
+
1203
+ await waitFor(() => {
1204
+ expect(screen.getByText(/success/i)).toBeInTheDocument();
1205
+ });
1206
+ });
1207
+ });` },
1208
+ // ═══════════════════════════════════════════════════════════════
1209
+ // 🔄 WORKFLOWS
1210
+ // ═══════════════════════════════════════════════════════════════
1211
+ { domain: 'workflow', topic: 'feature', update_type: 'workflow', title: 'Feature Development Flow', content: `1. PLAN
1212
+ - Write user story with acceptance criteria
1213
+ - Break into subtasks
1214
+ - Estimate complexity
1215
+ - Identify dependencies
1216
+
1217
+ 2. DESIGN
1218
+ - API contract (if backend)
1219
+ - Component hierarchy (if frontend)
1220
+ - Database changes (if needed)
1221
+ - Get design review
1222
+
1223
+ 3. IMPLEMENT
1224
+ - Create feature branch
1225
+ - Write tests first (TDD)
1226
+ - Implement in small commits
1227
+ - Keep PR focused
1228
+
1229
+ 4. TEST
1230
+ - Run unit tests
1231
+ - Run integration tests
1232
+ - Manual testing
1233
+ - Cross-browser testing (if UI)
1234
+
1235
+ 5. REVIEW
1236
+ - Self-review first
1237
+ - Open PR with description
1238
+ - Address feedback promptly
1239
+ - Get approval
1240
+
1241
+ 6. DEPLOY
1242
+ - Merge to main
1243
+ - Verify in staging
1244
+ - Deploy to production
1245
+ - Monitor for errors
1246
+
1247
+ 7. DOCUMENT
1248
+ - Update README if needed
1249
+ - Update API docs
1250
+ - Add to changelog` },
1251
+ { domain: 'workflow', topic: 'debugging', update_type: 'workflow', title: 'Systematic Debugging', content: `1. REPRODUCE
1252
+ - What are the exact steps?
1253
+ - What environment? (browser, OS, versions)
1254
+ - Is it consistent or intermittent?
1255
+ - Can you reproduce locally?
1256
+
1257
+ 2. ISOLATE
1258
+ - When did it start working/breaking?
1259
+ - Frontend or backend issue?
1260
+ - Which specific component/function?
1261
+ - Narrow down with binary search
1262
+
1263
+ 3. GATHER EVIDENCE
1264
+ - Console errors
1265
+ - Network requests/responses
1266
+ - Server logs
1267
+ - Error tracking (Sentry)
1268
+ - Database state
1269
+
1270
+ 4. HYPOTHESIZE
1271
+ - List top 3 likely causes
1272
+ - Rank by probability
1273
+ - Start with simplest explanation
1274
+
1275
+ 5. TEST HYPOTHESES
1276
+ - Add logging/breakpoints
1277
+ - Change ONE thing at a time
1278
+ - Verify assumptions
1279
+ - Don't skip steps
1280
+
1281
+ 6. FIX
1282
+ - Implement minimal fix
1283
+ - Verify fix works
1284
+ - Check for side effects
1285
+ - Add regression test
1286
+
1287
+ 7. PREVENT
1288
+ - Why wasn't this caught earlier?
1289
+ - Add monitoring/alerting?
1290
+ - Improve error handling?
1291
+ - Document for team` },
1292
+ { domain: 'workflow', topic: 'code-review', update_type: 'workflow', title: 'Effective Code Review', content: `## As Author
1293
+
1294
+ BEFORE SUBMITTING:
1295
+ 1. Self-review your changes first
1296
+ 2. Run all tests locally
1297
+ 3. Check linting passes
1298
+ 4. Write clear PR description
1299
+ 5. Add screenshots for UI changes
1300
+ 6. Keep PR < 400 lines if possible
1301
+
1302
+ DURING REVIEW:
1303
+ 1. Respond to all comments
1304
+ 2. Don't take feedback personally
1305
+ 3. Explain your reasoning
1306
+ 4. Make requested changes promptly
1307
+ 5. Re-request review when ready
1308
+
1309
+ ## As Reviewer
1310
+
1311
+ FIRST PASS (5 min):
1312
+ 1. Understand the goal from PR description
1313
+ 2. Check PR size is reasonable
1314
+ 3. Look at file structure changes
1315
+ 4. Identify areas of concern
1316
+
1317
+ DETAILED REVIEW:
1318
+ 1. Check logic and edge cases
1319
+ 2. Look for security issues
1320
+ 3. Check error handling
1321
+ 4. Verify tests cover changes
1322
+ 5. Check code style consistency
1323
+
1324
+ GIVING FEEDBACK:
1325
+ 1. Be specific, not vague
1326
+ 2. Explain the "why"
1327
+ 3. Suggest alternatives
1328
+ 4. Distinguish must-fix vs nice-to-have
1329
+ 5. Praise good patterns
1330
+ 6. Use conventional comments (nit:, blocking:)` },
1331
+ { domain: 'workflow', topic: 'incident', update_type: 'workflow', title: 'Incident Response', content: `1. DETECT
1332
+ - Monitoring alert
1333
+ - User report
1334
+ - Automated test failure
1335
+
1336
+ 2. TRIAGE (5 min)
1337
+ - Assess severity (P1-P4)
1338
+ - Estimate impact (users affected)
1339
+ - Assign incident commander
1340
+ - Start incident channel
1341
+
1342
+ 3. MITIGATE (ASAP)
1343
+ - Can we rollback?
1344
+ - Can we feature flag off?
1345
+ - Can we scale up?
1346
+ - Communicate status to stakeholders
1347
+
1348
+ 4. INVESTIGATE
1349
+ - Gather logs and metrics
1350
+ - Identify timeline of events
1351
+ - Find root cause
1352
+ - Document findings
1353
+
1354
+ 5. FIX
1355
+ - Implement permanent fix
1356
+ - Test thoroughly
1357
+ - Deploy with monitoring
1358
+ - Verify resolution
1359
+
1360
+ 6. COMMUNICATE
1361
+ - Update status page
1362
+ - Notify affected users
1363
+ - Internal update
1364
+
1365
+ 7. POST-MORTEM
1366
+ - Blameless analysis
1367
+ - Document timeline
1368
+ - Identify improvements
1369
+ - Create action items
1370
+ - Share learnings` },
1371
+ // ═══════════════════════════════════════════════════════════════
1372
+ // 💡 BEST PRACTICES
1373
+ // ═══════════════════════════════════════════════════════════════
1374
+ // React
1375
+ { domain: 'react', topic: 'performance', update_type: 'best_practice', title: 'Use React.memo() wisely', content: 'Wrap components with stable props but expensive render logic. Avoid for components with frequently changing props as the comparison overhead isn\'t worth it.', package_name: 'react', min_version: '16.6.0' },
1376
+ { domain: 'react', topic: 'hooks', update_type: 'best_practice', title: 'useCallback for handlers', content: 'Wrap callbacks passed to memoized child components with useCallback. Without it, a new function reference is created each render, breaking memo.', package_name: 'react', min_version: '16.8.0' },
1377
+ { domain: 'react', topic: 'lists', update_type: 'best_practice', title: 'Stable keys, never indices', content: 'Keys should be unique IDs from your data, not array indices. Index keys cause bugs with reordering and state preservation.', package_name: 'react', min_version: '16.0.0' },
1378
+ { domain: 'react', topic: 'state', update_type: 'best_practice', title: 'Colocate state', content: 'Keep state as close to where it\'s used as possible. Only lift state when truly needed. Avoid premature global state.', package_name: 'react', min_version: '16.0.0' },
1379
+ { domain: 'react', topic: 'effects', update_type: 'best_practice', title: 'Always cleanup useEffect', content: 'Return a cleanup function from useEffect for subscriptions, timers, and event listeners. Prevents memory leaks and stale closures.', package_name: 'react', min_version: '16.8.0' },
1380
+ { domain: 'react', topic: 'state', update_type: 'best_practice', title: 'Avoid derived state', content: 'Don\'t useState for values derivable from props or other state. Use useMemo or calculate during render instead.', package_name: 'react', min_version: '16.8.0' },
1381
+ { domain: 'react', topic: 'errors', update_type: 'best_practice', title: 'Use Error Boundaries', content: 'Wrap route-level and critical components in error boundaries. Prevents the entire app from crashing on render errors.', package_name: 'react', min_version: '16.0.0' },
1382
+ { domain: 'react', topic: 'refs', update_type: 'best_practice', title: 'useRef for non-render values', content: 'Use useRef for values that don\'t need re-render (timers, previous values, DOM refs). Unlike state, changing ref.current won\'t trigger render.', package_name: 'react', min_version: '16.8.0' },
1383
+ // TypeScript
1384
+ { domain: 'typescript', topic: 'types', update_type: 'best_practice', title: 'type vs interface', content: 'Use type for unions, intersections, and primitives. Use interface for object shapes that might be extended or implemented.', package_name: 'typescript', min_version: '4.0.0' },
1385
+ { domain: 'typescript', topic: 'safety', update_type: 'best_practice', title: 'unknown over any', content: 'Use unknown instead of any when type is truly unknown. unknown is type-safe - you must narrow it before use.', package_name: 'typescript', min_version: '3.0.0' },
1386
+ { domain: 'typescript', topic: 'config', update_type: 'best_practice', title: 'Enable strict mode', content: 'Set strict: true in tsconfig.json. This enables strictNullChecks, noImplicitAny, and other safety checks.', package_name: 'typescript', min_version: '2.3.0' },
1387
+ { domain: 'typescript', topic: 'types', update_type: 'best_practice', title: 'Prefer const assertions', content: 'Use as const for literal types: const routes = { home: "/home" } as const. Prevents widening to string.', package_name: 'typescript', min_version: '3.4.0' },
1388
+ { domain: 'typescript', topic: 'types', update_type: 'best_practice', title: 'Use satisfies keyword', content: 'satisfies validates type without widening: const config = { a: 1 } satisfies Config keeps literal types while ensuring shape.', package_name: 'typescript', min_version: '4.9.0' },
1389
+ { domain: 'typescript', topic: 'enums', update_type: 'best_practice', title: 'Avoid enums, use const objects', content: 'const STATUS = { IDLE: "idle" } as const is more predictable than enum at runtime and doesn\'t generate extra code.', package_name: 'typescript', min_version: '3.4.0' },
1390
+ // Next.js
1391
+ { domain: 'nextjs', topic: 'components', update_type: 'best_practice', title: 'Server Components by default', content: 'In App Router, components are Server Components by default. Only add "use client" when you need hooks, browser APIs, or event handlers.', package_name: 'next', min_version: '13.0.0' },
1392
+ { domain: 'nextjs', topic: 'data', update_type: 'best_practice', title: 'Fetch in Server Components', content: 'Do data fetching in Server Components, not useEffect. Use async components and fetch() with automatic deduplication.', package_name: 'next', min_version: '13.0.0' },
1393
+ { domain: 'nextjs', topic: 'data', update_type: 'best_practice', title: 'Parallel data fetching', content: 'Use Promise.all() for independent fetches. Avoid sequential awaits that create waterfalls.', package_name: 'next', min_version: '13.0.0' },
1394
+ { domain: 'nextjs', topic: 'images', update_type: 'best_practice', title: 'Always use next/image', content: 'Image component provides automatic optimization, lazy loading, responsive sizes, and WebP conversion.', package_name: 'next', min_version: '10.0.0' },
1395
+ { domain: 'nextjs', topic: 'routing', update_type: 'best_practice', title: 'Use route groups', content: 'Use (folder) syntax for route groups. Organize routes without affecting URL structure.', package_name: 'next', min_version: '13.0.0' },
1396
+ { domain: 'nextjs', topic: 'caching', update_type: 'best_practice', title: 'Understand caching', content: 'Next.js caches aggressively. Use revalidatePath/revalidateTag for on-demand revalidation. Set { cache: "no-store" } for dynamic data.', package_name: 'next', min_version: '13.0.0' },
1397
+ // Node.js
1398
+ { domain: 'nodejs', topic: 'async', update_type: 'best_practice', title: 'async/await over callbacks', content: 'Use async/await for cleaner code and better error handling with try/catch. Avoid callback hell.', package_name: 'node', min_version: '8.0.0' },
1399
+ { domain: 'nodejs', topic: 'config', update_type: 'best_practice', title: 'Validate env vars at startup', content: 'Use zod or joi to validate environment variables when the app starts. Fail fast if required vars are missing.', package_name: 'node', min_version: '12.0.0' },
1400
+ { domain: 'nodejs', topic: 'errors', update_type: 'best_practice', title: 'Handle uncaught exceptions', content: 'process.on("uncaughtException") should log the error and exit gracefully. Never swallow errors silently.', package_name: 'node', min_version: '1.0.0' },
1401
+ { domain: 'nodejs', topic: 'production', update_type: 'best_practice', title: 'Graceful shutdown', content: 'Handle SIGTERM/SIGINT to close database connections and finish in-flight requests before exiting.', package_name: 'node', min_version: '1.0.0' },
1402
+ { domain: 'nodejs', topic: 'streams', update_type: 'best_practice', title: 'Stream large data', content: 'Use streams for large files instead of reading entire files into memory. Prevents memory exhaustion.', package_name: 'node', min_version: '1.0.0' },
1403
+ // CSS
1404
+ { domain: 'css', topic: 'variables', update_type: 'best_practice', title: 'Use CSS custom properties', content: 'CSS variables (--color-primary) enable theming, reduce repetition, and can be changed at runtime via JavaScript.', package_name: null, min_version: null },
1405
+ { domain: 'css', topic: 'units', update_type: 'best_practice', title: 'rem for font sizes, px for borders', content: 'rem scales with user preferences for accessibility. px is fine for borders and small fixed elements.', package_name: null, min_version: null },
1406
+ { domain: 'css', topic: 'layout', update_type: 'best_practice', title: 'Mobile-first media queries', content: 'Write base styles for mobile, use min-width queries to enhance for larger screens. Better performance and simpler code.', package_name: null, min_version: null },
1407
+ { domain: 'css', topic: 'specificity', update_type: 'best_practice', title: 'Avoid !important', content: '!important breaks the cascade. Fix specificity issues with better selectors or CSS layers instead.', package_name: null, min_version: null },
1408
+ { domain: 'css', topic: 'performance', update_type: 'best_practice', title: 'Use contain property', content: 'contain: content isolates layout/paint. Great for cards, modals, and independently updating components.', package_name: null, min_version: null },
1409
+ // Git
1410
+ { domain: 'git', topic: 'commits', update_type: 'best_practice', title: 'Atomic commits', content: 'Each commit should be one logical change. Makes reviews, reverts, and bisecting much easier.', package_name: null, min_version: null },
1411
+ { domain: 'git', topic: 'commits', update_type: 'best_practice', title: 'Conventional commits', content: 'Use feat:, fix:, docs:, chore:, refactor: prefixes. Enables automatic changelog generation and semantic versioning.', package_name: null, min_version: null },
1412
+ { domain: 'git', topic: 'branches', update_type: 'best_practice', title: 'Short-lived feature branches', content: 'Feature branches should live hours or days, not weeks. Long-lived branches lead to merge hell.', package_name: null, min_version: null },
1413
+ { domain: 'git', topic: 'workflow', update_type: 'best_practice', title: 'Rebase feature branches', content: 'Rebase onto main before merging for linear history. Squash WIP commits to keep history clean.', package_name: null, min_version: null },
1414
+ { domain: 'git', topic: 'safety', update_type: 'best_practice', title: 'Never force push shared branches', content: 'Force pushing rewrites history and breaks collaborators. Only force push personal feature branches.', package_name: null, min_version: null },
1415
+ // Supabase
1416
+ { domain: 'supabase', topic: 'security', update_type: 'best_practice', title: 'Always enable RLS', content: 'Row Level Security is disabled by default. Enable it on ALL tables. Without RLS, your data is publicly accessible.', package_name: '@supabase/supabase-js', min_version: '2.0.0' },
1417
+ { domain: 'supabase', topic: 'queries', update_type: 'best_practice', title: 'Select specific columns', content: 'Use .select("id, name") instead of .select("*"). Reduces payload size and improves security.', package_name: '@supabase/supabase-js', min_version: '2.0.0' },
1418
+ { domain: 'supabase', topic: 'auth', update_type: 'best_practice', title: 'Use auth.uid() in RLS', content: 'Reference auth.uid() in RLS policies to scope data to the current user. Never trust client-side user IDs.', package_name: '@supabase/supabase-js', min_version: '2.0.0' },
1419
+ // Testing
1420
+ { domain: 'testing', topic: 'unit', update_type: 'best_practice', title: 'Test behavior, not implementation', content: 'Test what the code does, not how it does it. Tests should survive refactoring if behavior stays the same.', package_name: null, min_version: null },
1421
+ { domain: 'testing', topic: 'mocking', update_type: 'best_practice', title: 'Mock at boundaries', content: 'Mock external services (APIs, databases) not internal modules. Mocking internals makes tests brittle.', package_name: null, min_version: null },
1422
+ { domain: 'testing', topic: 'naming', update_type: 'best_practice', title: 'Descriptive test names', content: 'Test names should describe expected behavior: "should show error when email is invalid" not "test email"', package_name: null, min_version: null },
1423
+ { domain: 'testing', topic: 'isolation', update_type: 'best_practice', title: 'Tests should be independent', content: 'Each test should set up its own state and clean up after. Tests should pass in any order.', package_name: null, min_version: null },
1424
+ // Security
1425
+ { domain: 'security', topic: 'auth', update_type: 'best_practice', title: 'Use established auth libraries', content: 'Don\'t roll your own auth. Use NextAuth.js, Clerk, or Supabase Auth. Auth is hard to get right.', package_name: null, min_version: null },
1426
+ { domain: 'security', topic: 'secrets', update_type: 'best_practice', title: 'Never commit secrets', content: 'API keys, passwords, and tokens go in .env files (gitignored). Use secret managers in production.', package_name: null, min_version: null },
1427
+ { domain: 'security', topic: 'input', update_type: 'best_practice', title: 'Validate all input', content: 'Validate on server-side even if validated client-side. Client validation is for UX, server validation is for security.', package_name: null, min_version: null },
1428
+ { domain: 'security', topic: 'dependencies', update_type: 'best_practice', title: 'Keep dependencies updated', content: 'Run npm audit regularly. Use Dependabot or Renovate for automated updates. Review breaking changes.', package_name: null, min_version: null },
1429
+ ];
1430
+ //# sourceMappingURL=knowledge-base.js.map