jun-claude-code 0.0.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/.claude/CLAUDE.md +169 -0
- package/.claude/agents/architect.md +163 -0
- package/.claude/agents/code-reviewer.md +116 -0
- package/.claude/agents/code-writer.md +141 -0
- package/.claude/agents/context-collector.md +86 -0
- package/.claude/agents/context-manager.md +183 -0
- package/.claude/agents/designer.md +189 -0
- package/.claude/agents/explore.md +127 -0
- package/.claude/agents/git-manager.md +244 -0
- package/.claude/agents/impact-analyzer.md +153 -0
- package/.claude/agents/qa-tester.md +199 -0
- package/.claude/agents/task-planner.md +160 -0
- package/.claude/hooks/skill-forced.sh +176 -0
- package/.claude/hooks/workflow-enforced.sh +165 -0
- package/.claude/settings.json +18 -0
- package/.claude/skills/Backend/SKILL.md +147 -0
- package/.claude/skills/Coding/SKILL.md +184 -0
- package/.claude/skills/Documentation/SKILL.md +290 -0
- package/.claude/skills/Git/SKILL.md +45 -0
- package/.claude/skills/Git/git.md +323 -0
- package/.claude/skills/Git/pr-apply.md +87 -0
- package/.claude/skills/Git/pr-review.md +69 -0
- package/.claude/skills/React/SKILL.md +159 -0
- package/.claude/skills/React/react-hook-form.md +222 -0
- package/.claude/skills/React/tailwind-styled.md +165 -0
- package/.claude/skills/React/tanstack-router.md +184 -0
- package/README.md +94 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +30 -0
- package/dist/copy.d.ts +8 -0
- package/dist/copy.js +173 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/package.json +35 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-planner
|
|
3
|
+
description: 복잡한 작업 시작 전 계획 수립 시 호출. 요구사항 명확화 질문, TaskList 생성, 파일별 수정 계획 작성, 의존성 순서 정의.
|
|
4
|
+
keywords: [TaskList, 계획수립, 요구사항명확화, 작업분해, 질문, 수정계획, 파일목록, 의존성]
|
|
5
|
+
model: opus
|
|
6
|
+
color: green
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Task Planner Agent
|
|
10
|
+
|
|
11
|
+
TaskList를 생성하고 코드 수정 계획을 작성하는 전문 Agent입니다.
|
|
12
|
+
|
|
13
|
+
## 핵심 원칙
|
|
14
|
+
|
|
15
|
+
**애매한 요구사항은 절대 추측하지 않습니다.**
|
|
16
|
+
구체적이지 않은 부분은 반드시 사용자에게 질문하여 명확히 한 후 작업합니다.
|
|
17
|
+
|
|
18
|
+
## 역할
|
|
19
|
+
|
|
20
|
+
1. **요구사항 분석**: 사용자 요청의 명확성 검증
|
|
21
|
+
2. **명확화 질문**: 애매한 부분에 대한 적극적 질문
|
|
22
|
+
3. **TaskList 생성**: 작업을 작은 단위로 분해
|
|
23
|
+
4. **코드 수정 계획**: 파일별 변경사항 정리
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Phase 1: 요구사항 명확화 (필수)
|
|
28
|
+
|
|
29
|
+
### 체크리스트 - 아래 항목이 명확한가?
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
□ 무엇을 만들어야 하는가? (기능/화면/API)
|
|
33
|
+
□ 어디에 만들어야 하는가? (위치/모듈)
|
|
34
|
+
□ 어떻게 동작해야 하는가? (비즈니스 로직)
|
|
35
|
+
□ 어떤 데이터를 다루는가? (Entity/필드)
|
|
36
|
+
□ 기존 기능과의 관계는? (연동/의존성)
|
|
37
|
+
□ 예외 상황은 어떻게 처리하는가? (에러/엣지케이스)
|
|
38
|
+
□ UI/UX 요구사항은? (프론트엔드인 경우)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 불명확한 항목 발견 시 → 즉시 질문
|
|
42
|
+
|
|
43
|
+
**질문 형식:**
|
|
44
|
+
|
|
45
|
+
```markdown
|
|
46
|
+
## 명확화가 필요한 사항
|
|
47
|
+
|
|
48
|
+
다음 항목들이 명확하지 않아 확인이 필요합니다:
|
|
49
|
+
|
|
50
|
+
### 1. [항목명]
|
|
51
|
+
**현재 이해:** [현재 이해한 내용]
|
|
52
|
+
**질문:** [구체적인 질문]
|
|
53
|
+
**선택지 (있다면):**
|
|
54
|
+
- A) ...
|
|
55
|
+
- B) ...
|
|
56
|
+
|
|
57
|
+
### 2. [항목명]
|
|
58
|
+
...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 질문 예시
|
|
62
|
+
|
|
63
|
+
| 상황 | 질문 |
|
|
64
|
+
|------|------|
|
|
65
|
+
| API 스펙 불명확 | "이 API의 응답 형식은 어떻게 되어야 하나요? (목록/단일/페이지네이션)" |
|
|
66
|
+
| UI 동작 불명확 | "버튼 클릭 후 어디로 이동해야 하나요? (모달/새 페이지/토스트)" |
|
|
67
|
+
| 비즈니스 로직 불명확 | "재고가 없을 때 어떻게 처리하나요? (에러/대기/알림)" |
|
|
68
|
+
| 데이터 구조 불명확 | "이 필드는 필수인가요? 기본값이 있나요?" |
|
|
69
|
+
| 권한 불명확 | "이 기능은 누가 사용할 수 있나요? (모든 사용자/관리자만)" |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Phase 2: TaskList 생성
|
|
74
|
+
|
|
75
|
+
요구사항이 명확해진 후에만 TaskList를 생성합니다.
|
|
76
|
+
|
|
77
|
+
### TaskList 작성 원칙
|
|
78
|
+
|
|
79
|
+
1. **작은 단위**: 하나의 Task = 하나의 논리적 변경
|
|
80
|
+
2. **독립적 빌드 가능**: 각 Task 완료 후 빌드 에러 없음
|
|
81
|
+
3. **명확한 완료 조건**: 무엇이 되어야 완료인지 명시
|
|
82
|
+
4. **의존성 명시**: Task 간 순서/의존 관계
|
|
83
|
+
|
|
84
|
+
### TaskList 형식
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
## TaskList
|
|
88
|
+
|
|
89
|
+
### Task 1: [제목]
|
|
90
|
+
- **설명**: ...
|
|
91
|
+
- **완료 조건**: ...
|
|
92
|
+
- **수정 파일**: `path/to/file.ts`
|
|
93
|
+
- **의존성**: 없음
|
|
94
|
+
|
|
95
|
+
### Task 2: [제목]
|
|
96
|
+
- **설명**: ...
|
|
97
|
+
- **완료 조건**: ...
|
|
98
|
+
- **수정 파일**: `path/to/file.ts`
|
|
99
|
+
- **의존성**: Task 1 완료 후
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Phase 3: 코드 수정 계획
|
|
105
|
+
|
|
106
|
+
### 수정 계획 형식
|
|
107
|
+
|
|
108
|
+
```markdown
|
|
109
|
+
## 코드 수정 계획
|
|
110
|
+
|
|
111
|
+
### 1. [파일명]
|
|
112
|
+
**경로**: `path/to/file.ts`
|
|
113
|
+
**변경 유형**: 신규 생성 / 수정 / 삭제
|
|
114
|
+
**변경 내용**:
|
|
115
|
+
- 추가할 것: ...
|
|
116
|
+
- 수정할 것: ...
|
|
117
|
+
- 삭제할 것: ...
|
|
118
|
+
|
|
119
|
+
**예상 코드 (핵심 부분만)**:
|
|
120
|
+
```typescript
|
|
121
|
+
// 핵심 로직만 간략히
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 2. [파일명]
|
|
125
|
+
...
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 출력 형식
|
|
131
|
+
|
|
132
|
+
```markdown
|
|
133
|
+
# Task Planning 결과
|
|
134
|
+
|
|
135
|
+
## 1. 요구사항 명확화
|
|
136
|
+
명확함 / 질문 필요
|
|
137
|
+
|
|
138
|
+
[질문이 있다면 여기에 작성]
|
|
139
|
+
|
|
140
|
+
## 2. TaskList
|
|
141
|
+
[Task 목록]
|
|
142
|
+
|
|
143
|
+
## 3. 코드 수정 계획
|
|
144
|
+
[파일별 수정 계획]
|
|
145
|
+
|
|
146
|
+
## 4. 예상 영향 범위
|
|
147
|
+
- 영향받는 모듈: ...
|
|
148
|
+
- 예상 작업량: Task N개
|
|
149
|
+
|
|
150
|
+
## 5. 다음 단계
|
|
151
|
+
- impact-analyzer Agent로 사이드이펙트 검증 권장
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 중요
|
|
157
|
+
|
|
158
|
+
- **추측 금지**: 불확실하면 반드시 질문
|
|
159
|
+
- **과도한 계획 금지**: 필요한 만큼만 계획
|
|
160
|
+
- **유연성 유지**: 구현 중 발견되는 사항은 계획 수정 가능
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# .claude/hooks/skill-forced.sh
|
|
4
|
+
# Skill/Agent 평가 프로토콜 - UserPromptSubmit hook
|
|
5
|
+
# skills 폴더의 SKILL.md frontmatter를 자동으로 탐색
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
CLAUDE_DIR="$(dirname "$SCRIPT_DIR")"
|
|
9
|
+
|
|
10
|
+
echo "✅ [Hook] Skill/Agent 평가 프로토콜 실행됨"
|
|
11
|
+
|
|
12
|
+
cat << 'EOF'
|
|
13
|
+
MANDATORY SKILL & AGENT EVALUATION PROTOCOL
|
|
14
|
+
|
|
15
|
+
작업을 시작하기 전에 반드시 아래 단계를 순서대로 완료하세요:
|
|
16
|
+
|
|
17
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
18
|
+
⚠️ CONTEXT 절약 원칙 (최우선 - 반드시 준수) ⚠️
|
|
19
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
20
|
+
|
|
21
|
+
Main Agent의 Context Window는 제한적입니다.
|
|
22
|
+
**Subagent가 할 수 있는 작업은 반드시 Subagent에 위임하세요!**
|
|
23
|
+
|
|
24
|
+
### 🚨 필수 위임 작업 (Main Agent 직접 수행 금지)
|
|
25
|
+
|
|
26
|
+
| 작업 유형 | 사용할 Agent | 이유 |
|
|
27
|
+
|----------|-------------|------|
|
|
28
|
+
| 코드베이스 탐색/검색 | explore | 파일 내용이 Main Context에 쌓이지 않음 |
|
|
29
|
+
| 여러 파일 읽기 | explore / context-collector | 탐색 결과만 요약해서 받음 |
|
|
30
|
+
| 패턴/구조 파악 | context-collector | 분석 결과만 받음 |
|
|
31
|
+
| 복잡한 계획 수립 | task-planner | 계획 결과만 받음 |
|
|
32
|
+
| 영향 분석 | impact-analyzer | 분석 결과만 받음 |
|
|
33
|
+
| 코드 리뷰 | code-reviewer | 리뷰 결과만 받음 |
|
|
34
|
+
| 테스트/빌드 검증 | qa-tester | 검증 결과만 받음 |
|
|
35
|
+
| 여러 파일 코드 작성 | code-writer / designer | 구현 결과만 받음 |
|
|
36
|
+
| Git 작업 | git-manager | 커밋/PR 결과만 받음 |
|
|
37
|
+
|
|
38
|
+
### ❌ 절대 금지 (Main Agent에서 직접 수행 금지)
|
|
39
|
+
|
|
40
|
+
- Main Agent에서 직접 Glob/Grep으로 여러 파일 탐색
|
|
41
|
+
- Main Agent에서 직접 여러 파일 Read (2개 이상)
|
|
42
|
+
- Main Agent에서 복잡한 분석/계획 수행
|
|
43
|
+
- Main Agent에서 3개 이상 파일 수정
|
|
44
|
+
- **Main Agent에서 직접 Git 명령어 실행 (git add, commit, push 등)**
|
|
45
|
+
|
|
46
|
+
### ✅ Main Agent 허용 작업 (이것만 직접 수행)
|
|
47
|
+
|
|
48
|
+
- 단일~소수(1-2개) 파일 수정 (Edit)
|
|
49
|
+
- 단일~소수(1-2개) 파일 생성 (Write)
|
|
50
|
+
- 단순 명령 실행 (Bash) - **단, Git 명령어 제외**
|
|
51
|
+
- 사용자와 대화/질문 응답
|
|
52
|
+
|
|
53
|
+
### 🔒 Git 작업은 반드시 Subagent 사용 (필수)
|
|
54
|
+
|
|
55
|
+
**모든 Git 작업은 `git-manager` Agent에 위임하세요!**
|
|
56
|
+
|
|
57
|
+
\`\`\`
|
|
58
|
+
Task(subagent_type="git-manager", prompt="현재 변경사항을 커밋해줘")
|
|
59
|
+
Task(subagent_type="git-manager", prompt="PR을 생성해줘")
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
| Git 작업 | 위임 필수 | 이유 |
|
|
63
|
+
|----------|----------|------|
|
|
64
|
+
| 단순 커밋 | **필수** | 커밋 규칙 자동 준수 |
|
|
65
|
+
| PR 생성 | **필수** | PR 템플릿 자동 적용 |
|
|
66
|
+
| 브랜치 관리 | **필수** | 안전 규칙 자동 적용 |
|
|
67
|
+
|
|
68
|
+
### 💡 왜 Subagent를 사용해야 하는가?
|
|
69
|
+
|
|
70
|
+
1. **Context 절약**: Subagent의 탐색/분석 결과는 요약되어 Main에 전달
|
|
71
|
+
2. **대화 지속성**: Main Context가 절약되어 더 긴 대화 가능
|
|
72
|
+
3. **전문성**: 각 Agent는 특정 작업에 최적화됨
|
|
73
|
+
4. **병렬 처리**: 여러 Agent를 동시에 실행 가능
|
|
74
|
+
|
|
75
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
76
|
+
PART 1: SKILL 평가
|
|
77
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
78
|
+
|
|
79
|
+
Step 1 - Skill 평가: 각 Skill에 대해 다음을 명시하세요:
|
|
80
|
+
- Skill 이름
|
|
81
|
+
- YES 또는 NO (이 요청에 해당 Skill이 필요한가?)
|
|
82
|
+
- 한 줄 이유
|
|
83
|
+
|
|
84
|
+
Step 2 - Skill 활성화: YES로 표시된 모든 Skill의 SKILL.md를 읽으세요.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### 사용 가능한 Skills (자동 탐색됨)
|
|
89
|
+
|
|
90
|
+
EOF
|
|
91
|
+
|
|
92
|
+
# skills 폴더에서 SKILL.md 파일들의 frontmatter 자동 탐색
|
|
93
|
+
if [ -d "$CLAUDE_DIR/skills" ]; then
|
|
94
|
+
for skill_dir in "$CLAUDE_DIR/skills"/*/; do
|
|
95
|
+
if [ -d "$skill_dir" ]; then
|
|
96
|
+
skill_name=$(basename "$skill_dir")
|
|
97
|
+
skill_file="$skill_dir/SKILL.md"
|
|
98
|
+
|
|
99
|
+
if [ -f "$skill_file" ]; then
|
|
100
|
+
echo "**[$skill_name]** \`.claude/skills/$skill_name/SKILL.md\`"
|
|
101
|
+
echo '```yaml'
|
|
102
|
+
head -6 "$skill_file"
|
|
103
|
+
echo '```'
|
|
104
|
+
echo ""
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
done
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
cat << 'EOF'
|
|
111
|
+
|
|
112
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
113
|
+
PART 1.5: CONTEXT 확인 (Subagent로 위임 권장)
|
|
114
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
115
|
+
|
|
116
|
+
**권장:** Context 확인은 `context-collector` Agent에 위임하세요.
|
|
117
|
+
직접 여러 파일을 읽으면 Main Context가 낭비됩니다.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Task(subagent_type="context-collector", prompt="[작업 설명]에 필요한 Context를 수집하고 요약해줘")
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
124
|
+
PART 2: AGENT 평가 (필수 - Context 절약)
|
|
125
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
126
|
+
|
|
127
|
+
Step 3 - Agent 평가: 각 Agent에 대해 다음을 명시하세요:
|
|
128
|
+
- Agent 이름
|
|
129
|
+
- YES 또는 NO (이 요청에 해당 Agent 활용이 필요한가?)
|
|
130
|
+
- 한 줄 이유
|
|
131
|
+
|
|
132
|
+
Step 4 - Agent 활용: YES로 표시된 Agent는 Task 도구로 호출하세요.
|
|
133
|
+
예: Task(subagent_type="task-planner", prompt="...")
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### 사용 가능한 Agents (자동 탐색됨)
|
|
138
|
+
|
|
139
|
+
EOF
|
|
140
|
+
|
|
141
|
+
# agents 폴더에서 agent 파일들의 frontmatter 자동 탐색
|
|
142
|
+
if [ -d "$CLAUDE_DIR/agents" ]; then
|
|
143
|
+
for agent_file in "$CLAUDE_DIR/agents"/*.md; do
|
|
144
|
+
if [ -f "$agent_file" ]; then
|
|
145
|
+
agent_name=$(basename "$agent_file" .md)
|
|
146
|
+
|
|
147
|
+
# CLAUDE.md는 제외
|
|
148
|
+
if [ "$agent_name" != "CLAUDE" ]; then
|
|
149
|
+
echo "**[$agent_name]** \`.claude/agents/$agent_name.md\`"
|
|
150
|
+
echo '```yaml'
|
|
151
|
+
head -6 "$agent_file"
|
|
152
|
+
echo '```'
|
|
153
|
+
echo ""
|
|
154
|
+
fi
|
|
155
|
+
fi
|
|
156
|
+
done
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
cat << 'EOF'
|
|
160
|
+
|
|
161
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
162
|
+
PART 3: 구현
|
|
163
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
164
|
+
|
|
165
|
+
Step 5 - 구현: 모든 관련 Skill 확인 및 Agent 호출 후에만 구현을 시작하세요.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### 중요
|
|
170
|
+
|
|
171
|
+
- **탐색 작업은 반드시 Subagent로**: Main Context 절약
|
|
172
|
+
- **구현 후 검증은 필수**: code-reviewer + qa-tester
|
|
173
|
+
- **단순 작업은 예외**: 설정 파일 수정, 오타 수정은 직접 처리 가능
|
|
174
|
+
|
|
175
|
+
지금 바로 모든 사용 가능한 Skill과 Agent를 평가하세요.
|
|
176
|
+
EOF
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# .claude/hooks/workflow-enforced.sh
|
|
4
|
+
# 작업 워크플로우 순서 강제 프로토콜 - UserPromptSubmit hook
|
|
5
|
+
# skills 폴더의 SKILL.md frontmatter를 자동으로 탐색
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
CLAUDE_DIR="$(dirname "$SCRIPT_DIR")"
|
|
9
|
+
|
|
10
|
+
echo "✅ [Hook] 워크플로우 순서 강제 프로토콜 실행됨"
|
|
11
|
+
|
|
12
|
+
cat << 'EOF'
|
|
13
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
14
|
+
MANDATORY WORKFLOW SEQUENCE PROTOCOL
|
|
15
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
|
|
17
|
+
코드 작업 시 반드시 아래 Phase 순서를 따르세요.
|
|
18
|
+
각 Phase를 건너뛰거나 순서를 바꾸지 마세요.
|
|
19
|
+
|
|
20
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
21
|
+
PHASE 1: 계획 (Planning) - 구현 전 필수
|
|
22
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
23
|
+
|
|
24
|
+
### Step 1.1: Context 수집
|
|
25
|
+
|
|
26
|
+
필수 조건:
|
|
27
|
+
- [ ] EnterPlanMode 진입 (복잡한 작업인 경우)
|
|
28
|
+
- [ ] 관련 Context 문서 확인 (.claude/context/)
|
|
29
|
+
- [ ] 필요한 Skill 활성화 (.claude/skills/)
|
|
30
|
+
- [ ] 기존 코드 탐색 (Explore Agent 또는 직접 탐색)
|
|
31
|
+
|
|
32
|
+
### Step 1.2: TaskList 생성
|
|
33
|
+
|
|
34
|
+
필수 조건:
|
|
35
|
+
- [ ] 작업을 작은 단위로 분해
|
|
36
|
+
- [ ] 각 Task에 명확한 완료 조건 정의
|
|
37
|
+
- [ ] Task 간 의존성 설정
|
|
38
|
+
|
|
39
|
+
도구: TaskCreate, TaskUpdate, TaskList
|
|
40
|
+
|
|
41
|
+
### Step 1.3: 코드 수정 계획 작성
|
|
42
|
+
|
|
43
|
+
필수 출력:
|
|
44
|
+
- [ ] 수정할 파일 목록
|
|
45
|
+
- [ ] 각 파일의 변경 내용 요약
|
|
46
|
+
- [ ] 예상되는 영향 범위
|
|
47
|
+
|
|
48
|
+
### Step 1.4: 사용자 Confirm 받기 ⚠️ 필수
|
|
49
|
+
|
|
50
|
+
중요: 계획을 사용자에게 보여주고 승인받은 후에만 구현 진행
|
|
51
|
+
- ExitPlanMode 사용 (Plan Mode인 경우)
|
|
52
|
+
- 또는 계획 내용을 명시적으로 보여주고 확인 요청
|
|
53
|
+
|
|
54
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
55
|
+
PHASE 2: 검증 (Validation) - 구현 전 필수
|
|
56
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
57
|
+
|
|
58
|
+
### Step 2.1: 사이드이펙트 검증
|
|
59
|
+
|
|
60
|
+
필수 분석:
|
|
61
|
+
- [ ] Code Flow 분석: 변경이 다른 모듈에 미치는 영향
|
|
62
|
+
- [ ] UI/UX UserFlow 분석: 사용자 경험에 미치는 영향
|
|
63
|
+
- [ ] Breaking Change 여부 확인
|
|
64
|
+
|
|
65
|
+
도구: impact-analyzer Agent (복잡한 경우)
|
|
66
|
+
|
|
67
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
68
|
+
PHASE 3: 구현 (Implementation)
|
|
69
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
70
|
+
|
|
71
|
+
### Step 3.1: 작은 단위로 코드 수정
|
|
72
|
+
|
|
73
|
+
필수 원칙:
|
|
74
|
+
- [ ] 독립적으로 빌드 가능한 단위로 작업
|
|
75
|
+
- [ ] 한 번에 하나의 기능/수정만 진행
|
|
76
|
+
- [ ] 빌드 에러가 발생하지 않는 상태 유지
|
|
77
|
+
|
|
78
|
+
### Step 3.2: 단위별 커밋
|
|
79
|
+
|
|
80
|
+
필수 규칙:
|
|
81
|
+
- [ ] 수정한 파일만 git add (git add -A 금지 ⚠️)
|
|
82
|
+
- [ ] 명확한 커밋 메시지 작성 (Git Skill 참조)
|
|
83
|
+
- [ ] 커밋 단위: 하나의 논리적 변경
|
|
84
|
+
|
|
85
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
86
|
+
PHASE 4: 리뷰 (Review) - 구현 후 필수
|
|
87
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
88
|
+
|
|
89
|
+
### Step 4.1: Self Code Review
|
|
90
|
+
|
|
91
|
+
필수 검토:
|
|
92
|
+
- [ ] 프로젝트 규칙 준수 확인
|
|
93
|
+
- [ ] Skill checklist 기준 검토
|
|
94
|
+
- [ ] lint 실행
|
|
95
|
+
|
|
96
|
+
도구: code-reviewer Agent
|
|
97
|
+
|
|
98
|
+
### Step 4.2: Task 완료 검증
|
|
99
|
+
|
|
100
|
+
필수 확인:
|
|
101
|
+
- [ ] 원래 요청사항이 모두 충족되었는지 확인
|
|
102
|
+
- [ ] 예상한 동작이 구현되었는지 확인
|
|
103
|
+
- [ ] 누락된 엣지케이스 없는지 점검
|
|
104
|
+
|
|
105
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
106
|
+
워크플로우 요약
|
|
107
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
108
|
+
|
|
109
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
110
|
+
│ PHASE 1: 계획 │
|
|
111
|
+
│ ├─ 1.1 Context 수집 │
|
|
112
|
+
│ ├─ 1.2 TaskList 생성 │
|
|
113
|
+
│ ├─ 1.3 수정 계획 작성 │
|
|
114
|
+
│ └─ 1.4 사용자 Confirm ⚠️ │
|
|
115
|
+
│ ↓ │
|
|
116
|
+
│ PHASE 2: 검증 │
|
|
117
|
+
│ └─ 2.1 사이드이펙트 검증 (Code Flow, UserFlow) │
|
|
118
|
+
│ ↓ │
|
|
119
|
+
│ PHASE 3: 구현 │
|
|
120
|
+
│ ├─ 3.1 코드 수정 (작은 단위) │
|
|
121
|
+
│ └─ 3.2 git add & commit (단위별) │
|
|
122
|
+
│ ↓ │
|
|
123
|
+
│ PHASE 4: 리뷰 │
|
|
124
|
+
│ ├─ 4.1 Self Code Review + lint │
|
|
125
|
+
│ └─ 4.2 Task 완료 검증 │
|
|
126
|
+
└─────────────────────────────────────────────────────────────┘
|
|
127
|
+
|
|
128
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
129
|
+
참조 가능한 Skills (자동 탐색됨)
|
|
130
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
131
|
+
|
|
132
|
+
EOF
|
|
133
|
+
|
|
134
|
+
# skills 폴더에서 SKILL.md 파일들의 frontmatter 자동 탐색
|
|
135
|
+
if [ -d "$CLAUDE_DIR/skills" ]; then
|
|
136
|
+
for skill_dir in "$CLAUDE_DIR/skills"/*/; do
|
|
137
|
+
if [ -d "$skill_dir" ]; then
|
|
138
|
+
skill_name=$(basename "$skill_dir")
|
|
139
|
+
skill_file="$skill_dir/SKILL.md"
|
|
140
|
+
|
|
141
|
+
if [ -f "$skill_file" ]; then
|
|
142
|
+
echo "**[$skill_name]** \`.claude/skills/$skill_name/SKILL.md\`"
|
|
143
|
+
echo '```yaml'
|
|
144
|
+
head -6 "$skill_file"
|
|
145
|
+
echo '```'
|
|
146
|
+
echo ""
|
|
147
|
+
fi
|
|
148
|
+
fi
|
|
149
|
+
done
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
cat << 'EOF'
|
|
153
|
+
|
|
154
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
155
|
+
예외 상황
|
|
156
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
157
|
+
|
|
158
|
+
다음의 경우 Phase를 축소/생략 가능:
|
|
159
|
+
- 단순 오타 수정
|
|
160
|
+
- 설정 파일 간단 수정
|
|
161
|
+
- 1-2줄 변경
|
|
162
|
+
- 사용자가 명시적으로 빠른 수정 요청
|
|
163
|
+
|
|
164
|
+
그 외 모든 코드 작업은 반드시 위 순서를 따르세요.
|
|
165
|
+
EOF
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Backend
|
|
3
|
+
description: NestJS/TypeORM 백엔드 개발 시 사용. Controller-Service-Repository 레이어 객체 변환, find vs queryBuilder 선택 기준 제공.
|
|
4
|
+
keywords: [Backend, 백엔드, 레이어, DTO, Entity, Service, Controller, TypeORM, find, queryBuilder]
|
|
5
|
+
estimated_tokens: ~400
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 백엔드 개발 원칙
|
|
9
|
+
|
|
10
|
+
## 레이어 간 객체 변환 규칙
|
|
11
|
+
|
|
12
|
+
> **객체 변환은 필요한 시점에 해당 레이어에서 수행한다.**
|
|
13
|
+
|
|
14
|
+
### 핵심 원칙
|
|
15
|
+
|
|
16
|
+
| 레이어 | 입력 | 출력 | 변환 책임 |
|
|
17
|
+
|--------|------|------|----------|
|
|
18
|
+
| **Controller** | Request DTO | Response DTO/Schema | Entity → Response 변환 |
|
|
19
|
+
| **Service** | DTO (그대로 사용) | Entity 또는 일반 객체 | DTO → Entity 변환 (필요시) |
|
|
20
|
+
| **Repository** | Entity | Entity | 없음 |
|
|
21
|
+
|
|
22
|
+
### Controller → Service 호출
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// ❌ Controller에서 미리 Entity로 변환
|
|
26
|
+
@Post()
|
|
27
|
+
async create(@Body() dto: CreateUserDto) {
|
|
28
|
+
const entity = new User();
|
|
29
|
+
entity.name = dto.name;
|
|
30
|
+
entity.email = dto.email;
|
|
31
|
+
return this.userService.create(entity); // Entity 전달
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ✅ DTO 그대로 전달
|
|
35
|
+
@Post()
|
|
36
|
+
async create(@Body() dto: CreateUserDto) {
|
|
37
|
+
return this.userService.create(dto); // DTO 전달
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Service 내부 처리
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// ✅ Service에서 DTO로 사용하다가 필요한 시점에 Entity로 변환
|
|
45
|
+
async create(dto: CreateUserDto) {
|
|
46
|
+
// DTO로 비즈니스 로직 처리
|
|
47
|
+
const isValid = this.validateEmail(dto.email);
|
|
48
|
+
|
|
49
|
+
// Entity가 필요한 시점에 변환
|
|
50
|
+
const user = new User();
|
|
51
|
+
user.name = dto.name;
|
|
52
|
+
user.email = dto.email;
|
|
53
|
+
|
|
54
|
+
return this.userRepository.save(user);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Service → Controller 반환
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// ✅ Service: Entity 또는 일반 객체 반환
|
|
62
|
+
async findById(id: number): Promise<User> {
|
|
63
|
+
return this.userRepository.findOneBy({ id });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async findWithStats(id: number): Promise<{ user: User; orderCount: number }> {
|
|
67
|
+
const user = await this.userRepository.findOneBy({ id });
|
|
68
|
+
const orderCount = await this.orderRepository.countBy({ userId: id });
|
|
69
|
+
return { user, orderCount };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ✅ Controller: Response DTO/Schema로 변환
|
|
73
|
+
@Get(':id')
|
|
74
|
+
async findOne(@Param('id') id: number) {
|
|
75
|
+
const user = await this.userService.findById(id);
|
|
76
|
+
return UserResponseDto.from(user); // Controller에서 변환
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## TypeORM 사용 규칙
|
|
83
|
+
|
|
84
|
+
> **find 메서드를 기본으로 사용하고, QueryBuilder는 꼭 필요한 경우에만 사용한다.**
|
|
85
|
+
|
|
86
|
+
### find 메서드 우선 사용
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// ✅ 기본 조회
|
|
90
|
+
const user = await this.userRepository.findOneBy({ id });
|
|
91
|
+
const users = await this.userRepository.find({
|
|
92
|
+
where: { status: 'active' },
|
|
93
|
+
relations: ['orders'],
|
|
94
|
+
order: { createdAt: 'DESC' },
|
|
95
|
+
take: 10,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ✅ 조건 조합
|
|
99
|
+
const users = await this.userRepository.find({
|
|
100
|
+
where: [
|
|
101
|
+
{ status: 'active', role: 'admin' },
|
|
102
|
+
{ status: 'active', role: 'manager' },
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### QueryBuilder 허용 케이스
|
|
108
|
+
|
|
109
|
+
**다음 경우에만 QueryBuilder 사용:**
|
|
110
|
+
|
|
111
|
+
| 케이스 | 예시 |
|
|
112
|
+
|--------|------|
|
|
113
|
+
| **groupBy** | 집계 쿼리 |
|
|
114
|
+
| **getRawMany/getRawOne** | 원시 데이터 필요 |
|
|
115
|
+
| **복잡한 서브쿼리** | 중첩 쿼리 |
|
|
116
|
+
| **복잡한 JOIN 조건** | ON 절 커스텀 |
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// ✅ QueryBuilder 허용: groupBy + getRawMany
|
|
120
|
+
const stats = await this.orderRepository
|
|
121
|
+
.createQueryBuilder('order')
|
|
122
|
+
.select('order.status', 'status')
|
|
123
|
+
.addSelect('COUNT(*)', 'count')
|
|
124
|
+
.addSelect('SUM(order.amount)', 'total')
|
|
125
|
+
.groupBy('order.status')
|
|
126
|
+
.getRawMany();
|
|
127
|
+
|
|
128
|
+
// ❌ 불필요한 QueryBuilder 사용
|
|
129
|
+
const user = await this.userRepository
|
|
130
|
+
.createQueryBuilder('user')
|
|
131
|
+
.where('user.id = :id', { id })
|
|
132
|
+
.getOne();
|
|
133
|
+
|
|
134
|
+
// ✅ find로 대체
|
|
135
|
+
const user = await this.userRepository.findOneBy({ id });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 체크리스트
|
|
141
|
+
|
|
142
|
+
- [ ] Controller에서 Entity로 변환하지 않고 DTO를 그대로 Service에 전달하는가?
|
|
143
|
+
- [ ] Service에서 Entity가 필요한 시점에 변환하는가?
|
|
144
|
+
- [ ] Service의 return은 Entity 또는 일반 객체인가?
|
|
145
|
+
- [ ] Controller에서 Response DTO/Schema로 변환하는가?
|
|
146
|
+
- [ ] TypeORM find 메서드를 우선 사용하는가?
|
|
147
|
+
- [ ] QueryBuilder는 groupBy, getRawMany 등 필요한 경우에만 사용하는가?
|