@su-record/vibe 2.4.72 → 2.4.76

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.
Files changed (164) hide show
  1. package/CLAUDE.md +216 -215
  2. package/README.md +4 -4
  3. package/agents/research/best-practices-agent.md +13 -13
  4. package/agents/research/codebase-patterns-agent.md +33 -33
  5. package/agents/research/framework-docs-agent.md +23 -23
  6. package/agents/research/security-advisory-agent.md +29 -29
  7. package/agents/review/architecture-reviewer.md +31 -31
  8. package/agents/review/complexity-reviewer.md +21 -21
  9. package/agents/review/data-integrity-reviewer.md +29 -29
  10. package/agents/review/git-history-reviewer.md +24 -24
  11. package/agents/review/performance-reviewer.md +29 -29
  12. package/agents/review/python-reviewer.md +53 -53
  13. package/agents/review/rails-reviewer.md +40 -40
  14. package/agents/review/react-reviewer.md +40 -40
  15. package/agents/review/security-reviewer.md +29 -29
  16. package/agents/review/simplicity-reviewer.md +24 -24
  17. package/agents/review/test-coverage-reviewer.md +31 -31
  18. package/agents/review/typescript-reviewer.md +41 -41
  19. package/commands/vibe.analyze.md +103 -7
  20. package/commands/vibe.reason.md +106 -0
  21. package/commands/vibe.review.md +123 -38
  22. package/commands/vibe.run.md +286 -223
  23. package/commands/vibe.spec.md +425 -186
  24. package/commands/vibe.utils.md +104 -3
  25. package/commands/vibe.verify.md +179 -86
  26. package/dist/cli/detect.js +40 -40
  27. package/dist/cli/detect.js.map +1 -1
  28. package/dist/cli/index.d.ts +1 -1
  29. package/dist/cli/index.js +1 -1
  30. package/dist/cli/llm.js +5 -5
  31. package/dist/cli/llm.js.map +1 -1
  32. package/dist/cli/setup.js +3 -3
  33. package/dist/cli/setup.js.map +1 -1
  34. package/dist/lib/ContextCompressor.js +1 -1
  35. package/dist/lib/ContextCompressor.js.map +1 -1
  36. package/dist/lib/MemoryManager.d.ts +13 -155
  37. package/dist/lib/MemoryManager.d.ts.map +1 -1
  38. package/dist/lib/MemoryManager.js +52 -617
  39. package/dist/lib/MemoryManager.js.map +1 -1
  40. package/dist/lib/gemini-api.js +12 -12
  41. package/dist/lib/gemini-api.js.map +1 -1
  42. package/dist/lib/gemini-oauth.js +22 -22
  43. package/dist/lib/gemini-oauth.js.map +1 -1
  44. package/dist/lib/gemini-storage.js +3 -3
  45. package/dist/lib/gemini-storage.js.map +1 -1
  46. package/dist/lib/gpt-api.js +11 -11
  47. package/dist/lib/gpt-api.js.map +1 -1
  48. package/dist/lib/gpt-oauth.js +28 -28
  49. package/dist/lib/gpt-oauth.js.map +1 -1
  50. package/dist/lib/gpt-storage.js +3 -3
  51. package/dist/lib/gpt-storage.js.map +1 -1
  52. package/dist/lib/memory/KnowledgeGraph.d.ts +34 -0
  53. package/dist/lib/memory/KnowledgeGraph.d.ts.map +1 -0
  54. package/dist/lib/memory/KnowledgeGraph.js +216 -0
  55. package/dist/lib/memory/KnowledgeGraph.js.map +1 -0
  56. package/dist/lib/memory/KnowledgeGraph.test.d.ts +2 -0
  57. package/dist/lib/memory/KnowledgeGraph.test.d.ts.map +1 -0
  58. package/dist/lib/memory/KnowledgeGraph.test.js +189 -0
  59. package/dist/lib/memory/KnowledgeGraph.test.js.map +1 -0
  60. package/dist/lib/memory/MemorySearch.d.ts +25 -0
  61. package/dist/lib/memory/MemorySearch.d.ts.map +1 -0
  62. package/dist/lib/memory/MemorySearch.js +85 -0
  63. package/dist/lib/memory/MemorySearch.js.map +1 -0
  64. package/dist/lib/memory/MemorySearch.test.d.ts +2 -0
  65. package/dist/lib/memory/MemorySearch.test.d.ts.map +1 -0
  66. package/dist/lib/memory/MemorySearch.test.js +149 -0
  67. package/dist/lib/memory/MemorySearch.test.js.map +1 -0
  68. package/dist/lib/memory/MemoryStorage.d.ts +77 -0
  69. package/dist/lib/memory/MemoryStorage.d.ts.map +1 -0
  70. package/dist/lib/memory/MemoryStorage.js +278 -0
  71. package/dist/lib/memory/MemoryStorage.js.map +1 -0
  72. package/dist/lib/memory/MemoryStorage.test.d.ts +2 -0
  73. package/dist/lib/memory/MemoryStorage.test.d.ts.map +1 -0
  74. package/dist/lib/memory/MemoryStorage.test.js +198 -0
  75. package/dist/lib/memory/MemoryStorage.test.js.map +1 -0
  76. package/dist/lib/memory/index.d.ts +4 -0
  77. package/dist/lib/memory/index.d.ts.map +1 -0
  78. package/dist/lib/memory/index.js +8 -0
  79. package/dist/lib/memory/index.js.map +1 -0
  80. package/dist/orchestrator/orchestrator.d.ts.map +1 -1
  81. package/dist/orchestrator/orchestrator.js +4 -6
  82. package/dist/orchestrator/orchestrator.js.map +1 -1
  83. package/dist/tools/convention/analyzeComplexity.d.ts +3 -1
  84. package/dist/tools/convention/analyzeComplexity.d.ts.map +1 -1
  85. package/dist/tools/convention/analyzeComplexity.js +102 -4
  86. package/dist/tools/convention/analyzeComplexity.js.map +1 -1
  87. package/dist/tools/convention/analyzeComplexity.test.d.ts +2 -0
  88. package/dist/tools/convention/analyzeComplexity.test.d.ts.map +1 -0
  89. package/dist/tools/convention/analyzeComplexity.test.js +207 -0
  90. package/dist/tools/convention/analyzeComplexity.test.js.map +1 -0
  91. package/dist/tools/convention/applyQualityRules.js +1 -1
  92. package/dist/tools/convention/applyQualityRules.js.map +1 -1
  93. package/dist/tools/convention/checkCouplingCohesion.js +2 -2
  94. package/dist/tools/convention/checkCouplingCohesion.js.map +1 -1
  95. package/dist/tools/convention/suggestImprovements.js +1 -1
  96. package/dist/tools/convention/suggestImprovements.js.map +1 -1
  97. package/dist/tools/convention/validateCodeQuality.d.ts +3 -1
  98. package/dist/tools/convention/validateCodeQuality.d.ts.map +1 -1
  99. package/dist/tools/convention/validateCodeQuality.js +145 -2
  100. package/dist/tools/convention/validateCodeQuality.js.map +1 -1
  101. package/dist/tools/convention/validateCodeQuality.test.d.ts +2 -0
  102. package/dist/tools/convention/validateCodeQuality.test.d.ts.map +1 -0
  103. package/dist/tools/convention/validateCodeQuality.test.js +230 -0
  104. package/dist/tools/convention/validateCodeQuality.test.js.map +1 -0
  105. package/dist/tools/memory/autoSaveContext.js +1 -1
  106. package/dist/tools/memory/autoSaveContext.js.map +1 -1
  107. package/dist/tools/memory/createMemoryTimeline.js +27 -27
  108. package/dist/tools/memory/createMemoryTimeline.js.map +1 -1
  109. package/dist/tools/memory/deleteMemory.js +1 -1
  110. package/dist/tools/memory/deleteMemory.js.map +1 -1
  111. package/dist/tools/memory/getMemoryGraph.js +24 -24
  112. package/dist/tools/memory/getMemoryGraph.js.map +1 -1
  113. package/dist/tools/memory/getSessionContext.js +36 -36
  114. package/dist/tools/memory/getSessionContext.js.map +1 -1
  115. package/dist/tools/memory/linkMemories.js +21 -21
  116. package/dist/tools/memory/linkMemories.js.map +1 -1
  117. package/dist/tools/memory/prioritizeMemory.js +1 -1
  118. package/dist/tools/memory/prioritizeMemory.js.map +1 -1
  119. package/dist/tools/memory/restoreSessionContext.js +1 -1
  120. package/dist/tools/memory/restoreSessionContext.js.map +1 -1
  121. package/dist/tools/memory/searchMemories.js +1 -1
  122. package/dist/tools/memory/searchMemories.js.map +1 -1
  123. package/dist/tools/memory/searchMemoriesAdvanced.js +42 -42
  124. package/dist/tools/memory/searchMemoriesAdvanced.js.map +1 -1
  125. package/dist/tools/memory/startSession.js +2 -2
  126. package/dist/tools/memory/startSession.js.map +1 -1
  127. package/dist/tools/memory/updateMemory.js +1 -1
  128. package/dist/tools/memory/updateMemory.js.map +1 -1
  129. package/dist/tools/semantic/analyzeDependencyGraph.js +38 -38
  130. package/dist/tools/semantic/analyzeDependencyGraph.js.map +1 -1
  131. package/dist/tools/semantic/findReferences.js +1 -1
  132. package/dist/tools/semantic/findReferences.js.map +1 -1
  133. package/dist/tools/semantic/findSymbol.js +1 -1
  134. package/dist/tools/semantic/findSymbol.js.map +1 -1
  135. package/dist/tools/time/getCurrentTime.js +1 -1
  136. package/dist/tools/time/getCurrentTime.js.map +1 -1
  137. package/dist/tools/ui/previewUiAscii.js +2 -2
  138. package/dist/tools/ui/previewUiAscii.js.map +1 -1
  139. package/hooks/hooks.json +11 -2
  140. package/hooks/scripts/llm-orchestrate.js +1 -1
  141. package/hooks/scripts/utils.js +31 -6
  142. package/languages/csharp-unity.md +82 -83
  143. package/languages/dart-flutter.md +89 -88
  144. package/languages/go.md +76 -75
  145. package/languages/java-spring.md +85 -84
  146. package/languages/kotlin-android.md +64 -63
  147. package/languages/python-django.md +83 -82
  148. package/languages/python-fastapi.md +82 -81
  149. package/languages/rust.md +75 -74
  150. package/languages/swift-ios.md +73 -72
  151. package/languages/typescript-electron.md +70 -71
  152. package/languages/typescript-nextjs.md +93 -92
  153. package/languages/typescript-node.md +64 -63
  154. package/languages/typescript-nuxt.md +113 -112
  155. package/languages/typescript-react-native.md +82 -81
  156. package/languages/typescript-react.md +76 -75
  157. package/languages/typescript-tauri.md +74 -75
  158. package/languages/typescript-vue.md +73 -72
  159. package/package.json +1 -1
  160. package/skills/git-worktree.md +25 -25
  161. package/skills/multi-llm-orchestration.md +4 -6
  162. package/skills/priority-todos.md +39 -39
  163. package/skills/vibe-capabilities.md +2 -2
  164. package/vibe/config.json +2 -2
@@ -1,40 +1,41 @@
1
- # TypeScript + Next.js 품질 규칙
1
+ # TypeScript + Next.js Quality Rules
2
2
 
3
- ## 핵심 원칙 (core + React에서 상속)
3
+ ## Core Principles (inherited from core + React)
4
4
 
5
5
  ```markdown
6
- 단일 책임 (SRP)
7
- 중복 제거 (DRY)
8
- 재사용성
9
- ✅ 낮은 복잡도
10
- 함수 ≤ 30줄, JSX ≤ 50줄
11
- React 규칙 모두 적용
6
+ # Core Principles (inherited from core + React)
7
+ Single Responsibility (SRP)
8
+ No Duplication (DRY)
9
+ Reusability
10
+ Low Complexity
11
+ Function <= 30 lines, JSX <= 50 lines
12
+ All React rules apply
12
13
  ```
13
14
 
14
- ## Next.js 특화 규칙
15
+ ## Next.js Specific Rules
15
16
 
16
- ### 1. App Router (Next.js 13+) 우선
17
+ ### 1. App Router (Next.js 13+) First
17
18
 
18
19
  ```typescript
19
- // App Router 구조
20
+ // Good: App Router structure
20
21
  app/
21
- ├── layout.tsx # 루트 레이아웃
22
- ├── page.tsx # 페이지
23
- ├── loading.tsx # 로딩 UI
24
- ├── error.tsx # 에러 UI
25
- ├── not-found.tsx # 404 페이지
22
+ ├── layout.tsx # Root layout
23
+ ├── page.tsx # Home page
24
+ ├── loading.tsx # Loading UI
25
+ ├── error.tsx # Error UI
26
+ ├── not-found.tsx # 404 page
26
27
  ├── users/
27
28
  │ ├── page.tsx # /users
28
29
  │ ├── [id]/
29
30
  │ │ └── page.tsx # /users/:id
30
- │ └── loading.tsx # /users 로딩
31
+ │ └── loading.tsx # /users loading
31
32
  └── api/
32
33
  └── users/
33
34
  └── route.ts # API Route
34
35
 
35
- // 서버 컴포넌트 (기본)
36
+ // Good: Server Component (default)
36
37
  export default async function UsersPage() {
37
- // 서버에서 데이터 페칭
38
+ // Fetch data on server
38
39
  const users = await getUsers();
39
40
 
40
41
  return (
@@ -45,7 +46,7 @@ export default async function UsersPage() {
45
46
  );
46
47
  }
47
48
 
48
- // 클라이언트 컴포넌트 (필요 시에만)
49
+ // Good: Client Component (only when needed)
49
50
  'use client';
50
51
 
51
52
  import { useState } from 'react';
@@ -57,17 +58,17 @@ export function InteractiveButton() {
57
58
  }
58
59
  ```
59
60
 
60
- ### 2. 서버 컴포넌트 vs 클라이언트 컴포넌트
61
+ ### 2. Server Components vs Client Components
61
62
 
62
63
  ```typescript
63
- // 서버 컴포넌트 (권장)
64
- // - 데이터 페칭
65
- // - 환경 변수 접근
66
- // - DB 직접 접근
67
- // - 민감한 정보 처리
64
+ // Good: Server Component (recommended)
65
+ // - Data fetching
66
+ // - Environment variable access
67
+ // - Direct DB access
68
+ // - Sensitive information handling
68
69
 
69
70
  async function UserProfile({ userId }: { userId: string }) {
70
- // 서버에서만 실행 (API 노출 안 됨)
71
+ // Runs only on server (API key not exposed)
71
72
  const user = await db.user.findUnique({
72
73
  where: { id: userId },
73
74
  });
@@ -75,11 +76,11 @@ async function UserProfile({ userId }: { userId: string }) {
75
76
  return <div>{user.name}</div>;
76
77
  }
77
78
 
78
- // 클라이언트 컴포넌트 (필요 시만)
79
- // - useState, useEffect 사용
80
- // - 이벤트 핸들러
81
- // - 브라우저 API
82
- // - 서드파티 라이브러리 (대부분)
79
+ // Good: Client Component (only when needed)
80
+ // - useState, useEffect usage
81
+ // - Event handlers
82
+ // - Browser APIs
83
+ // - Third-party libraries (mostly)
83
84
 
84
85
  'use client';
85
86
 
@@ -90,20 +91,20 @@ function SearchBar() {
90
91
  }
91
92
  ```
92
93
 
93
- ### 3. Data Fetching 패턴
94
+ ### 3. Data Fetching Patterns
94
95
 
95
96
  ```typescript
96
- // 서버 컴포넌트에서 직접 fetch
97
+ // Good: Direct fetch in Server Component
97
98
  async function PostsPage() {
98
- // 자동 캐싱, 재검증
99
+ // Auto caching, revalidation
99
100
  const posts = await fetch('https://api.example.com/posts', {
100
- next: { revalidate: 60 }, // 60 캐싱
101
+ next: { revalidate: 60 }, // 60 second cache
101
102
  }).then(res => res.json());
102
103
 
103
104
  return <PostList posts={posts} />;
104
105
  }
105
106
 
106
- // 병렬 데이터 페칭
107
+ // Good: Parallel data fetching
107
108
  async function UserDashboard({ userId }: { userId: string }) {
108
109
  const [user, posts, comments] = await Promise.all([
109
110
  getUser(userId),
@@ -120,12 +121,12 @@ async function UserDashboard({ userId }: { userId: string }) {
120
121
  );
121
122
  }
122
123
 
123
- // 순차적 데이터 페칭 (의존 관계)
124
+ // Good: Sequential data fetching (dependencies)
124
125
  async function UserWithPosts({ username }: { username: string }) {
125
- // 1. 사용자 조회
126
+ // 1. Get user
126
127
  const user = await getUserByUsername(username);
127
128
 
128
- // 2. 사용자 ID로 게시물 조회
129
+ // 2. Get posts by user ID
129
130
  const posts = await getUserPosts(user.id);
130
131
 
131
132
  return (
@@ -149,7 +150,7 @@ const createUserSchema = z.object({
149
150
  name: z.string().min(1),
150
151
  });
151
152
 
152
- // GET /api/users
153
+ // Good: GET /api/users
153
154
  export async function GET(request: NextRequest) {
154
155
  try {
155
156
  const users = await db.user.findMany();
@@ -162,7 +163,7 @@ export async function GET(request: NextRequest) {
162
163
  }
163
164
  }
164
165
 
165
- // POST /api/users
166
+ // Good: POST /api/users
166
167
  export async function POST(request: NextRequest) {
167
168
  try {
168
169
  const body = await request.json();
@@ -183,7 +184,7 @@ export async function POST(request: NextRequest) {
183
184
  }
184
185
 
185
186
  // app/api/users/[id]/route.ts
186
- // GET /api/users/:id
187
+ // Good: GET /api/users/:id
187
188
  export async function GET(
188
189
  request: NextRequest,
189
190
  { params }: { params: { id: string } }
@@ -203,7 +204,7 @@ export async function GET(
203
204
  ### 5. Metadata & SEO
204
205
 
205
206
  ```typescript
206
- // 정적 메타데이터
207
+ // Good: Static metadata
207
208
  import { Metadata } from 'next';
208
209
 
209
210
  export const metadata: Metadata = {
@@ -216,7 +217,7 @@ export const metadata: Metadata = {
216
217
  },
217
218
  };
218
219
 
219
- // 동적 메타데이터
220
+ // Good: Dynamic metadata
220
221
  export async function generateMetadata({
221
222
  params,
222
223
  }: {
@@ -238,7 +239,7 @@ export async function generateMetadata({
238
239
  ### 6. Streaming & Suspense
239
240
 
240
241
  ```typescript
241
- // Streaming으로 빠른 초기 렌더링
242
+ // Good: Streaming for fast initial render
242
243
  import { Suspense } from 'react';
243
244
 
244
245
  export default function Dashboard() {
@@ -246,10 +247,10 @@ export default function Dashboard() {
246
247
  <div>
247
248
  <h1>Dashboard</h1>
248
249
 
249
- {/* 빠른 컴포넌트 먼저 렌더 */}
250
+ {/* Fast component renders first */}
250
251
  <QuickStats />
251
252
 
252
- {/* 느린 컴포넌트 나중에 스트리밍 */}
253
+ {/* Slow component streams later */}
253
254
  <Suspense fallback={<ChartSkeleton />}>
254
255
  <SlowChart />
255
256
  </Suspense>
@@ -270,7 +271,7 @@ async function SlowChart() {
270
271
  ### 7. Server Actions
271
272
 
272
273
  ```typescript
273
- // Server Action (서버에서만 실행)
274
+ // Good: Server Action (runs only on server)
274
275
  'use server';
275
276
 
276
277
  import { revalidatePath } from 'next/cache';
@@ -279,18 +280,18 @@ export async function createUser(formData: FormData) {
279
280
  const email = formData.get('email') as string;
280
281
  const name = formData.get('name') as string;
281
282
 
282
- // 서버에서 직접 DB 접근
283
+ // Direct DB access on server
283
284
  const user = await db.user.create({
284
285
  data: { email, name },
285
286
  });
286
287
 
287
- // 캐시 재검증
288
+ // Cache revalidation
288
289
  revalidatePath('/users');
289
290
 
290
291
  return user;
291
292
  }
292
293
 
293
- // 클라이언트에서 사용
294
+ // Good: Usage on client
294
295
  'use client';
295
296
 
296
297
  import { createUser } from './actions';
@@ -309,19 +310,19 @@ export function CreateUserForm() {
309
310
  ### 8. Middleware
310
311
 
311
312
  ```typescript
312
- // middleware.ts (루트)
313
+ // middleware.ts (root)
313
314
  import { NextResponse } from 'next/server';
314
315
  import type { NextRequest } from 'next/server';
315
316
 
316
317
  export function middleware(request: NextRequest) {
317
- // 인증 체크
318
+ // Auth check
318
319
  const token = request.cookies.get('token')?.value;
319
320
 
320
321
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
321
322
  return NextResponse.redirect(new URL('/login', request.url));
322
323
  }
323
324
 
324
- // 헤더 추가
325
+ // Add headers
325
326
  const response = NextResponse.next();
326
327
  response.headers.set('X-Custom-Header', 'value');
327
328
 
@@ -333,14 +334,14 @@ export const config = {
333
334
  };
334
335
  ```
335
336
 
336
- ### 9. 환경 변수
337
+ ### 9. Environment Variables
337
338
 
338
339
  ```typescript
339
- // 서버 전용 환경 변수
340
- const dbUrl = process.env.DATABASE_URL; // 서버 컴포넌트에서만
340
+ // Good: Server-only environment variables
341
+ const dbUrl = process.env.DATABASE_URL; // Server components only
341
342
  const apiKey = process.env.API_SECRET_KEY;
342
343
 
343
- // 클라이언트 노출 환경 변수 (NEXT_PUBLIC_ 접두사)
344
+ // Good: Client-exposed environment variables (NEXT_PUBLIC_ prefix)
344
345
  const publicUrl = process.env.NEXT_PUBLIC_API_URL;
345
346
 
346
347
  // .env.local
@@ -349,12 +350,12 @@ API_SECRET_KEY=secret123
349
350
  NEXT_PUBLIC_API_URL=https://api.example.com
350
351
  ```
351
352
 
352
- ### 10. 이미지 최적화
353
+ ### 10. Image Optimization
353
354
 
354
355
  ```typescript
355
356
  import Image from 'next/image';
356
357
 
357
- // Next.js Image 컴포넌트 (자동 최적화)
358
+ // Good: Next.js Image component (auto optimization)
358
359
  export function UserAvatar({ user }: { user: User }) {
359
360
  return (
360
361
  <Image
@@ -362,12 +363,12 @@ export function UserAvatar({ user }: { user: User }) {
362
363
  alt={user.name}
363
364
  width={100}
364
365
  height={100}
365
- priority // LCP 이미지는 priority
366
+ priority // priority for LCP images
366
367
  />
367
368
  );
368
369
  }
369
370
 
370
- // 외부 이미지 (next.config.js 설정 필요)
371
+ // Good: External images (requires next.config.js configuration)
371
372
  // next.config.js
372
373
  module.exports = {
373
374
  images: {
@@ -376,66 +377,66 @@ module.exports = {
376
377
  };
377
378
  ```
378
379
 
379
- ## 안티패턴
380
+ ## Anti-patterns
380
381
 
381
382
  ```typescript
382
- // 클라이언트 컴포넌트에서 서버 전용 코드
383
+ // Bad: Server-only code in Client Component
383
384
  'use client';
384
385
 
385
386
  function BadComponent() {
386
- const data = await db.user.findMany(); // 클라이언트에서 DB 접근 불가
387
+ const data = await db.user.findMany(); // Bad: Cannot access DB from client
387
388
  }
388
389
 
389
- // 서버 컴포넌트에서 브라우저 API
390
+ // Bad: Browser API in Server Component
390
391
  async function BadServerComponent() {
391
- const width = window.innerWidth; // window 브라우저에만 존재
392
+ const width = window.innerWidth; // Bad: window only exists in browser
392
393
  }
393
394
 
394
- // API Route에서 다른 API Route 호출
395
+ // Bad: Calling API Route from another API Route
395
396
  export async function GET() {
396
- const response = await fetch('http://localhost:3000/api/users'); //
397
- // 대신 직접 DB 함수 호출
398
- const users = await getUsers(); //
397
+ const response = await fetch('http://localhost:3000/api/users'); // Bad
398
+ // Instead, call DB function directly
399
+ const users = await getUsers(); // Good
399
400
  }
400
401
 
401
- // 환경 변수 노출
402
+ // Bad: Exposing environment variables
402
403
  'use client';
403
404
 
404
405
  function BadClient() {
405
- const apiKey = process.env.API_SECRET_KEY; // undefined (클라이언트에서)
406
+ const apiKey = process.env.API_SECRET_KEY; // Bad: undefined (on client)
406
407
  }
407
408
  ```
408
409
 
409
- ## 성능 최적화
410
+ ## Performance Optimization
410
411
 
411
412
  ```typescript
412
- // Static Generation (SSG)
413
+ // Good: Static Generation (SSG)
413
414
  export async function generateStaticParams() {
414
415
  const posts = await getPosts();
415
416
  return posts.map(post => ({ id: post.id }));
416
417
  }
417
418
 
418
- // Incremental Static Regeneration (ISR)
419
- export const revalidate = 60; // 60초마다 재생성
419
+ // Good: Incremental Static Regeneration (ISR)
420
+ export const revalidate = 60; // Regenerate every 60 seconds
420
421
 
421
- // Dynamic Rendering (SSR)
422
+ // Good: Dynamic Rendering (SSR)
422
423
  export const dynamic = 'force-dynamic';
423
424
 
424
- // Partial Prerendering (실험적)
425
+ // Good: Partial Prerendering (experimental)
425
426
  export const experimental_ppr = true;
426
427
  ```
427
428
 
428
- ## 체크리스트
429
+ ## Checklist
429
430
 
430
- Next.js 코드 작성 시:
431
+ When writing Next.js code:
431
432
 
432
- - [ ] App Router 사용 (Pages Router 지양)
433
- - [ ] 서버 컴포넌트 우선 (클라이언트 최소화)
434
- - [ ] API Route 대신 Server Action 고려
435
- - [ ] 메타데이터 정의 (SEO)
436
- - [ ] Suspense로 Streaming
437
- - [ ] Next.js Image 컴포넌트 사용
438
- - [ ] 환경 변수 올바르게 사용
439
- - [ ] Middleware로 인증/권한 체크
440
- - [ ] 캐싱 전략 설정 (revalidate)
441
- - [ ] TypeScript 엄격 모드
433
+ - [ ] Use App Router (avoid Pages Router)
434
+ - [ ] Server Components first (minimize client)
435
+ - [ ] Consider Server Actions instead of API Routes
436
+ - [ ] Define metadata (SEO)
437
+ - [ ] Streaming with Suspense
438
+ - [ ] Use Next.js Image component
439
+ - [ ] Use environment variables correctly
440
+ - [ ] Auth/permission check with Middleware
441
+ - [ ] Configure caching strategy (revalidate)
442
+ - [ ] TypeScript strict mode