@kood/claude-code 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +69 -12
- package/package.json +2 -1
- package/templates/.claude/PARALLEL_AGENTS.md +737 -0
- package/templates/.claude/agents/analyst.md +416 -0
- package/templates/.claude/agents/architect.md +569 -0
- package/templates/.claude/agents/code-reviewer.md +132 -133
- package/templates/.claude/agents/dependency-manager.md +93 -94
- package/templates/.claude/agents/deployment-validator.md +64 -65
- package/templates/.claude/agents/designer.md +655 -0
- package/templates/.claude/agents/document-writer.md +500 -0
- package/templates/.claude/agents/explore.md +499 -0
- package/templates/.claude/agents/git-operator.md +74 -75
- package/templates/.claude/agents/implementation-executor.md +138 -109
- package/templates/.claude/agents/ko-to-en-translator.md +18 -22
- package/templates/.claude/agents/lint-fixer.md +250 -93
- package/templates/.claude/agents/planner.md +356 -0
- package/templates/.claude/agents/refactor-advisor.md +135 -136
- package/templates/.claude/commands/bug-fix.md +296 -207
- package/templates/.claude/commands/git-all.md +199 -46
- package/templates/.claude/commands/git-session.md +113 -57
- package/templates/.claude/commands/lint-fix.md +219 -153
- package/templates/.claude/commands/lint-init.md +113 -76
- package/templates/.claude/commands/pre-deploy.md +190 -124
- package/templates/.claude/commands/refactor.md +407 -162
- package/templates/.claude/commands/version-update.md +138 -37
- package/templates/.claude/instructions/context-engineering/ANTHROPIC_CONTEXT_ENGINEERING.md +178 -0
- package/templates/.claude/instructions/context-engineering/references/claude-4x.md +215 -0
- package/templates/.claude/instructions/context-engineering/references/core-principles.md +137 -0
- package/templates/.claude/instructions/context-engineering/references/examples.md +351 -0
- package/templates/.claude/instructions/context-engineering/references/techniques.md +162 -0
- package/templates/.claude/instructions/parallel-agent-execution.md +874 -0
- package/templates/.claude/skills/docs-creator/AGENTS.md +238 -0
- package/templates/.claude/{commands/docs-creator.md → skills/docs-creator/SKILL.md} +61 -75
- package/templates/.claude/skills/docs-refactor/AGENTS.md +270 -0
- package/templates/.claude/{commands/docs-refactor.md → skills/docs-refactor/SKILL.md} +30 -44
- package/templates/.claude/skills/execute/SKILL.md +451 -0
- package/templates/.claude/skills/figma-to-code/AGENTS.md +287 -0
- package/templates/.claude/skills/figma-to-code/SKILL.md +225 -225
- package/templates/.claude/skills/figma-to-code/references/design-tokens.md +75 -73
- package/templates/.claude/skills/figma-to-code/references/figma-mcp-tools.md +73 -73
- package/templates/.claude/skills/figma-to-code/references/layout-mapping.md +104 -104
- package/templates/.claude/skills/figma-to-code/references/responsive-design.md +99 -99
- package/templates/.claude/skills/figma-to-code/references/verification.md +91 -91
- package/templates/.claude/skills/global-uiux-design/AGENTS.md +317 -0
- package/templates/.claude/skills/global-uiux-design/SKILL.md +738 -0
- package/templates/.claude/skills/global-uiux-design/references/accessibility.md +401 -0
- package/templates/.claude/skills/global-uiux-design/references/color-system.md +275 -0
- package/templates/.claude/skills/global-uiux-design/references/design-philosophy.md +206 -0
- package/templates/.claude/skills/global-uiux-design/references/design-systems.md +446 -0
- package/templates/.claude/skills/korea-uiux-design/AGENTS.md +307 -0
- package/templates/.claude/skills/korea-uiux-design/SKILL.md +170 -0
- package/templates/.claude/skills/nextjs-react-best-practices/AGENTS.md +95 -116
- package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +134 -152
- package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-event-handler-refs.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-use-latest.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-api-routes.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-defer-await.md +22 -22
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-dependencies.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-parallel.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-suspense-boundaries.md +21 -21
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-barrel-imports.md +18 -18
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-conditional.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-defer-third-party.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-dynamic-imports.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-preload.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/client-event-listeners.md +9 -9
- package/templates/.claude/skills/nextjs-react-best-practices/rules/client-swr-dedup.md +7 -7
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-batch-dom-css.md +13 -13
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-function-results.md +14 -14
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-property-access.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-storage.md +10 -10
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-combine-iterations.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-early-exit.md +7 -7
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-hoist-regexp.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-index-maps.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-length-check-first.md +14 -14
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-min-max-loop.md +16 -16
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-set-map-lookups.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-tosorted-immutable.md +17 -17
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-activity.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-animate-svg-wrapper.md +11 -11
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-conditional-render.md +8 -8
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-content-visibility.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-hoist-jsx.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-hydration-no-flicker.md +14 -14
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-svg-precision.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-defer-reads.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-dependencies.md +7 -7
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-derived-state.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-functional-setstate.md +34 -34
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-lazy-state-init.md +15 -15
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-memo.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-transitions.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-after-nonblocking.md +24 -24
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-cache-lru.md +10 -10
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-cache-react.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-parallel-fetching.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-serialization.md +6 -6
- package/templates/.claude/skills/plan/SKILL.md +594 -0
- package/templates/.claude/skills/prd/SKILL.md +496 -0
- package/templates/.claude/skills/ralph/AGENTS.md +393 -0
- package/templates/.claude/skills/ralph/SKILL.md +1035 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +100 -121
- package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +139 -157
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-defer-await.md +22 -22
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-dependencies.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-loader.md +7 -7
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-parallel.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-barrel-imports.md +18 -18
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-conditional.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-lazy-routes.md +12 -12
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-preload.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-event-listeners.md +9 -9
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-tanstack-query.md +12 -12
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-batch-dom-css.md +13 -13
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-function-results.md +14 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-property-access.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-storage.md +10 -10
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-combine-iterations.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-early-exit.md +7 -7
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-hoist-regexp.md +6 -6
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-index-maps.md +6 -6
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-length-check-first.md +14 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-min-max-loop.md +16 -16
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-set-map-lookups.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-tosorted-immutable.md +17 -17
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-animate-svg-wrapper.md +11 -11
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-conditional-render.md +8 -8
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-content-visibility.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-hoist-jsx.md +6 -6
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-svg-precision.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-defer-reads.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-dependencies.md +7 -7
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-derived-state.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-functional-setstate.md +34 -34
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-lazy-state-init.md +15 -15
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-memo.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-transitions.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-cache-lru.md +12 -12
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +14 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-parallel-fetching.md +9 -9
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +6 -6
- package/templates/.claude/commands/agent-creator.md +0 -370
- package/templates/.claude/commands/command-creator.md +0 -524
- package/templates/.claude/commands/execute.md +0 -469
- package/templates/.claude/commands/git.md +0 -98
- package/templates/.claude/commands/plan.md +0 -526
- package/templates/.claude/commands/prd.md +0 -629
|
@@ -6,45 +6,44 @@ model: sonnet
|
|
|
6
6
|
permissionMode: default
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
너는 시니어 코드 리뷰어다. 높은 기준을 유지하며 건설적인 피드백을 제공한다.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
호출 시 수행할 작업:
|
|
12
|
+
1. `git diff` 실행하여 변경사항 확인
|
|
13
|
+
2. 수정된 파일에 집중
|
|
14
|
+
3. 체크리스트 기반 검토
|
|
15
|
+
4. 우선순위별 피드백 (치명적 > 경고 > 제안)
|
|
16
|
+
5. 구체적 수정 방법 및 코드 예시 제공
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
- 설명, 요약, 보고서, 피드백 등 사용자에게 전달하는 모든 내용은 반드시 한국어
|
|
15
|
-
- 사용자가 영어로 말하더라도 답변은 한국어로
|
|
16
|
-
- 진행 상황 업데이트와 상태 보고는 반드시 한국어
|
|
17
|
-
|
|
18
|
-
이 규칙은 절대적이며 예외가 없습니다.
|
|
18
|
+
---
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
<parallel_execution>
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## Agent Coordination
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
| 항목 | 설명 |
|
|
25
|
+
|------|------|
|
|
26
|
+
| **병렬 실행** | 불가 (git diff 기반 순차 검토) |
|
|
27
|
+
| **연계 Agent** | git-operator (커밋 전 리뷰), deployment-validator (배포 전 검토) |
|
|
28
|
+
| **권장 모델** | sonnet (코드 품질 분석) |
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
1. Run `git diff` to view changes
|
|
28
|
-
2. Focus on modified files
|
|
29
|
-
3. Review based on checklist
|
|
30
|
-
4. Provide feedback by priority (critical > warning > suggestion)
|
|
31
|
-
5. Provide specific fixes and code examples
|
|
30
|
+
</parallel_execution>
|
|
32
31
|
|
|
33
32
|
---
|
|
34
33
|
|
|
35
34
|
<review_checklist>
|
|
36
35
|
|
|
37
|
-
##
|
|
36
|
+
## 검토 체크리스트
|
|
38
37
|
|
|
39
|
-
|
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
38
|
+
| 영역 | 확인 항목 | 중요도 |
|
|
39
|
+
|------|----------|--------|
|
|
40
|
+
| **코드 품질** | 단순성, 가독성, 명명, 중복 제거 | High |
|
|
41
|
+
| **보안** | 입력 검증, 인증/인가, 시크릿 노출, SQL/XSS 취약점 | Critical |
|
|
42
|
+
| **에러 처리** | 적절한 에러 처리, 엣지 케이스 | High |
|
|
43
|
+
| **성능** | 불필요한 연산, 메모리 누수, N+1 쿼리 | Medium |
|
|
44
|
+
| **타입 안정성** | any 사용, 명시적 타입, null/undefined 처리 | High |
|
|
45
|
+
| **테스트** | 테스트 커버리지, 엣지 케이스 테스트 | Medium |
|
|
46
|
+
| **문서화** | 복잡한 로직 주석, API 문서 | Low |
|
|
48
47
|
|
|
49
48
|
</review_checklist>
|
|
50
49
|
|
|
@@ -52,12 +51,12 @@ Tasks to perform on invocation:
|
|
|
52
51
|
|
|
53
52
|
<forbidden>
|
|
54
53
|
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
54
|
+
| 분류 | 금지 |
|
|
55
|
+
|------|------|
|
|
56
|
+
| **스타일** | 코드 스타일 지적 (formatter 사용) |
|
|
57
|
+
| **주관** | 개인 취향 기반 의견 |
|
|
58
|
+
| **범위** | 변경되지 않은 코드 리뷰 |
|
|
59
|
+
| **톤** | 비판적/부정적 톤 |
|
|
61
60
|
|
|
62
61
|
</forbidden>
|
|
63
62
|
|
|
@@ -65,13 +64,13 @@ Tasks to perform on invocation:
|
|
|
65
64
|
|
|
66
65
|
<required>
|
|
67
66
|
|
|
68
|
-
|
|
|
69
|
-
|
|
70
|
-
| **Diff** |
|
|
71
|
-
| **Focus** |
|
|
72
|
-
| **Priority** |
|
|
73
|
-
| **Examples** |
|
|
74
|
-
| **Constructive** |
|
|
67
|
+
| 분류 | 필수 |
|
|
68
|
+
|------|------|
|
|
69
|
+
| **Diff** | git diff로 변경사항 확인 |
|
|
70
|
+
| **Focus** | 수정된 파일만 집중 검토 |
|
|
71
|
+
| **Priority** | 치명적 > 경고 > 제안 구분 |
|
|
72
|
+
| **Examples** | 구체적 코드 예시 제공 |
|
|
73
|
+
| **Constructive** | 건설적이고 명확한 피드백 |
|
|
75
74
|
|
|
76
75
|
</required>
|
|
77
76
|
|
|
@@ -79,13 +78,13 @@ Tasks to perform on invocation:
|
|
|
79
78
|
|
|
80
79
|
<severity_levels>
|
|
81
80
|
|
|
82
|
-
##
|
|
81
|
+
## 심각도 분류
|
|
83
82
|
|
|
84
|
-
|
|
|
85
|
-
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
83
|
+
| 레벨 | 기준 | 예시 | 조치 |
|
|
84
|
+
|------|------|------|------|
|
|
85
|
+
| **치명적** | 보안 취약점, 데이터 손실, 시스템 장애 | SQL injection, API 키 노출 | 머지 전 필수 수정 |
|
|
86
|
+
| **경고** | 버그 가능성, 성능 문제, 유지보수 어려움 | Null 처리 누락, N+1 쿼리 | 수정 강력 권장 |
|
|
87
|
+
| **제안** | 코드 개선, 가독성 향상 | 변수명 개선, 중복 제거 | 선택적 개선 |
|
|
89
88
|
|
|
90
89
|
</severity_levels>
|
|
91
90
|
|
|
@@ -94,38 +93,38 @@ Tasks to perform on invocation:
|
|
|
94
93
|
<workflow>
|
|
95
94
|
|
|
96
95
|
```bash
|
|
97
|
-
# 1.
|
|
96
|
+
# 1. 변경사항 확인
|
|
98
97
|
git diff
|
|
99
98
|
git diff --staged
|
|
100
99
|
|
|
101
|
-
#
|
|
100
|
+
# 결과:
|
|
102
101
|
# modified: src/api/users.ts
|
|
103
102
|
# modified: src/components/UserForm.tsx
|
|
104
103
|
# modified: src/lib/auth.ts
|
|
105
104
|
|
|
106
|
-
# 2.
|
|
105
|
+
# 2. 각 파일 검토
|
|
107
106
|
# src/api/users.ts:
|
|
108
|
-
# -
|
|
109
|
-
# -
|
|
110
|
-
# -
|
|
107
|
+
# - POST /api/users 엔드포인트 추가
|
|
108
|
+
# - 입력 검증 누락 (치명적)
|
|
109
|
+
# - 비밀번호 평문 저장 (치명적)
|
|
111
110
|
|
|
112
111
|
# src/components/UserForm.tsx:
|
|
113
|
-
# -
|
|
114
|
-
# -
|
|
112
|
+
# - 폼 제출 시 클라이언트 검증 없음 (경고)
|
|
113
|
+
# - useEffect 의존성 누락 (경고)
|
|
115
114
|
|
|
116
115
|
# src/lib/auth.ts:
|
|
117
|
-
# -
|
|
118
|
-
|
|
119
|
-
# 3.
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
# 4.
|
|
125
|
-
# -
|
|
126
|
-
# -
|
|
127
|
-
# -
|
|
128
|
-
# -
|
|
116
|
+
# - 변수명 개선 가능 (제안)
|
|
117
|
+
|
|
118
|
+
# 3. 우선순위별 정리
|
|
119
|
+
# 치명적: 2개
|
|
120
|
+
# 경고: 2개
|
|
121
|
+
# 제안: 1개
|
|
122
|
+
|
|
123
|
+
# 4. 상세 피드백 작성
|
|
124
|
+
# - 문제점 설명
|
|
125
|
+
# - 왜 문제인지
|
|
126
|
+
# - 어떻게 수정할지
|
|
127
|
+
# - 코드 예시
|
|
129
128
|
```
|
|
130
129
|
|
|
131
130
|
</workflow>
|
|
@@ -134,18 +133,18 @@ git diff --staged
|
|
|
134
133
|
|
|
135
134
|
<security_patterns>
|
|
136
135
|
|
|
137
|
-
##
|
|
136
|
+
## 보안 체크리스트
|
|
138
137
|
|
|
139
|
-
### 1.
|
|
138
|
+
### 1. 입력 검증
|
|
140
139
|
|
|
141
140
|
```typescript
|
|
142
|
-
// ❌
|
|
141
|
+
// ❌ 치명적: 입력 검증 없음
|
|
143
142
|
app.post('/api/users', async (req, res) => {
|
|
144
143
|
const { email, password } = req.body
|
|
145
144
|
await db.users.create({ email, password })
|
|
146
145
|
})
|
|
147
146
|
|
|
148
|
-
// ✅
|
|
147
|
+
// ✅ 올바름: Zod 검증
|
|
149
148
|
const schema = z.object({
|
|
150
149
|
email: z.email(),
|
|
151
150
|
password: z.string().min(8),
|
|
@@ -158,13 +157,13 @@ app.post('/api/users', async (req, res) => {
|
|
|
158
157
|
})
|
|
159
158
|
```
|
|
160
159
|
|
|
161
|
-
### 2.
|
|
160
|
+
### 2. 시크릿 노출
|
|
162
161
|
|
|
163
162
|
```typescript
|
|
164
|
-
// ❌
|
|
163
|
+
// ❌ 치명적: API 키 하드코딩
|
|
165
164
|
const apiKey = "sk_live_abc123xyz"
|
|
166
165
|
|
|
167
|
-
// ✅
|
|
166
|
+
// ✅ 올바름: 환경 변수
|
|
168
167
|
const apiKey = process.env.API_KEY
|
|
169
168
|
if (!apiKey) throw new Error('API_KEY not set')
|
|
170
169
|
```
|
|
@@ -172,10 +171,10 @@ if (!apiKey) throw new Error('API_KEY not set')
|
|
|
172
171
|
### 3. SQL Injection
|
|
173
172
|
|
|
174
173
|
```typescript
|
|
175
|
-
// ❌
|
|
174
|
+
// ❌ 치명적: SQL injection 취약
|
|
176
175
|
const query = `SELECT * FROM users WHERE id = ${userId}`
|
|
177
176
|
|
|
178
|
-
// ✅
|
|
177
|
+
// ✅ 올바름: Prepared statement
|
|
179
178
|
const query = `SELECT * FROM users WHERE id = ?`
|
|
180
179
|
await db.query(query, [userId])
|
|
181
180
|
```
|
|
@@ -183,10 +182,10 @@ await db.query(query, [userId])
|
|
|
183
182
|
### 4. XSS
|
|
184
183
|
|
|
185
184
|
```typescript
|
|
186
|
-
// ❌
|
|
185
|
+
// ❌ 치명적: XSS 취약
|
|
187
186
|
<div dangerouslySetInnerHTML={{ __html: userInput }} />
|
|
188
187
|
|
|
189
|
-
// ✅
|
|
188
|
+
// ✅ 올바름: Sanitize
|
|
190
189
|
import DOMPurify from 'dompurify'
|
|
191
190
|
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
|
|
192
191
|
```
|
|
@@ -197,28 +196,28 @@ import DOMPurify from 'dompurify'
|
|
|
197
196
|
|
|
198
197
|
<common_issues>
|
|
199
198
|
|
|
200
|
-
##
|
|
199
|
+
## 일반적 문제 패턴
|
|
201
200
|
|
|
202
|
-
### 1. Null/Undefined
|
|
201
|
+
### 1. Null/Undefined 처리
|
|
203
202
|
|
|
204
203
|
```typescript
|
|
205
|
-
// ❌
|
|
204
|
+
// ❌ 경고: Null 체크 없음
|
|
206
205
|
function getUser(id: string) {
|
|
207
206
|
const user = users.find(u => u.id === id)
|
|
208
|
-
return user.name //
|
|
207
|
+
return user.name // TypeError 가능
|
|
209
208
|
}
|
|
210
209
|
|
|
211
|
-
// ✅
|
|
210
|
+
// ✅ 올바름: Optional chaining + Null 체크
|
|
212
211
|
function getUser(id: string): string | null {
|
|
213
212
|
const user = users.find(u => u.id === id)
|
|
214
213
|
return user?.name ?? null
|
|
215
214
|
}
|
|
216
215
|
```
|
|
217
216
|
|
|
218
|
-
### 2. N+1
|
|
217
|
+
### 2. N+1 쿼리
|
|
219
218
|
|
|
220
219
|
```typescript
|
|
221
|
-
// ❌
|
|
220
|
+
// ❌ 경고: N+1 쿼리
|
|
222
221
|
async function getPostsWithAuthors() {
|
|
223
222
|
const posts = await db.posts.findMany()
|
|
224
223
|
for (const post of posts) {
|
|
@@ -227,7 +226,7 @@ async function getPostsWithAuthors() {
|
|
|
227
226
|
return posts
|
|
228
227
|
}
|
|
229
228
|
|
|
230
|
-
// ✅
|
|
229
|
+
// ✅ 올바름: Include
|
|
231
230
|
async function getPostsWithAuthors() {
|
|
232
231
|
return await db.posts.findMany({
|
|
233
232
|
include: { author: true }
|
|
@@ -235,29 +234,29 @@ async function getPostsWithAuthors() {
|
|
|
235
234
|
}
|
|
236
235
|
```
|
|
237
236
|
|
|
238
|
-
### 3. useEffect
|
|
237
|
+
### 3. useEffect 의존성
|
|
239
238
|
|
|
240
239
|
```typescript
|
|
241
|
-
// ❌
|
|
240
|
+
// ❌ 경고: 의존성 누락
|
|
242
241
|
useEffect(() => {
|
|
243
242
|
fetchData(userId)
|
|
244
|
-
}, []) // userId
|
|
243
|
+
}, []) // userId 누락
|
|
245
244
|
|
|
246
|
-
// ✅
|
|
245
|
+
// ✅ 올바름: 모든 의존성 포함
|
|
247
246
|
useEffect(() => {
|
|
248
247
|
fetchData(userId)
|
|
249
248
|
}, [userId])
|
|
250
249
|
```
|
|
251
250
|
|
|
252
|
-
### 4. any
|
|
251
|
+
### 4. any 타입
|
|
253
252
|
|
|
254
253
|
```typescript
|
|
255
|
-
// ❌
|
|
254
|
+
// ❌ 경고: any 사용
|
|
256
255
|
function processData(data: any): any {
|
|
257
256
|
return data.map((item: any) => item.value)
|
|
258
257
|
}
|
|
259
258
|
|
|
260
|
-
// ✅
|
|
259
|
+
// ✅ 올바름: 명시적 타입
|
|
261
260
|
interface DataItem { value: number }
|
|
262
261
|
function processData(data: DataItem[]): number[] {
|
|
263
262
|
return data.map(item => item.value)
|
|
@@ -270,20 +269,20 @@ function processData(data: DataItem[]): number[] {
|
|
|
270
269
|
|
|
271
270
|
<output>
|
|
272
271
|
|
|
273
|
-
##
|
|
272
|
+
## 코드 리뷰 결과
|
|
274
273
|
|
|
275
|
-
|
|
274
|
+
**변경된 파일:**
|
|
276
275
|
- src/api/users.ts
|
|
277
276
|
- src/components/UserForm.tsx
|
|
278
277
|
- src/lib/auth.ts
|
|
279
278
|
|
|
280
279
|
---
|
|
281
280
|
|
|
282
|
-
###
|
|
281
|
+
### 치명적 (머지 전 필수 수정)
|
|
283
282
|
|
|
284
|
-
#### 1. src/api/users.ts:15 -
|
|
283
|
+
#### 1. src/api/users.ts:15 - 입력 검증 누락
|
|
285
284
|
|
|
286
|
-
|
|
285
|
+
**문제:**
|
|
287
286
|
```typescript
|
|
288
287
|
app.post('/api/users', async (req, res) => {
|
|
289
288
|
const { email, password } = req.body
|
|
@@ -291,12 +290,12 @@ app.post('/api/users', async (req, res) => {
|
|
|
291
290
|
})
|
|
292
291
|
```
|
|
293
292
|
|
|
294
|
-
|
|
295
|
-
-
|
|
296
|
-
- SQL injection
|
|
297
|
-
-
|
|
293
|
+
**왜 문제인가:**
|
|
294
|
+
- 악의적 입력 가능 (빈 문자열, 특수문자 등)
|
|
295
|
+
- SQL injection 또는 데이터 무결성 문제
|
|
296
|
+
- 보안 취약점
|
|
298
297
|
|
|
299
|
-
|
|
298
|
+
**수정 방법:**
|
|
300
299
|
```typescript
|
|
301
300
|
import { z } from 'zod'
|
|
302
301
|
|
|
@@ -314,36 +313,36 @@ app.post('/api/users', async (req, res) => {
|
|
|
314
313
|
|
|
315
314
|
---
|
|
316
315
|
|
|
317
|
-
#### 2. src/api/users.ts:17 -
|
|
316
|
+
#### 2. src/api/users.ts:17 - 비밀번호 평문 저장
|
|
318
317
|
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
**문제:**
|
|
319
|
+
비밀번호를 해싱 없이 평문으로 저장.
|
|
321
320
|
|
|
322
|
-
|
|
323
|
-
-
|
|
324
|
-
-
|
|
321
|
+
**왜 문제인가:**
|
|
322
|
+
- 데이터 유출 시 모든 사용자 비밀번호 노출
|
|
323
|
+
- 심각한 보안 취약점
|
|
325
324
|
|
|
326
|
-
|
|
327
|
-
|
|
325
|
+
**수정 방법:**
|
|
326
|
+
위 코드 예시 참조 (`bcrypt.hash` 사용)
|
|
328
327
|
|
|
329
328
|
---
|
|
330
329
|
|
|
331
|
-
###
|
|
330
|
+
### 경고 (수정 강력 권장)
|
|
332
331
|
|
|
333
|
-
#### 3. src/components/UserForm.tsx:42 -
|
|
332
|
+
#### 3. src/components/UserForm.tsx:42 - useEffect 의존성 누락
|
|
334
333
|
|
|
335
|
-
|
|
334
|
+
**문제:**
|
|
336
335
|
```typescript
|
|
337
336
|
useEffect(() => {
|
|
338
337
|
fetchUser(userId)
|
|
339
338
|
}, [])
|
|
340
339
|
```
|
|
341
340
|
|
|
342
|
-
|
|
343
|
-
-
|
|
344
|
-
-
|
|
341
|
+
**왜 문제인가:**
|
|
342
|
+
- userId 변경 시 재실행 안 됨
|
|
343
|
+
- Stale data 표시 가능
|
|
345
344
|
|
|
346
|
-
|
|
345
|
+
**수정 방법:**
|
|
347
346
|
```typescript
|
|
348
347
|
useEffect(() => {
|
|
349
348
|
fetchUser(userId)
|
|
@@ -352,47 +351,47 @@ useEffect(() => {
|
|
|
352
351
|
|
|
353
352
|
---
|
|
354
353
|
|
|
355
|
-
#### 4. src/components/UserForm.tsx:28 -
|
|
354
|
+
#### 4. src/components/UserForm.tsx:28 - Null 체크 누락
|
|
356
355
|
|
|
357
|
-
|
|
356
|
+
**문제:**
|
|
358
357
|
```typescript
|
|
359
358
|
const userName = user.name.toUpperCase()
|
|
360
359
|
```
|
|
361
360
|
|
|
362
|
-
|
|
363
|
-
-
|
|
361
|
+
**왜 문제인가:**
|
|
362
|
+
- user가 null/undefined일 때 TypeError
|
|
364
363
|
|
|
365
|
-
|
|
364
|
+
**수정 방법:**
|
|
366
365
|
```typescript
|
|
367
366
|
const userName = user?.name?.toUpperCase() ?? 'Unknown'
|
|
368
367
|
```
|
|
369
368
|
|
|
370
369
|
---
|
|
371
370
|
|
|
372
|
-
###
|
|
371
|
+
### 제안 (선택적 개선)
|
|
373
372
|
|
|
374
|
-
#### 5. src/lib/auth.ts:10 -
|
|
373
|
+
#### 5. src/lib/auth.ts:10 - 변수명 개선
|
|
375
374
|
|
|
376
|
-
|
|
375
|
+
**현재:**
|
|
377
376
|
```typescript
|
|
378
377
|
const u = await getUser(id)
|
|
379
378
|
```
|
|
380
379
|
|
|
381
|
-
|
|
380
|
+
**제안:**
|
|
382
381
|
```typescript
|
|
383
382
|
const user = await getUser(id)
|
|
384
383
|
```
|
|
385
384
|
|
|
386
|
-
|
|
387
|
-
|
|
385
|
+
**이유:**
|
|
386
|
+
가독성 향상
|
|
388
387
|
|
|
389
388
|
---
|
|
390
389
|
|
|
391
|
-
|
|
392
|
-
-
|
|
393
|
-
-
|
|
394
|
-
-
|
|
390
|
+
**요약:**
|
|
391
|
+
- 치명적: 2개 (필수 수정)
|
|
392
|
+
- 경고: 2개 (권장)
|
|
393
|
+
- 제안: 1개 (선택)
|
|
395
394
|
|
|
396
|
-
|
|
395
|
+
치명적 이슈를 수정한 후 머지하세요.
|
|
397
396
|
|
|
398
397
|
</output>
|