@su-record/vibe 2.4.56 โ†’ 2.4.57

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 (44) hide show
  1. package/CLAUDE.md +7 -18
  2. package/agents/compounder.md +1 -1
  3. package/agents/implementer.md +2 -1
  4. package/agents/simplifier.md +2 -1
  5. package/commands/vibe.run.md +4 -1
  6. package/commands/vibe.spec.md +56 -3
  7. package/dist/cli/index.d.ts.map +1 -1
  8. package/dist/cli/index.js +0 -4
  9. package/dist/cli/index.js.map +1 -1
  10. package/dist/cli/postinstall.js +32 -1
  11. package/dist/cli/postinstall.js.map +1 -1
  12. package/dist/cli/setup.d.ts +18 -4
  13. package/dist/cli/setup.d.ts.map +1 -1
  14. package/dist/cli/setup.js +87 -27
  15. package/dist/cli/setup.js.map +1 -1
  16. package/dist/cli/types.d.ts +6 -0
  17. package/dist/cli/types.d.ts.map +1 -1
  18. package/languages/csharp-unity.md +516 -0
  19. package/languages/gdscript-godot.md +470 -0
  20. package/languages/ruby-rails.md +489 -0
  21. package/languages/typescript-angular.md +433 -0
  22. package/languages/typescript-astro.md +416 -0
  23. package/languages/typescript-electron.md +407 -0
  24. package/languages/typescript-nestjs.md +524 -0
  25. package/languages/typescript-svelte.md +407 -0
  26. package/languages/typescript-tauri.md +366 -0
  27. package/package.json +1 -1
  28. package/skills/vibe-capabilities.md +1 -1
  29. package/vibe/constitution.md +130 -97
  30. package/vibe/rules/core/communication-guide.md +50 -56
  31. package/vibe/rules/core/development-philosophy.md +35 -36
  32. package/vibe/rules/core/quick-start.md +66 -85
  33. package/vibe/rules/quality/bdd-contract-testing.md +94 -89
  34. package/vibe/rules/quality/checklist.md +132 -132
  35. package/vibe/rules/quality/testing-strategy.md +132 -129
  36. package/vibe/rules/standards/anti-patterns.md +74 -74
  37. package/vibe/rules/standards/code-structure.md +44 -44
  38. package/vibe/rules/standards/complexity-metrics.md +63 -62
  39. package/vibe/rules/standards/naming-conventions.md +72 -72
  40. package/vibe/templates/constitution-template.md +153 -95
  41. package/vibe/templates/contract-backend-template.md +41 -32
  42. package/vibe/templates/contract-frontend-template.md +35 -30
  43. package/vibe/templates/feature-template.md +33 -33
  44. package/vibe/templates/spec-template.md +118 -96
@@ -1,19 +1,19 @@
1
- # ๐Ÿšซ ์ž๋™ ์•ˆํ‹ฐํŒจํ„ด ํšŒํ”ผ
1
+ # Automatic Anti-Pattern Avoidance
2
2
 
3
- ## TypeScript ์•ˆํ‹ฐํŒจํ„ด
3
+ ## TypeScript Anti-Patterns
4
4
 
5
- ### 1. any ํƒ€์ž… ์‚ฌ์šฉ
5
+ ### 1. Using any Type
6
6
 
7
7
  ```typescript
8
- // โŒ any ์‚ฌ์šฉ
8
+ // โŒ Using any
9
9
  function processData(data: any) {
10
- return data.value; // ํƒ€์ž… ์•ˆ์ „์„ฑ ์ƒ์‹ค
10
+ return data.value; // Loss of type safety
11
11
  }
12
12
 
13
13
  // โœ… unknown + type guard
14
14
  function processData(data: unknown) {
15
15
  if (isValidData(data)) {
16
- return data.value; // ํƒ€์ž… ์•ˆ์ „
16
+ return data.value; // Type safe
17
17
  }
18
18
  throw new Error('Invalid data');
19
19
  }
@@ -23,31 +23,31 @@ function isValidData(data: unknown): data is { value: string } {
23
23
  }
24
24
  ```
25
25
 
26
- ### 2. as any ๊ฐ•์ œ ํƒ€์ž… ์บ์ŠคํŒ…
26
+ ### 2. Forced Type Casting with as any
27
27
 
28
28
  ```typescript
29
- // โŒ as any๋กœ ํƒ€์ž… ์šฐํšŒ
29
+ // โŒ Bypassing types with as any
30
30
  const user = response as any;
31
- user.name; // ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ ์œ„ํ—˜
31
+ user.name; // Runtime error risk
32
32
 
33
- // โœ… ์ ์ ˆํ•œ ํƒ€์ž… ์ •์˜
33
+ // โœ… Proper type definition
34
34
  interface User {
35
35
  name: string;
36
36
  email: string;
37
37
  }
38
38
 
39
39
  const user = response as User;
40
- user.name; // ํƒ€์ž… ์•ˆ์ „
40
+ user.name; // Type safe
41
41
  ```
42
42
 
43
- ### 3. @ts-ignore ๋‚จ์šฉ
43
+ ### 3. Overusing @ts-ignore
44
44
 
45
45
  ```typescript
46
- // โŒ @ts-ignore๋กœ ์—๋Ÿฌ ๋ฌด์‹œ
46
+ // โŒ Ignoring errors with @ts-ignore
47
47
  // @ts-ignore
48
48
  const result = problematicCode();
49
49
 
50
- // โœ… ํƒ€์ž… ๋ฌธ์ œ ๊ทผ๋ณธ ํ•ด๊ฒฐ
50
+ // โœ… Fix the type issue at its root
51
51
  interface Expected {
52
52
  id: string;
53
53
  }
@@ -57,17 +57,17 @@ const result: Expected = {
57
57
  };
58
58
  ```
59
59
 
60
- ## React ์•ˆํ‹ฐํŒจํ„ด
60
+ ## React Anti-Patterns
61
61
 
62
- ### 1. dangerouslySetInnerHTML ์‚ฌ์šฉ
62
+ ### 1. Using dangerouslySetInnerHTML
63
63
 
64
64
  ```typescript
65
- // โŒ XSS ์ทจ์•ฝ์ 
65
+ // โŒ XSS vulnerability
66
66
  function Component({ html }: { html: string }) {
67
67
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
68
68
  }
69
69
 
70
- // โœ… ์•ˆ์ „ํ•œ ๋ Œ๋”๋ง
70
+ // โœ… Safe rendering
71
71
  import DOMPurify from 'dompurify';
72
72
 
73
73
  function Component({ html }: { html: string }) {
@@ -75,7 +75,7 @@ function Component({ html }: { html: string }) {
75
75
  return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
76
76
  }
77
77
 
78
- // โœ… ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•: ๋งˆํฌ๋‹ค์šด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ
78
+ // โœ… Better approach: Use markdown library
79
79
  import ReactMarkdown from 'react-markdown';
80
80
 
81
81
  function Component({ markdown }: { markdown: string }) {
@@ -83,7 +83,7 @@ function Component({ markdown }: { markdown: string }) {
83
83
  }
84
84
  ```
85
85
 
86
- ### 2. Props Drilling (3๋‹จ๊ณ„ ์ด์ƒ)
86
+ ### 2. Props Drilling (More than 3 levels)
87
87
 
88
88
  ```typescript
89
89
  // โŒ Props drilling
@@ -104,7 +104,7 @@ function GrandChild({ user }: { user: User }) {
104
104
  return <div>{user.name}</div>;
105
105
  }
106
106
 
107
- // โœ… Context API ์‚ฌ์šฉ
107
+ // โœ… Use Context API
108
108
  const UserContext = createContext<User | undefined>(undefined);
109
109
 
110
110
  function App() {
@@ -122,73 +122,73 @@ function GrandChild() {
122
122
  }
123
123
  ```
124
124
 
125
- ### 3. useEffect ์˜์กด์„ฑ ๋ฐฐ์—ด ๋ˆ„๋ฝ
125
+ ### 3. Missing useEffect Dependency Array
126
126
 
127
127
  ```typescript
128
- // โŒ ์˜์กด์„ฑ ๋ˆ„๋ฝ
128
+ // โŒ Missing dependency
129
129
  function Component({ userId }: { userId: string }) {
130
130
  const [user, setUser] = useState<User>();
131
131
 
132
132
  useEffect(() => {
133
133
  fetchUser(userId).then(setUser);
134
- }, []); // userId ์˜์กด์„ฑ ๋ˆ„๋ฝ!
134
+ }, []); // Missing userId dependency!
135
135
 
136
136
  return <div>{user?.name}</div>;
137
137
  }
138
138
 
139
- // โœ… ๋ชจ๋“  ์˜์กด์„ฑ ๋ช…์‹œ
139
+ // โœ… Specify all dependencies
140
140
  function Component({ userId }: { userId: string }) {
141
141
  const [user, setUser] = useState<User>();
142
142
 
143
143
  useEffect(() => {
144
144
  fetchUser(userId).then(setUser);
145
- }, [userId]); // ์˜์กด์„ฑ ๋ช…์‹œ
145
+ }, [userId]); // Dependency specified
146
146
 
147
147
  return <div>{user?.name}</div>;
148
148
  }
149
149
  ```
150
150
 
151
- ## JavaScript ์•ˆํ‹ฐํŒจํ„ด
151
+ ## JavaScript Anti-Patterns
152
152
 
153
- ### 1. var ์‚ฌ์šฉ
153
+ ### 1. Using var
154
154
 
155
155
  ```typescript
156
- // โŒ var ์‚ฌ์šฉ
156
+ // โŒ Using var
157
157
  var count = 0;
158
158
  if (true) {
159
- var count = 1; // ๊ฐ™์€ ๋ณ€์ˆ˜!
159
+ var count = 1; // Same variable!
160
160
  }
161
161
  console.log(count); // 1
162
162
 
163
- // โœ… const/let ์‚ฌ์šฉ
163
+ // โœ… Use const/let
164
164
  let count = 0;
165
165
  if (true) {
166
- let count = 1; // ๋ธ”๋ก ์Šค์ฝ”ํ”„
166
+ let count = 1; // Block scope
167
167
  }
168
168
  console.log(count); // 0
169
169
  ```
170
170
 
171
- ### 2. == ์‚ฌ์šฉ (๋А์Šจํ•œ ๋น„๊ต)
171
+ ### 2. Using == (Loose Comparison)
172
172
 
173
173
  ```typescript
174
- // โŒ == ์‚ฌ์šฉ
175
- if (value == null) { } // undefined๋„ ๋งค์นญ
176
- if ('5' == 5) { } // true (ํƒ€์ž… ๊ฐ•์ œ ๋ณ€ํ™˜)
174
+ // โŒ Using ==
175
+ if (value == null) { } // Also matches undefined
176
+ if ('5' == 5) { } // true (type coercion)
177
177
 
178
- // โœ… === ์‚ฌ์šฉ
178
+ // โœ… Use ===
179
179
  if (value === null) { }
180
180
  if (value === undefined) { }
181
181
  if ('5' === 5) { } // false
182
182
  ```
183
183
 
184
- ### 3. eval() ์‚ฌ์šฉ
184
+ ### 3. Using eval()
185
185
 
186
186
  ```typescript
187
- // โŒ eval() ์‚ฌ์šฉ (๋ณด์•ˆ ์œ„ํ—˜)
187
+ // โŒ Using eval() (security risk)
188
188
  const code = userInput;
189
- eval(code); // ์ž„์˜ ์ฝ”๋“œ ์‹คํ–‰ ๊ฐ€๋Šฅ
189
+ eval(code); // Can execute arbitrary code
190
190
 
191
- // โœ… ๋Œ€์•ˆ ๊ตฌํ˜„
191
+ // โœ… Alternative implementation
192
192
  const allowedOperations = {
193
193
  add: (a: number, b: number) => a + b,
194
194
  subtract: (a: number, b: number) => a - b,
@@ -200,28 +200,28 @@ if (operation) {
200
200
  }
201
201
  ```
202
202
 
203
- ## CSS ์•ˆํ‹ฐํŒจํ„ด
203
+ ## CSS Anti-Patterns
204
204
 
205
- ### 1. !important ๋‚จ์šฉ
205
+ ### 1. Overusing !important
206
206
 
207
207
  ```css
208
- /* โŒ !important ๋‚จ์šฉ */
208
+ /* โŒ Overusing !important */
209
209
  .button {
210
210
  color: blue !important;
211
211
  background: red !important;
212
212
  }
213
213
 
214
- /* โœ… ๊ตฌ์ฒด์ ์ธ ์„ ํƒ์ž ์‚ฌ์šฉ */
214
+ /* โœ… Use specific selectors */
215
215
  .navigation .button.primary {
216
216
  color: blue;
217
217
  background: red;
218
218
  }
219
219
  ```
220
220
 
221
- ### 2. ์ธ๋ผ์ธ ์Šคํƒ€์ผ ๋‚จ์šฉ
221
+ ### 2. Overusing Inline Styles
222
222
 
223
223
  ```typescript
224
- // โŒ ์ธ๋ผ์ธ ์Šคํƒ€์ผ
224
+ // โŒ Inline styles
225
225
  function Button() {
226
226
  return (
227
227
  <button
@@ -237,7 +237,7 @@ function Button() {
237
237
  );
238
238
  }
239
239
 
240
- // โœ… CSS ํด๋ž˜์Šค ์‚ฌ์šฉ
240
+ // โœ… Use CSS classes
241
241
  function Button() {
242
242
  return <button className="btn-primary">Click me</button>;
243
243
  }
@@ -251,18 +251,18 @@ function Button() {
251
251
  }
252
252
  ```
253
253
 
254
- ## ์„ฑ๋Šฅ ์•ˆํ‹ฐํŒจํ„ด
254
+ ## Performance Anti-Patterns
255
255
 
256
- ### 1. ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง
256
+ ### 1. Unnecessary Re-renders
257
257
 
258
258
  ```typescript
259
- // โŒ ๋งค๋ฒˆ ์ƒˆ ๊ฐ์ฒด/ํ•จ์ˆ˜ ์ƒ์„ฑ
259
+ // โŒ Creating new objects/functions every render
260
260
  function Parent() {
261
261
  return <Child config={{ theme: 'dark' }} onClick={() => {}} />;
262
- // ๋งค ๋ Œ๋”๋งˆ๋‹ค ์ƒˆ ๊ฐ์ฒด/ํ•จ์ˆ˜ ์ƒ์„ฑ โ†’ Child ๋ฆฌ๋ Œ๋”
262
+ // New object/function created every render โ†’ Child re-renders
263
263
  }
264
264
 
265
- // โœ… useMemo/useCallback ์‚ฌ์šฉ
265
+ // โœ… Use useMemo/useCallback
266
266
  function Parent() {
267
267
  const config = useMemo(() => ({ theme: 'dark' }), []);
268
268
  const handleClick = useCallback(() => {}, []);
@@ -271,10 +271,10 @@ function Parent() {
271
271
  }
272
272
  ```
273
273
 
274
- ### 2. ๋™๊ธฐ์  ๋ฌด๊ฑฐ์šด ์—ฐ์‚ฐ
274
+ ### 2. Synchronous Heavy Computations
275
275
 
276
276
  ```typescript
277
- // โŒ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ๋ธ”๋กœํ‚น
277
+ // โŒ Blocking main thread
278
278
  function Component({ data }: { data: number[] }) {
279
279
  const result = data
280
280
  .map(heavyComputation)
@@ -284,7 +284,7 @@ function Component({ data }: { data: number[] }) {
284
284
  return <div>{result}</div>;
285
285
  }
286
286
 
287
- // โœ… useMemo๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜
287
+ // โœ… Memoization with useMemo
288
288
  function Component({ data }: { data: number[] }) {
289
289
  const result = useMemo(
290
290
  () =>
@@ -299,42 +299,42 @@ function Component({ data }: { data: number[] }) {
299
299
  }
300
300
  ```
301
301
 
302
- ## ๋ณด์•ˆ ์•ˆํ‹ฐํŒจํ„ด
302
+ ## Security Anti-Patterns
303
303
 
304
- ### 1. ๋ฏผ๊ฐ ์ •๋ณด ํ•˜๋“œ์ฝ”๋”ฉ
304
+ ### 1. Hardcoding Sensitive Information
305
305
 
306
306
  ```typescript
307
- // โŒ API ํ‚ค ํ•˜๋“œ์ฝ”๋”ฉ
307
+ // โŒ Hardcoded API key
308
308
  const API_KEY = 'sk-1234567890abcdef';
309
309
 
310
- // โœ… ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์‚ฌ์šฉ
310
+ // โœ… Use environment variables
311
311
  const API_KEY = process.env.NEXT_PUBLIC_API_KEY;
312
312
  ```
313
313
 
314
- ### 2. SQL Injection ์ทจ์•ฝ์ 
314
+ ### 2. SQL Injection Vulnerability
315
315
 
316
316
  ```typescript
317
- // โŒ ์ง์ ‘ ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ
317
+ // โŒ Direct string concatenation
318
318
  const query = `SELECT * FROM users WHERE id = ${userId}`;
319
319
 
320
- // โœ… ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋œ ์ฟผ๋ฆฌ
320
+ // โœ… Parameterized query
321
321
  const query = 'SELECT * FROM users WHERE id = ?';
322
322
  db.execute(query, [userId]);
323
323
  ```
324
324
 
325
- ## ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์•ˆํ‹ฐํŒจํ„ด
325
+ ## Error Handling Anti-Patterns
326
326
 
327
- ### 1. ๋นˆ catch ๋ธ”๋ก
327
+ ### 1. Empty catch Block
328
328
 
329
329
  ```typescript
330
- // โŒ ์—๋Ÿฌ ๋ฌด์‹œ
330
+ // โŒ Ignoring errors
331
331
  try {
332
332
  riskyOperation();
333
333
  } catch (e) {
334
- // ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ํ•จ
334
+ // Does nothing
335
335
  }
336
336
 
337
- // โœ… ์ ์ ˆํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
337
+ // โœ… Proper error handling
338
338
  try {
339
339
  riskyOperation();
340
340
  } catch (error) {
@@ -344,26 +344,26 @@ try {
344
344
  }
345
345
  ```
346
346
 
347
- ### 2. ์—๋Ÿฌ ํƒ€์ž… ํ™•์ธ ์—†์ด ์ฒ˜๋ฆฌ
347
+ ### 2. Handling Without Error Type Check
348
348
 
349
349
  ```typescript
350
- // โŒ ๋ชจ๋“  ์—๋Ÿฌ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌ
350
+ // โŒ Treating all errors the same
351
351
  try {
352
352
  await fetchData();
353
353
  } catch (error) {
354
- showError('Failed'); // ๊ตฌ์ฒด์ ์ด์ง€ ์•Š์Œ
354
+ showError('Failed'); // Not specific
355
355
  }
356
356
 
357
- // โœ… ์—๋Ÿฌ ํƒ€์ž…๋ณ„ ์ฒ˜๋ฆฌ
357
+ // โœ… Handle by error type
358
358
  try {
359
359
  await fetchData();
360
360
  } catch (error) {
361
361
  if (error instanceof NetworkError) {
362
- showError('๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”');
362
+ showError('Please check your network connection');
363
363
  } else if (error instanceof AuthError) {
364
364
  redirectToLogin();
365
365
  } else {
366
- showError('์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค');
366
+ showError('An unknown error occurred');
367
367
  }
368
368
  }
369
369
  ```
@@ -1,17 +1,17 @@
1
- # ๐Ÿ—๏ธ ์ฝ”๋“œ ๊ตฌ์กฐ ์ž๋™ํ™” ๊ทœ์น™
1
+ # Code Structure Automation Rules
2
2
 
3
- ## ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ (์—„๊ฒฉํ•œ ์ˆœ์„œ)
3
+ ## Component Structure (Strict Order)
4
4
 
5
5
  ```typescript
6
- // 1. Import ๋ฌธ
6
+ // 1. Import statements
7
7
  import React, { useState, useEffect } from 'react';
8
8
 
9
- // 2. ํƒ€์ž…/์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
9
+ // 2. Type/Interface definitions
10
10
  interface Props {
11
11
  userId: string;
12
12
  }
13
13
 
14
- // 3. ์ปดํฌ๋„ŒํŠธ ์ •์˜
14
+ // 3. Component definition
15
15
  function UserProfile({ userId }: Props) {
16
16
  // 4. State & Refs
17
17
  const [user, setUser] = useState<User | null>(null);
@@ -45,17 +45,17 @@ function UserProfile({ userId }: Props) {
45
45
  }
46
46
  ```
47
47
 
48
- ## ํ•จ์ˆ˜ ๋ถ„๋ฆฌ ๊ธฐ์ค€
48
+ ## Function Separation Criteria
49
49
 
50
- ### 1. ํ•จ์ˆ˜ ๊ธธ์ด ๊ธฐ์ค€
50
+ ### 1. Function Length Criteria
51
51
 
52
52
  ```typescript
53
- // โŒ 20์ค„ ์ดˆ๊ณผ - ๋ถ„๋ฆฌ ํ•„์š”
53
+ // โŒ Over 20 lines - needs separation
54
54
  function processUserData(user: User) {
55
- // 30์ค„์˜ ๋ณต์žกํ•œ ๋กœ์ง
55
+ // 30 lines of complex logic
56
56
  }
57
57
 
58
- // โœ… ๋‹จ์ผ ์ฑ…์ž„์œผ๋กœ ๋ถ„๋ฆฌ
58
+ // โœ… Separate by single responsibility
59
59
  function processUserData(user: User) {
60
60
  const validated = validateUser(user);
61
61
  const transformed = transformUserData(validated);
@@ -67,19 +67,19 @@ function transformUserData(user: User) { /* ... */ }
67
67
  function saveUserData(user: User) { /* ... */ }
68
68
  ```
69
69
 
70
- ### 2. ์ปดํฌ๋„ŒํŠธ JSX ๊ธธ์ด ๊ธฐ์ค€
70
+ ### 2. Component JSX Length Criteria
71
71
 
72
72
  ```typescript
73
- // โŒ JSX 50์ค„ ์ดˆ๊ณผ - ๋ถ„๋ฆฌ ํ•„์š”
73
+ // โŒ JSX over 50 lines - needs separation
74
74
  function Dashboard() {
75
75
  return (
76
76
  <div>
77
- {/* 60์ค„์˜ ๋ณต์žกํ•œ JSX */}
77
+ {/* 60 lines of complex JSX */}
78
78
  </div>
79
79
  );
80
80
  }
81
81
 
82
- // โœ… ์„œ๋ธŒ ์ปดํฌ๋„ŒํŠธ ์ถ”์ถœ
82
+ // โœ… Extract sub-components
83
83
  function Dashboard() {
84
84
  return (
85
85
  <div>
@@ -95,37 +95,37 @@ function DashboardContent() { /* ... */ }
95
95
  function DashboardFooter() { /* ... */ }
96
96
  ```
97
97
 
98
- ### 3. ์ค‘์ฒฉ ๊นŠ์ด ๊ธฐ์ค€
98
+ ### 3. Nesting Depth Criteria
99
99
 
100
100
  ```typescript
101
- // โŒ ์ค‘์ฒฉ 3๋‹จ๊ณ„ ์ดˆ๊ณผ
101
+ // โŒ Nesting over 3 levels
102
102
  function processData(data: Data) {
103
103
  if (data) {
104
104
  if (data.isValid) {
105
105
  if (data.user) {
106
106
  if (data.user.isActive) {
107
- // ๋„ˆ๋ฌด ๊นŠ์€ ์ค‘์ฒฉ
107
+ // Too deep nesting
108
108
  }
109
109
  }
110
110
  }
111
111
  }
112
112
  }
113
113
 
114
- // โœ… Early return์œผ๋กœ ํ‰ํƒ„ํ™”
114
+ // โœ… Flatten with early returns
115
115
  function processData(data: Data) {
116
116
  if (!data) return null;
117
117
  if (!data.isValid) return null;
118
118
  if (!data.user) return null;
119
119
  if (!data.user.isActive) return null;
120
120
 
121
- // ๋กœ์ง ์‹คํ–‰
121
+ // Execute logic
122
122
  }
123
123
  ```
124
124
 
125
125
  ### 4. Cyclomatic Complexity > 10
126
126
 
127
127
  ```typescript
128
- // โŒ ๋ณต์žก๋„ ๋†’์Œ (15)
128
+ // โŒ High complexity (15)
129
129
  function calculatePrice(item: Item) {
130
130
  let price = item.basePrice;
131
131
  if (item.discount) price *= 0.9;
@@ -133,11 +133,11 @@ function calculatePrice(item: Item) {
133
133
  if (item.seasonal) price *= 0.95;
134
134
  if (item.member) price *= 0.85;
135
135
  if (item.firstTime) price *= 0.9;
136
- // ... ๋” ๋งŽ์€ ์กฐ๊ฑด
136
+ // ... more conditions
137
137
  return price;
138
138
  }
139
139
 
140
- // โœ… ๋ณต์žก๋„ ๊ฐ์†Œ (3)
140
+ // โœ… Reduced complexity (3)
141
141
  function calculatePrice(item: Item) {
142
142
  const basePrice = item.basePrice;
143
143
  const discounts = getApplicableDiscounts(item);
@@ -148,20 +148,20 @@ function calculatePrice(item: Item) {
148
148
  ### 5. Cognitive Complexity > 15
149
149
 
150
150
  ```typescript
151
- // โŒ ์ธ์ง€ ๋ณต์žก๋„ ๋†’์Œ
151
+ // โŒ High cognitive complexity
152
152
  function processOrder(order: Order) {
153
153
  if (order.isPremium) {
154
154
  for (let item of order.items) {
155
155
  if (item.category === 'electronics') {
156
156
  if (item.price > 1000) {
157
- // ์ค‘์ฒฉ๋œ ๋ณต์žกํ•œ ๋กœ์ง
157
+ // Nested complex logic
158
158
  }
159
159
  }
160
160
  }
161
161
  }
162
162
  }
163
163
 
164
- // โœ… ์ธ์ง€ ๋ณต์žก๋„ ๊ฐ์†Œ
164
+ // โœ… Reduced cognitive complexity
165
165
  function processOrder(order: Order) {
166
166
  if (!order.isPremium) return;
167
167
 
@@ -172,7 +172,7 @@ function processOrder(order: Order) {
172
172
  }
173
173
  ```
174
174
 
175
- ## ํŒŒ์ผ ๊ตฌ์กฐ ํ‘œ์ค€
175
+ ## File Structure Standard
176
176
 
177
177
  ```typescript
178
178
  // ๐Ÿ“ user-profile.component.tsx
@@ -189,23 +189,23 @@ type UserRole = 'admin' | 'user';
189
189
  const MAX_BIO_LENGTH = 500;
190
190
  const DEFAULT_AVATAR = '/avatar.png';
191
191
 
192
- // 4. Helper Functions (๋‚ด๋ถ€ ์ „์šฉ)
192
+ // 4. Helper Functions (internal only)
193
193
  function formatUserName(name: string) { }
194
194
 
195
195
  // 5. Main Component
196
196
  export function UserProfile() { }
197
197
 
198
- // 6. Sub Components (exportํ•˜์ง€ ์•Š์Œ)
198
+ // 6. Sub Components (not exported)
199
199
  function ProfileHeader() { }
200
200
  function ProfileContent() { }
201
201
  ```
202
202
 
203
- ## ๋ชจ๋“ˆ ๊ตฌ์„ฑ ์›์น™
203
+ ## Module Organization Principles
204
204
 
205
- ### 1. ์‘์ง‘๋„ (Cohesion)
205
+ ### 1. Cohesion
206
206
 
207
207
  ```typescript
208
- // โœ… ๋†’์€ ์‘์ง‘๋„ - ๊ด€๋ จ ๊ธฐ๋Šฅ๋งŒ ๋ชจ์Œ
208
+ // โœ… High cohesion - only related functions
209
209
  // ๐Ÿ“ user.service.ts
210
210
  export class UserService {
211
211
  getUser(id: string) { }
@@ -213,8 +213,8 @@ export class UserService {
213
213
  deleteUser(id: string) { }
214
214
  }
215
215
 
216
- // โŒ ๋‚ฎ์€ ์‘์ง‘๋„ - ๊ด€๋ จ ์—†๋Š” ๊ธฐ๋Šฅ ํ˜ผ์žฌ
217
- // ๐Ÿ“ utils.ts (์•ˆํ‹ฐํŒจํ„ด)
216
+ // โŒ Low cohesion - unrelated functions mixed
217
+ // ๐Ÿ“ utils.ts (anti-pattern)
218
218
  export class Utils {
219
219
  validateEmail(email: string) { }
220
220
  formatCurrency(amount: number) { }
@@ -222,10 +222,10 @@ export class Utils {
222
222
  }
223
223
  ```
224
224
 
225
- ### 2. ๊ฒฐํ•ฉ๋„ (Coupling)
225
+ ### 2. Coupling
226
226
 
227
227
  ```typescript
228
- // โœ… ๋А์Šจํ•œ ๊ฒฐํ•ฉ - ์ธํ„ฐํŽ˜์ด์Šค ์˜์กด
228
+ // โœ… Loose coupling - depends on interface
229
229
  interface Storage {
230
230
  save(key: string, value: unknown): void;
231
231
  load(key: string): unknown;
@@ -235,16 +235,16 @@ class UserService {
235
235
  constructor(private storage: Storage) { }
236
236
  }
237
237
 
238
- // โŒ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ - ๊ตฌํ˜„์ฒด ์ง์ ‘ ์˜์กด
238
+ // โŒ Tight coupling - depends on implementation directly
239
239
  class UserService {
240
- private storage = new LocalStorage(); // ์ง์ ‘ ์˜์กด
240
+ private storage = new LocalStorage(); // Direct dependency
241
241
  }
242
242
  ```
243
243
 
244
- ## ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ œํ•œ
244
+ ## Function Parameter Limit
245
245
 
246
246
  ```typescript
247
- // โŒ ๋งค๊ฐœ๋ณ€์ˆ˜ 5๊ฐœ ์ดˆ๊ณผ
247
+ // โŒ Over 5 parameters
248
248
  function createUser(
249
249
  name: string,
250
250
  email: string,
@@ -254,7 +254,7 @@ function createUser(
254
254
  role: string
255
255
  ) { }
256
256
 
257
- // โœ… ๊ฐ์ฒด๋กœ ๊ทธ๋ฃนํ™”
257
+ // โœ… Group into object
258
258
  interface CreateUserParams {
259
259
  name: string;
260
260
  email: string;
@@ -267,19 +267,19 @@ interface CreateUserParams {
267
267
  function createUser(params: CreateUserParams) { }
268
268
  ```
269
269
 
270
- ## ์ˆœํ™˜ ์˜์กด์„ฑ ๋ฐฉ์ง€
270
+ ## Preventing Circular Dependencies
271
271
 
272
272
  ```typescript
273
- // โŒ ์ˆœํ™˜ ์˜์กด์„ฑ
273
+ // โŒ Circular dependency
274
274
  // fileA.ts
275
275
  import { funcB } from './fileB';
276
276
  export function funcA() { funcB(); }
277
277
 
278
278
  // fileB.ts
279
- import { funcA } from './fileA'; // ์ˆœํ™˜!
279
+ import { funcA } from './fileA'; // Circular!
280
280
  export function funcB() { funcA(); }
281
281
 
282
- // โœ… ๊ณตํ†ต ๋ชจ๋“ˆ ๋ถ„๋ฆฌ
282
+ // โœ… Separate common module
283
283
  // shared.ts
284
284
  export function sharedFunc() { }
285
285