AI 코딩 도구 통합 개발자 매뉴얼 - k82022603/k82022603.github.io GitHub Wiki
AI 코딩 도구 통합 개발자 매뉴얼 #
Claude Code, Codex, Google Antigravity 완전 정복
Git 워크플로우부터 PR 자동화까지, 실전에서 바로 쓰는 완벽 가이드
- Part 1: 기본 설정과 개념
- Part 2: Git 워크플로우 마스터
- Part 3: 도구별 완전 활용법
- Part 4: 슬래시 커맨드 라이브러리
- Part 5: 실전 시나리오
- 부록 1: 커맨드 템플릿 모음
- 부록 2: 슬래시 커맨드 고급 활용
현대 AI 코딩 도구는 각자 강점이 다릅니다. 마치 요리사가 상황에 따라 다른 칼을 쓰듯, 개발자도 작업에 맞는 도구를 선택해야 합니다.
핵심 철학: "계획을 먼저 세우고, 단계적으로 실행한다"
강점:
- Plan Mode: 복잡한 작업을 단계별로 분해
- Subagent System: 여러 AI가 협업 (Explore, Plan, Task, Test)
- 터미널 통합: Git, 파일 시스템 직접 제어
- 200K 컨텍스트: 대규모 코드베이스 전체 이해
약점:
- GUI가 없음 (터미널만)
- 학습 곡선 있음
- 빠른 실험보다는 체계적 개발에 적합
언제 사용하나?
# 복잡한 기능 설계
claude --mode plan "
사용자 인증 시스템을 만들어줘.
- JWT 토큰
- Redis 세션
- 소셜 로그인 (Google, GitHub)
- 2FA 지원
"
# 결과: 단계별 실행 계획 + 각 단계마다 승인 요청
# Plan → Review → Approve → Execute디렉토리 구조:
~/.claude/
├── commands/ # 슬래시 커맨드 (.md 파일)
│ ├── commit.md
│ ├── pr.md
│ └── devlog.md
├── config.json # 전역 설정
└── CLAUDE.md # 프로젝트별 규칙 (프로젝트 루트에도)
핵심 철학: "완벽을 추구한다. 느려도 정확하게"
강점:
- Effort Levels: medium, high, xhigh (정밀도 조절)
- 버그 탐지: SWE-Bench Pro 56.4% (업계 최고)
- 코드 리뷰: Critical/Medium/Low 우선순위 자동 분류
- 보안 감사: 취약점 스캔 전문
약점:
- 느림 (특히 xhigh effort)
- 비용 (effort에 따라 토큰 소비량 차이 큼)
- 개발보다는 검증에 특화
언제 사용하나?
# 코드 리뷰 (배포 전)
codex --effort xhigh "
이 PR을 프로덕션 배포 전 최종 검증해줘.
우선순위:
1. CRITICAL만 찾기 (보안, 데이터 손실)
2. 나머지는 무시
$(git diff main)
"
# 빠른 체크 (개발 중)
codex --effort medium "간단히 체크해줘"Effort 레벨 가이드:
| Effort | 속도 | 정확도 | 토큰 | 사용 시기 |
|---|---|---|---|---|
| medium | 빠름 | 80% | 1x | 개발 중 빠른 피드백 |
| high | 보통 | 95% | 3x | PR 생성 전 리뷰 |
| xhigh | 느림 | 99% | 10x | 프로덕션 배포 전 |
핵심 철학: "동시에 여러 일을 하고, 브라우저로 검증한다"
강점:
- Manager View: 여러 에이전트를 동시 실행
- Browser Subagent: 실제 브라우저로 UI 테스트
- Artifacts: 자동 스크린샷, 비디오 녹화
- 병렬 워크스페이스: 독립적인 작업 3개 동시 진행
약점:
- 실험적 (2025년 11월 출시)
- 안정성 이슈 가능
- 한국어 지원 제한적
언제 사용하나?
Manager View에서:
┌─────────────────┬─────────────────┬─────────────────┐
│ Workspace 1 │ Workspace 2 │ Workspace 3 │
│ Dashboard 구현 │ 로그인 페이지 │ 통계 차트 │
│ (Agent A) │ (Agent B) │ (Agent C) │
└─────────────────┴─────────────────┴─────────────────┘
20분 후:
✓ 3개 페이지 완성
✓ 18개 스크린샷 (다양한 해상도)
✓ 3개 비디오 (실제 동작)
✓ 자동 테스트 리포트
도구 선택 플로우차트:
작업 시작
↓
복잡한 설계 필요? ───YES→ Claude Code (Plan Mode)
↓ NO
↓
병렬 작업 가능? ───YES→ Antigravity (Manager View)
↓ NO
↓
최종 검증 단계? ───YES→ Codex (xhigh)
↓ NO
↓
빠른 개발 ───→ Claude Code (일반 모드)
# 1. Claude Code
curl -O https://install.claude.ai/cli.sh
sh cli.sh
# 설정 확인
claude --version
# claude version 2.5.0
# 2. OpenAI Codex
npm install -g @openai/codex-cli
# API 키 설정
echo "OPENAI_API_KEY=sk-..." > ~/.openairc
# 3. Google Antigravity
# 웹 기반이므로 별도 설치 불필요
# https://antigravity.google.com 접속~/projects/my-app/
├── .claude/
│ ├── CLAUDE.md # 프로젝트 규칙
│ ├── commands/ # 커스텀 슬래시 커맨드
│ │ ├── commit.md
│ │ ├── commit-push.md
│ │ ├── pr.md
│ │ ├── devlog.md
│ │ ├── review.md
│ │ └── deploy.md
│ └── plugins/ # Claude Code 플러그인
│ └── my-plugin.json
├── .codex/
│ └── config.json # Codex 설정
├── .antigravity/
│ └── workspaces.json # Workspace 설정
└── .devlog/ # 개발 일지 (자동 생성)
├── 2026-01-04.md
└── 2026-01-05.md
# 프로젝트: [프로젝트명]
## 기술 스택
- Backend: Spring Boot 3.2, Java 21
- Frontend: React 18, TypeScript
- Database: PostgreSQL 15
- Infra: Docker, AWS
## Git 워크플로우
### 브랜치 전략
- main: 프로덕션
- develop: 개발 통합
- feature/*: 기능 개발
- hotfix/*: 긴급 수정
### 커밋 컨벤션 (Conventional Commits)
- feat: 새 기능
- fix: 버그 수정
- refactor: 리팩토링
- docs: 문서
- test: 테스트
- chore: 기타
예시: `feat(auth): add JWT token refresh`
### PR 규칙
- 제목: 커밋 컨벤션 따름
- 본문: 변경사항, 테스트 방법, 스크린샷 포함
- 리뷰어: 최소 1명 승인 필요
## 코딩 규칙
### CRITICAL (절대 지켜야 함)
- NEVER: SQL 문자열 직접 조합
- ALWAYS: PreparedStatement 또는 JPA
- NEVER: 민감정보 로그 출력
- ALWAYS: 예외는 CustomException으로
### IMPORTANT (매우 중요)
- 모든 API는 @Valid로 입력 검증
- Service 메서드는 @Transactional
- 200줄 넘는 메서드는 분리
- 테스트 커버리지 80% 유지
### RECOMMENDED (권장)
- JavaDoc 주석 작성
- TODO는 Jira 티켓 번호 포함
- Magic Number는 상수로
## AI 도구 사용 가이드
### Claude Code
- 복잡한 기능: Plan Mode 사용
- 커밋 전: /commit 실행
- 하루 마무리: /devlog 실행
### Codex
- PR 생성 전: --effort high
- 배포 전: --effort xhigh
- 개발 중: --effort medium
### Antigravity
- 다중 페이지 개발: Manager View
- UI 검증: Browser Subagent파일 생성: ~/.claude/commands/commit.md
---
description: "현재까지의 작업을 논리적 단위별로 나눠서 커밋"
---
현재까지 작업한 내용을 작업 단위별로 나눠서 커밋해주세요.
## 수행 단계
### 1. 현재 변경사항 분석
```bash
git status
git diff
git diff --staged
```
다음 정보를 파악:
- 수정된 파일 목록
- 각 파일의 변경 내용
- 변경사항 간의 관계
### 2. 변경사항을 논리적 단위로 그룹화
**좋은 예**:
```
그룹 1 (기능): UserService.java, UserRepository.java
그룹 2 (테스트): UserServiceTest.java
그룹 3 (문서): README.md, API.md
```
**나쁜 예**:
```
그룹 1: UserService.java, README.md, docker-compose.yml
(관련 없는 파일들이 섞임)
```
**그룹화 원칙**:
- 하나의 커밋 = 하나의 완성된 의미
- 관련 있는 파일끼리 묶기
- 다른 타입(기능/테스트/문서)은 분리
### 3. 각 그룹별로 순차 커밋
우선순위:
1. 핵심 기능 (feat)
2. 버그 수정 (fix)
3. 리팩토링 (refactor)
4. 테스트 (test)
5. 문서 (docs)
6. 기타 (chore)
각 커밋마다:
```bash
git add [관련 파일들]
git commit -m "type(scope): 간결한 설명
상세 설명 (선택):
- 변경 이유
- 영향 범위
- 관련 이슈 번호
"
```
**커밋 메시지 템플릿**:
```
feat(auth): JWT 토큰 갱신 기능 추가
- 만료된 토큰 자동 갱신
- Refresh Token 저장 (Redis)
- 보안: HttpOnly 쿠키 사용
Resolves: #123
```
### 4. 커밋 검증
```bash
# 커밋 이력 확인
git log --oneline -10
# 각 커밋이 의미있는지 확인:
# ✓ feat(auth): add JWT refresh
# ✓ test(auth): add JWT refresh tests
# ✓ docs(api): update authentication API docs
# ✗ update files (❌ 불명확)
```
### 5. 최종 상태 확인
```bash
git status
# 출력이 "nothing to commit, working tree clean"이어야 함
# 만약 남은 파일이 있다면:
# 1. 의도적으로 남긴 것인지 확인
# 2. 필요하면 추가 커밋
# 3. 또는 .gitignore 추가
```
## 특수 케이스
### 케이스 1: 파일이 너무 많을 때 (50개 이상)
```bash
# 파일 타입별로 그룹화
git add src/**/*.java # Java 파일만
git commit -m "refactor: update service layer"
git add src/**/*Test.java # 테스트만
git commit -m "test: update service tests"
git add *.md # 문서만
git commit -m "docs: update documentation"
```
### 케이스 2: 실험적 변경사항이 섞여있을 때
```bash
# 안정적인 변경사항만 먼저 커밋
git add -p # 인터랙티브 모드
# 각 hunk마다 선택:
# y: 이 변경사항 추가
# n: 스킵
# s: 더 작게 나누기
```
### 케이스 3: 민감한 정보가 포함된 경우
```bash
# 체크: 민감 정보 검색
git diff | grep -i "password\|secret\|key"
# 발견 시:
# 1. 해당 파일 수정 (민감정보 제거)
# 2. .gitignore 추가
# 3. 환경 변수로 대체
```
## 주의사항
### 절대 하지 말 것
- ❌ `git add .` (무분별한 전체 추가)
- ❌ 관련 없는 파일 한 커밋에
- ❌ "WIP", "update", "fix" 같은 불명확한 메시지
- ❌ .env, credentials, node_modules 커밋
### 반드시 할 것
- ✅ CLAUDE.md의 커밋 컨벤션 따르기
- ✅ 각 커밋은 독립적으로 의미 있게
- ✅ 커밋 메시지에 이유(why) 포함
- ✅ 큰 변경은 작은 커밋으로 분할
## 출력 형식
커밋 완료 후 다음 정보 출력:
```
✅ 커밋 완료 (총 3개)
1. feat(user): add profile update API
- 파일: UserController.java, UserService.java
- 변경: +89 -12
2. test(user): add profile update tests
- 파일: UserControllerTest.java
- 변경: +156 -0
3. docs(api): update user API documentation
- 파일: API.md
- 변경: +23 -5
📊 전체 변경: +268 -17
🔗 최신 커밋: 7a3b9c2
```사용 방법:
# 작업 완료 후
claude
> /commit
# Claude가 자동으로:
# 1. git status, git diff 분석
# 2. 논리적 단위로 분류
# 3. 우선순위대로 커밋
# 4. 결과 요약 출력실제 예시:
# Before (수동)
$ git status
Modified: UserService.java
Modified: UserController.java
Modified: UserServiceTest.java
Modified: README.md
Modified: docker-compose.yml
$ git add .
$ git commit -m "update user" # ❌
# After (AI)
$ claude
> /commit
# AI 분석:
"3개의 논리적 그룹 발견:
1. 사용자 프로필 기능 (feat)
2. 테스트 (test)
3. 문서 및 인프라 (docs, chore)
순차 커밋을 시작합니다..."
# 결과:
✅ feat(user): add profile update API
✅ test(user): add profile update tests
✅ docs: update README with new API
✅ chore(docker): add Redis for session파일 생성: ~/.claude/commands/commit-push.md
---
description: "논리적 단위별 커밋 후 원격 저장소에 푸시"
---
현재까지 작업한 내용을 커밋하고, 원격 저장소에 푸시해주세요.
### 1. 현재 변경사항 분석
(파일 수정을 위한 `git status`, `git diff` 분석)
### 2. 논리적 단위 그룹화 및 순차 커밋
(작업 단위별로 `git add` 및 Conventional Commits 기반 `git commit` 수행)
### 3. 최종 상태 및 충돌 확인
(로컬 커밋 완료 상태 확인 및 원격 브랜치와 비교)
### 5. 원격 브랜치 상태 확인
```bash
# 원격 브랜치 최신 정보 가져오기
git fetch origin
# 현재 브랜치 확인
CURRENT_BRANCH=$(git branch --show-current)
echo "현재 브랜치: $CURRENT_BRANCH"
# 원격 브랜치 존재 여부
git ls-remote --heads origin $CURRENT_BRANCH
```
### 6. 로컬/원격 비교
```bash
# 로컬이 원격보다 앞서있는지 확인
git rev-list origin/$CURRENT_BRANCH..$CURRENT_BRANCH
# 출력 분석:
# - 결과 있음: 로컬에 새 커밋 존재 (푸시 필요)
# - 결과 없음: 이미 동기화됨 (푸시 불필요)
# 원격이 로컬보다 앞서있는지 확인
git rev-list $CURRENT_BRANCH..origin/$CURRENT_BRANCH
# 출력 분석:
# - 결과 있음: 원격에 새 커밋 존재 (pull 필요)
# - 결과 없음: 로컬이 최신
```
### 7. 충돌 사전 감지
원격이 로컬보다 앞선 경우:
```bash
# 1. 원격 변경사항 확인
git log $CURRENT_BRANCH..origin/$CURRENT_BRANCH --oneline
# 2. 사용자에게 알림
echo "⚠️ 원격 브랜치에 새 커밋이 있습니다:"
echo "$(git log $CURRENT_BRANCH..origin/$CURRENT_BRANCH --oneline)"
echo ""
echo "옵션:"
echo "1. pull 후 push (권장)"
echo "2. force push (위험 - 팀 작업 시 절대 금지)"
echo ""
read -p "선택 (1/2): " choice
if [ "$choice" = "1" ]; then
# Pull (rebase 권장)
git pull --rebase origin $CURRENT_BRANCH
# 충돌 발생 시
if [ $? -ne 0 ]; then
echo "❌ 충돌 발생. 수동 해결 필요."
echo ""
echo "충돌 파일:"
git diff --name-only --diff-filter=U
echo ""
echo "해결 후 다음 명령 실행:"
echo " git add [해결된 파일]"
echo " git rebase --continue"
exit 1
fi
fi
```
### 8. 푸시 실행
```bash
# 새 브랜치인 경우
if ! git ls-remote --heads origin $CURRENT_BRANCH | grep -q $CURRENT_BRANCH; then
echo "📝 새 브랜치 생성 및 푸시"
git push -u origin $CURRENT_BRANCH
else
echo "📤 기존 브랜치 푸시"
git push origin $CURRENT_BRANCH
fi
# 푸시 성공 확인
if [ $? -eq 0 ]; then
echo "✅ 푸시 성공!"
echo ""
echo "원격 URL: $(git remote get-url origin)"
echo "브랜치: $CURRENT_BRANCH"
echo "커밋: $(git log -1 --oneline)"
else
echo "❌ 푸시 실패"
echo ""
echo "가능한 원인:"
echo "1. 권한 없음 (SSH 키 확인)"
echo "2. 브랜치 보호 규칙"
echo "3. 네트워크 문제"
exit 1
fi
```
### 9. CI/CD 트리거 확인 (선택)
푸시 후 CI/CD가 자동 실행되는 경우:
```bash
# GitHub Actions인 경우
echo "🔄 GitHub Actions 확인 중..."
gh run list --branch $CURRENT_BRANCH --limit 1
# 또는 웹 브라우저로 열기
gh run watch
```
## 특수 케이스
### 케이스 1: Protected Branch (main, develop)
```bash
# Protected 브랜치로 직접 푸시 불가
if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "develop" ]; then
echo "⚠️ Protected 브랜치에는 직접 푸시 불가"
echo ""
echo "올바른 절차:"
echo "1. feature 브랜치 생성"
echo "2. 해당 브랜치에서 작업"
echo "3. PR 생성"
echo ""
echo "자동으로 feature 브랜치를 만들까요? (y/n)"
read answer
if [ "$answer" = "y" ]; then
FEATURE_NAME="feature/$(date +%Y%m%d)-auto"
git checkout -b $FEATURE_NAME
git push -u origin $FEATURE_NAME
echo "✅ $FEATURE_NAME 생성 및 푸시 완료"
fi
exit 0
fi
```
### 케이스 2: Large Files (100MB+)
```bash
# Git LFS 필요한지 체크
LARGE_FILES=$(git diff --cached --name-only | xargs ls -lh 2>/dev/null | awk '$5 ~ /M$/ && $5+0 > 50')
if [ ! -z "$LARGE_FILES" ]; then
echo "⚠️ 큰 파일 발견 (50MB+):"
echo "$LARGE_FILES"
echo ""
echo "Git LFS 사용을 권장합니다."
echo "계속하시겠습니까? (y/n)"
read answer
if [ "$answer" != "y" ]; then
echo "푸시 취소됨"
exit 1
fi
fi
```
### 케이스 3: Pre-push Hook
```bash
# .git/hooks/pre-push가 있는 경우 실행
if [ -x .git/hooks/pre-push ]; then
echo "🔍 Pre-push 훅 실행 중..."
.git/hooks/pre-push
if [ $? -ne 0 ]; then
echo "❌ Pre-push 훅 실패"
echo "훅을 무시하고 푸시? (y/n)"
read answer
if [ "$answer" != "y" ]; then
exit 1
fi
fi
fi
```
## 주의사항
### 푸시 전 반드시 확인
- ✅ 모든 테스트 통과
- ✅ .env, credentials 제외됨
- ✅ CLAUDE.md 규칙 준수
- ✅ 팀원과 충돌 여부
### 절대 하지 말 것
- ❌ `git push -f` (force push)
- 예외: 자신만 쓰는 feature 브랜치
- ❌ 민감 정보 포함된 커밋 푸시
- ❌ 테스트 실패 상태로 푸시
- ❌ 빌드 깨진 상태로 푸시
## 출력 예시
```text
📋 커밋 요약 (3개)
─────────────────────────────────────
1. feat(auth): add JWT refresh
2. test(auth): add JWT refresh tests
3. docs(api): update auth endpoints
─────────────────────────────────────
🔍 원격 브랜치 확인...
✓ origin/feature/auth-refresh 존재
✓ 로컬이 3 commits ahead
✓ 충돌 없음
📤 푸시 중...
Enumerating objects: 15, done.
Counting objects: 100% (15/15), done.
Delta compression using up to 8 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (9/9), 2.14 KiB | 2.14 MiB/s, done.
Total 9 (delta 6), reused 0 (delta 0), pack-reused 0
To github.com:user/repo.git
3a7b9c2..8f4d1e5 feature/auth-refresh -> feature/auth-refresh
✅ 푸시 성공!
📊 최종 상태
─────────────────────────────────────
브랜치: feature/auth-refresh
원격: github.com:user/repo.git
최신: 8f4d1e5 docs(api): update auth endpoints
앞서있음: 0 commits
뒤처짐: 0 commits
─────────────────────────────────────
💡 다음 단계
1. PR 생성: claude > /pr
2. CI 확인: gh run watch
```파일 생성: ~/.claude/commands/pr.md
# 명령어 디렉토리 생성
mkdir -p ~/.claude/commands
# 스크립트 파일 생성 (아래 스크립트 참조)
cat > ~/.claude/commands/pr.md << 'SCRIPT_END'
#!/bin/bash
set -e
# ... (스크립트 내용)
SCRIPT_END
# 실행 권한 부여
chmod +x ~/.claude/commands/pr.md{% raw %}
#!/bin/bash
set -e
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 함수 정의
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
check_environment() {
echo "🔍 환경 확인 중..."
if ! command -v gh &> /dev/null; then
echo "❌ GitHub CLI (gh)가 설치되지 않았습니다"
echo "설치: https://cli.github.com"
exit 1
fi
if ! gh auth status &> /dev/null; then
echo "❌ GitHub 인증이 필요합니다"
echo "실행: gh auth login"
exit 1
fi
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo "❌ Git 저장소가 아닙니다"
exit 1
fi
echo "✅ 환경 확인 완료"
}
setup_branches() {
echo ""
echo "📂 브랜치 설정 중..."
CURRENT_BRANCH=$(git branch --show-current)
if [ -z "$CURRENT_BRANCH" ]; then
echo "❌ 현재 브랜치를 확인할 수 없습니다"
exit 1
fi
echo " 현재 브랜치: $CURRENT_BRANCH"
if git show-ref --verify --quiet refs/heads/main; then
DEFAULT_BASE="main"
elif git show-ref --verify --quiet refs/heads/master; then
DEFAULT_BASE="master"
else
DEFAULT_BASE="develop"
fi
echo " 기본 브랜치: $DEFAULT_BASE"
echo ""
echo "Base 브랜치를 선택하세요:"
echo " 1) $DEFAULT_BASE (기본)"
echo " 2) develop"
echo " 3) 직접 입력"
echo ""
echo -n "선택 [1/2/3, 기본=1]: "
read -r base_choice
case "$base_choice" in
2) BASE_BRANCH="develop" ;;
3)
echo -n "Base 브랜치 이름: "
read -r BASE_BRANCH
;;
*) BASE_BRANCH="$DEFAULT_BASE" ;;
esac
echo " → Base: $BASE_BRANCH"
}
analyze_commits() {
echo ""
echo "📊 커밋 분석 중..."
COMMITS=$(git log "$BASE_BRANCH".."$CURRENT_BRANCH" --oneline)
COMMIT_COUNT=$(git rev-list --count "$BASE_BRANCH".."$CURRENT_BRANCH")
if [ "$COMMIT_COUNT" -eq 0 ]; then
echo "❌ 새 커밋이 없습니다"
exit 1
fi
echo ""
echo "포함될 커밋:"
echo "─────────────────────────────────────"
echo "$COMMITS"
echo "─────────────────────────────────────"
echo "커밋 수: $COMMIT_COUNT"
}
generate_pr_title() {
echo ""
echo "📝 PR 제목 생성 중..."
if [ "$COMMIT_COUNT" -eq 1 ]; then
PR_TITLE=$(git log -1 --pretty=%s)
else
FEAT_COMMIT=$(echo "$COMMITS" | grep "^[a-f0-9]* feat" | head -1 | sed 's/^[a-f0-9]* //')
if [ -n "$FEAT_COMMIT" ]; then
PR_TITLE="$FEAT_COMMIT"
else
PR_TITLE=$(echo "$COMMITS" | head -1 | sed 's/^[a-f0-9]* //')
fi
fi
echo ""
echo "제안된 PR 제목:"
echo " $PR_TITLE"
echo ""
echo -n "사용하시겠습니까? [y/n/수정]: "
read -r title_answer
case "$title_answer" in
n|N|no|No)
echo -n "새 제목 입력: "
read -r PR_TITLE
;;
수정|e|edit)
echo -n "수정할 제목: "
read -r new_title
if [ -n "$new_title" ]; then
PR_TITLE="$new_title"
fi
;;
esac
echo " 최종 제목: $PR_TITLE"
}
load_pr_template() {
if [ -f .github/PULL_REQUEST_TEMPLATE.md ]; then
cat .github/PULL_REQUEST_TEMPLATE.md
else
cat <<'TEMPLATE_EOF'
## 변경사항 요약
[변경 내용을 한 줄로]
## 상세 설명
### 추가된 기능
-
### 수정된 버그
-
### 변경된 사항
-
## 테스트 방법
### 로컬 테스트
# 재현 단계
### 예상 결과
-
## 체크리스트
- [ ] 코드가 프로젝트 스타일 가이드를 따릅니다
- [ ] 자체 코드 리뷰를 수행했습니다
- [ ] 코드에 주석을 추가했습니다
- [ ] 문서를 업데이트했습니다
- [ ] 테스트를 추가/업데이트했습니다
- [ ] 모든 테스트가 통과합니다
## 관련 이슈
Closes #
Related to #
TEMPLATE_EOF
fi
}
generate_pr_body_with_ai() {
local template="$1"
echo ""
echo "🤖 AI가 PR 본문을 작성 중..."
local changed_files
changed_files=$(git diff --name-status "$BASE_BRANCH".."$CURRENT_BRANCH" 2>/dev/null || echo "(정보 없음)")
local diff_stat
diff_stat=$(git diff "$BASE_BRANCH".."$CURRENT_BRANCH" --stat 2>/dev/null || echo "(정보 없음)")
if ! command -v claude &> /dev/null; then
echo "⚠️ Claude CLI 없음. 템플릿 사용"
echo "$template"
return 1
fi
local pr_body
pr_body=$(claude 2>/dev/null <<CLAUDE_PROMPT
다음 Git 변경사항으로 PR 본문을 작성해줘.
커밋 이력:
$COMMITS
변경된 파일:
$changed_files
변경 통계:
$diff_stat
템플릿:
$template
요구사항:
1. 템플릿의 모든 섹션 채우기
2. 구체적이고 명확하게
3. 마크다운 형식
4. 한국어 사용
출력은 순수 마크다운만 (프리앰블 없이)
CLAUDE_PROMPT
)
if [ $? -ne 0 ] || [ -z "$pr_body" ]; then
echo "⚠️ AI 생성 실패. 템플릿 사용"
echo "$template"
return 1
fi
echo "$pr_body"
return 0
}
confirm_and_edit_pr_body() {
local pr_body="$1"
echo ""
echo "─────────────────────────────────────"
echo "$pr_body"
echo "─────────────────────────────────────"
echo ""
echo "이 본문을 사용하시겠습니까?"
echo " y/yes : 그대로 사용"
echo " e/edit : 에디터로 수정"
echo " m/manual : 수동 입력"
echo " n/no : 취소"
echo ""
echo -n "선택 [y/e/m/n]: "
read -r answer
answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]' | tr -d ' ')
case "$answer" in
y|yes|"")
echo "$pr_body"
return 0
;;
e|edit|수정)
local temp_file
temp_file=$(mktemp /tmp/pr_body.XXXXXX.md)
echo "$pr_body" > "$temp_file"
${EDITOR:-vim} "$temp_file"
pr_body=$(cat "$temp_file")
rm -f "$temp_file"
echo "$pr_body"
return 0
;;
m|manual)
echo ""
echo "PR 본문 입력 (Ctrl+D로 완료):"
cat
return 0
;;
n|no|취소)
echo "❌ PR 생성 취소"
return 1
;;
*)
echo "❌ 잘못된 입력: $answer"
confirm_and_edit_pr_body "$pr_body"
return $?
;;
esac
}
generate_pr_body() {
echo ""
echo "📄 PR 본문 생성 중..."
local template
template=$(load_pr_template)
local pr_body
pr_body=$(generate_pr_body_with_ai "$template")
local final_pr_body
final_pr_body=$(confirm_and_edit_pr_body "$pr_body")
if [ $? -ne 0 ] || [ -z "$final_pr_body" ]; then
echo "❌ PR 본문 생성 실패"
exit 1
fi
FINAL_PR_BODY="$final_pr_body"
}
assign_reviewers() {
echo ""
echo "👥 리뷰어 지정 중..."
REVIEWERS=""
if [ -f .github/CODEOWNERS ]; then
echo " CODEOWNERS 파일 발견"
local changed_files
changed_files=$(git diff --name-only "$BASE_BRANCH".."$CURRENT_BRANCH")
local owners=()
while IFS= read -r file; do
local owner
owner=$(grep -E "^${file}" .github/CODEOWNERS | awk '{print $2}' | head -n 1)
if [ -n "$owner" ]; then
owner=$(echo "$owner" | sed 's/@//')
owners+=("$owner")
fi
done <<< "$changed_files"
if [ ${#owners[@]} -gt 0 ]; then
REVIEWERS=$(printf '%s\n' "${owners[@]}" | sort -u | tr '\n' ',' | sed 's/,$//')
fi
fi
if [ -n "$REVIEWERS" ]; then
echo " 추천 리뷰어: $REVIEWERS"
else
echo " CODEOWNERS에서 리뷰어를 찾을 수 없습니다"
fi
echo ""
echo -n "리뷰어를 수정하시겠습니까? [y/n]: "
read -r modify_reviewers
if [ "$modify_reviewers" = "y" ]; then
echo -n "리뷰어 입력 (쉼표로 구분): "
read -r manual_reviewers
if [ -n "$manual_reviewers" ]; then
REVIEWERS="$manual_reviewers"
fi
fi
}
infer_labels() {
echo ""
echo "🏷️ 라벨 추론 중..."
LABELS=""
if [[ $CURRENT_BRANCH == feature/* ]] || echo "$COMMITS" | grep -qi "feat"; then
LABELS="${LABELS},enhancement"
fi
if [[ $CURRENT_BRANCH == hotfix/* ]] || echo "$COMMITS" | grep -qi "fix"; then
LABELS="${LABELS},bug"
fi
if echo "$COMMITS" | grep -qi "docs"; then
LABELS="${LABELS},documentation"
fi
if echo "$COMMITS" | grep -qi "test"; then
LABELS="${LABELS},testing"
fi
if echo "$COMMITS" | grep -qi "refactor"; then
LABELS="${LABELS},refactoring"
fi
LABELS=$(echo "$LABELS" | sed 's/^,//')
if [ -n "$LABELS" ]; then
echo " 추론된 라벨: $LABELS"
fi
}
select_pr_options() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "PR 생성 옵션"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "1) Draft PR로 생성 (기본)"
echo "2) 즉시 리뷰 요청"
echo "3) Auto-merge 활성화"
echo ""
echo -n "선택 [1/2/3, 기본=1]: "
read -r pr_option
PR_FLAGS=""
AUTO_MERGE=false
case "$pr_option" in
2) PR_FLAGS="--web" ;;
3)
PR_FLAGS="--web"
AUTO_MERGE=true
;;
*) PR_FLAGS="--draft" ;;
esac
}
create_pull_request() {
echo ""
echo "🚀 PR 생성 중..."
local create_cmd="gh pr create --title \"$PR_TITLE\" --body \"$FINAL_PR_BODY\" --base \"$BASE_BRANCH\" --head \"$CURRENT_BRANCH\" $PR_FLAGS"
if [ -n "$REVIEWERS" ]; then
create_cmd="$create_cmd --reviewer \"$REVIEWERS\""
fi
if [ -n "$LABELS" ]; then
create_cmd="$create_cmd --label \"$LABELS\""
fi
if eval "$create_cmd"; then
echo ""
echo "✅ PR 생성 완료!"
PR_URL=$(gh pr view --json url -q .url)
echo " URL: $PR_URL"
if [ "$AUTO_MERGE" = true ]; then
echo ""
echo "🔄 Auto-merge 활성화 중..."
echo "머지 방법 선택:"
echo " 1) merge (머지 커밋)"
echo " 2) squash (스쿼시 머지, 기본)"
echo " 3) rebase (리베이스)"
echo -n "선택 [1/2/3]: "
read -r merge_method
case "$merge_method" in
1) METHOD="merge" ;;
3) METHOD="rebase" ;;
*) METHOD="squash" ;;
esac
gh pr merge --auto --$METHOD
echo " ✅ Auto-merge 활성화 ($METHOD)"
fi
if command -v codex &> /dev/null; then
echo ""
echo -n "Codex 셀프 리뷰를 실행하시겠습니까? [y/n]: "
read -r run_codex
if [ "$run_codex" = "y" ]; then
echo ""
echo "🤖 Codex 리뷰 시작..."
if codex review --pr "$PR_URL" --effort high; then
echo " ✅ Codex 리뷰 완료"
else
echo " ⚠️ Codex 리뷰 실패"
fi
fi
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ PR 워크플로우 완료!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "다음 단계:"
echo " 1) PR 확인: $PR_URL"
echo " 2) CI 상태: gh pr checks"
echo " 3) 리뷰 대기 또는 추가 커밋"
echo ""
else
echo ""
echo "❌ PR 생성 실패"
echo ""
echo "가능한 원인:"
echo " 1. 원격 브랜치 없음 (먼저 push 필요)"
echo " 2. 이미 PR 존재"
echo " 3. 권한 부족"
echo " 4. Base 브랜치 잘못 지정"
exit 1
fi
}
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 메인 실행
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
main() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🚀 Pull Request 자동 생성"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
check_environment
setup_branches
analyze_commits
generate_pr_title
generate_pr_body
assign_reviewers
infer_labels
select_pr_options
create_pull_request
}
main{% endraw %}
예시 1: 기본 워크플로우
$ claude
> /pr
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚀 Pull Request 자동 생성
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔍 환경 확인 중...
✅ 환경 확인 완료
📂 브랜치 설정 중...
현재 브랜치: feature/user-profile
기본 브랜치: main
Base 브랜치를 선택하세요:
1) main (기본)
2) develop
3) 직접 입력
선택 [1/2/3, 기본=1]: 1
→ Base: main
📊 커밋 분석 중...
포함될 커밋:
─────────────────────────────────────
8f4d1e5 docs(api): update auth endpoints
7a3b9c2 test(auth): add JWT refresh tests
6c2a8f1 feat(auth): add JWT refresh token
─────────────────────────────────────
커밋 수: 3실행 결과:
✅ PR 생성 완료!
URL: https://github.com/user/repo/pull/456
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ PR 워크플로우 완료!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
다음 단계:
1) PR 확인: https://github.com/user/repo/pull/456
2) CI 상태: gh pr checks
3) 리뷰 대기 또는 추가 커밋예시 2: Auto-merge 활성화
$ bash ~/.claude/commands/pr.md
선택 [1/2/3, 기본=1]: 3
🚀 PR 생성 중...
✅ PR 생성 완료!
URL: https://github.com/user/repo/pull/457
🔄 Auto-merge 활성화 중...
머지 방법 선택:
1) merge (머지 커밋)
2) squash (스쿼시 머지, 기본)
3) rebase (리베이스)
선택 [1/2/3]: 2
✅ Auto-merge 활성화 (squash)- ✅ 환경 자동 확인 (gh, git, 인증)
- ✅ Base 브랜치 선택 (main/master/develop)
- ✅ 커밋 분석 및 PR 제목 자동 생성
- ✅ AI를 활용한 PR 본문 작성 (Claude CLI)
- ✅ CODEOWNERS 기반 리뷰어 자동 지정
- ✅ 브랜치/커밋 기반 라벨 추론
- ✅ Draft/Web/Auto-merge 옵션
- ✅ Codex 셀프 리뷰 통합
필수
-
GitHub CLI (
gh) - [설치 가이드](https://cli.github.com) - Git
선택
- Claude CLI - PR 본문 AI 생성용
- Codex - 자동 코드 리뷰용
"원격 브랜치 없음" 에러
# 먼저 브랜치를 push 하세요
git push -u origin <브랜치명>"이미 PR 존재" 에러
# 기존 PR 확인
gh pr list
# 기존 PR 닫기 (필요시)
gh pr close <PR번호>Claude CLI 없음 경고
AI 본문 생성이 스킵되고 템플릿이 사용됩니다. Claude CLI를 설치하면 AI 생성 기능을 사용할 수 있습니다.
-
PR 템플릿 사용:
.github/PULL_REQUEST_TEMPLATE.md파일 생성 -
CODEOWNERS 설정:
.github/CODEOWNERS파일로 자동 리뷰어 지정 -
커밋 컨벤션:
feat:,fix:,docs:등의 접두사로 자동 라벨링 -
빠른 실행:
alias pr='bash ~/.claude/commands/pr.md'를.bashrc에 추가
Plan Mode는 Claude Code의 핵심 기능입니다. 복잡한 작업을 단계별로 분해하고, 각 단계마다 승인을 받아 진행합니다.
활성화 방법:
# 방법 1: 플래그 사용
claude --mode plan "복잡한 작업"
# 방법 2: 환경 변수
export CLAUDE_MODE=plan
claude "작업"
# 방법 3: 대화 중 전환
claude
> /plan
> 이제 계획 모드입니다. 작업을 설명해주세요.Plan Mode 워크플로우:
사용자 요청
↓
┌─────────────────────────────┐
│ Phase 1: Exploration │
│ - 코드베이스 분석 │
│ - 의존성 파악 │
│ - 제약사항 확인 │
└─────────────────────────────┘
↓
┌─────────────────────────────┐
│ Phase 2: Planning │
│ - 단계 분해 │
│ - 우선순위 결정 │
│ - 리스크 식별 │
└─────────────────────────────┘
↓
사용자 승인 (y/n/수정)
↓
┌─────────────────────────────┐
│ Phase 3: Execution │
│ Step 1 실행 → 승인 대기 │
│ Step 2 실행 → 승인 대기 │
│ Step 3 실행 → 승인 대기 │
└─────────────────────────────┘
↓
┌─────────────────────────────┐
│ Phase 4: Validation │
│ - 테스트 실행 │
│ - 결과 검증 │
│ - 문서화 │
└─────────────────────────────┘
실전 예시:
$ claude --mode plan
User: 우리 서비스에 결제 기능을 추가해줘.
- PG사: 토스페이먼츠
- 지원 방식: 카드, 계좌이체
- 정기결제 포함
Claude (Exploration):
📊 코드베이스 분석 중...
발견 사항:
- Spring Boot 3.2 사용
- 기존 주문(Order) 엔티티 존재
- DB: PostgreSQL
- 결제 관련 코드 없음
외부 의존성:
- Toss Payments SDK 추가 필요
- Webhook 엔드포인트 필요
제약사항:
- PCI DSS 규정 준수 필요
- 카드번호 저장 금지
- 트랜잭션 관리 중요
계속 진행할까요?
User: y
Claude (Planning):
📋 실행 계획
Phase 1: 환경 설정 (15분)
1.1. Toss Payments SDK 의존성 추가
1.2. application.yml에 API 키 설정
1.3. TossPaymentsConfig 클래스 생성
Phase 2: 도메인 모델 (30분)
2.1. Payment 엔티티 생성
2.2. PaymentMethod enum 정의
2.3. PaymentStatus enum 정의
2.4. Order-Payment 연관관계 설정
Phase 3: 결제 프로세스 (1시간)
3.1. PaymentService 구현
- requestPayment() - 결제 요청
- approvePayment() - 결제 승인
- cancelPayment() - 결제 취소
3.2. PaymentController 구현
3.3. Webhook 핸들러 구현
Phase 4: 정기결제 (45분)
4.1. Subscription 엔티티
4.2. 스케줄러 설정
4.3. 자동 결제 로직
Phase 5: 테스트 (1시간)
5.1. 단위 테스트
5.2. 통합 테스트
5.3. Webhook 테스트
Phase 6: 문서화 (20분)
6.1. API 문서 업데이트
6.2. README에 설정 가이드
6.3. 결제 플로우 다이어그램
총 예상 시간: 3시간 50분
리스크:
⚠️ High: Webhook 누락 시 결제 상태 불일치
⚠️ Medium: API 키 노출 위험
⚠️ Low: 네트워크 타임아웃
이 계획으로 진행할까요? (y/n/수정)
User: y
Claude (Execution - Phase 1):
🔧 Phase 1.1: Toss Payments SDK 추가
pom.xml 수정:
```xml
<dependency>
<groupId>com.tosspayments</groupId>
<artifactId>toss-payments-java</artifactId>
<version>1.0.0</version>
</dependency>
```
완료. 다음 단계로? (y/n/롤백)
User: y
Claude (Execution - Phase 1.2):
🔧 Phase 1.2: API 키 설정
application.yml 수정:
```yaml
toss:
payments:
secret-key: ${TOSS_SECRET_KEY}
client-key: ${TOSS_CLIENT_KEY}
```
.env.example 추가:
```
TOSS_SECRET_KEY=test_sk_...
TOSS_CLIENT_KEY=test_ck_...
```
⚠️ 주의: 실제 키는 .env에만 저장하고 절대 커밋하지 마세요!
완료. 다음 단계로? (y/n/롤백)
... (모든 Phase 순차 실행)
Claude Code는 내부적으로 여러 Subagent를 동시에 실행할 수 있습니다.
Subagent 종류:
| Subagent | 역할 | 사용 시점 |
|---|---|---|
| Explore | 코드베이스 탐색, 파일 구조 파악 | 프로젝트 초기 분석 |
| Plan | 실행 계획 수립 | 복잡한 작업 전 |
| Task | 실제 코드 작성 | 개발 단계 |
| Test | 테스트 코드 생성 및 실행 | 검증 단계 |
| Review | 코드 리뷰, 개선 제안 | PR 전 |
수동 Subagent 실행:
파일 생성: ~/.claude/commands/parallel-dev.md
---
description: "여러 Subagent로 병렬 개발"
---
다음 작업을 병렬로 실행해주세요:
Subagent 1 (Explore):
- src/ 디렉토리 구조 분석
- 주요 클래스와 의존성 파악
- 결과를 explore_result.md에 저장
Subagent 2 (Plan):
- explore_result.md 읽기
- 새 기능 추가 계획 수립
- 결과를 plan.md에 저장
Subagent 3 (Task):
- plan.md 읽기
- 1단계 구현 (서비스 레이어)
- 결과를 Git에 커밋
모든 Subagent가 완료되면 요약 리포트 생성.
```
**사용**:
```bash
claude
> /parallel-dev
# Claude가 3개 Subagent 동시 실행
# 각자 독립적으로 작업 후 결과 통합
```개발 일지 자동화:
파일 생성: ~/.claude/commands/devlog.md
---
description: "오늘 작업 내용을 정리해서 개발 일지 작성"
---
오늘({{ 현재 날짜 }}) 작업한 내용으로 개발 일지를 작성해주세요.
## 수집 정보
### 1. Git 커밋 이력
```bash
git log --since="today" --author="$(git config user.name)" --oneline
```
### 2. 변경된 파일
```bash
git diff --name-status HEAD@{yesterday}..HEAD
```
### 3. 세션 기록
- .devlog/ 디렉토리의 오늘 날짜 md 파일들 읽기
- 각 커밋 시 저장된 요약 통합
## 출력 형식
파일명: `.devlog/YYYY-MM-DD.md`
내용:
```markdown
# 개발 일지 - YYYY-MM-DD
## 📊 요약
- 커밋 수: X개
- 변경 파일: Y개
- 주요 작업: [간단 요약]
## ✅ 완료한 작업
### [기능/버그/개선]
- 작업 내용 1
- 상세 설명
- 커밋: abc1234
- 작업 내용 2
## 🔧 진행 중인 작업
- 작업 A (70% 완료)
- 작업 B (시작 단계)
## 🐛 발견한 이슈
- 이슈 1: 설명
- 해결 방법: ...
- 또는 TODO로 남김
## 💡 배운 점
- 기술적 인사이트
- 개선 아이디어
## 📝 내일 할 일
- [ ] 작업 1
- [ ] 작업 2
## 📈 통계
- 추가된 코드: +XXX줄
- 삭제된 코드: -YYY줄
- 테스트 커버리지: ZZ%
```
## 추가 작업
1. Slack에 요약 전송 (선택)
```bash
if [ -f .slack-webhook ]; then
curl -X POST $(cat .slack-webhook) \
-H 'Content-Type: application/json' \
-d '{"text": "오늘의 개발 일지 작성 완료: [링크]"}'
fi
```
```bash
git add .devlog/$(date +%Y-%m-%d).md
git commit -m "docs: add devlog for $(date +%Y-%m-%d)"
```사용 시나리오:
# 하루 일과 종료 전
claude
> /devlog
# Claude가 자동으로:
# 1. 오늘 커밋 분석
# 2. 세션 기록 통합
# 3. 개발 일지 생성
# 4. Git 커밋
# 5. Slack 알림 (설정된 경우)
✅ 개발 일지 생성 완료!
파일: .devlog/2026-01-04.md
📊 오늘의 통계
─────────────────────────────────
커밋: 8개
파일 변경: 23개
추가: +487줄
삭제: -123줄
주요 작업: JWT 토큰 갱신 기능 완성
─────────────────────────────────
💬 Slack 알림 전송 완료
🔗 Git 커밋 완료 (a7b3c9d)
Medium Effort - 개발 중 빠른 피드백:
---
description: "Codex로 빠른 코드 체크 (medium effort)"
---
현재 작업 중인 코드를 빠르게 체크해주세요.
실행:
```bash
codex --effort medium "
최근 변경사항을 간단히 체크해줘.
변경 파일:
$(git diff --name-only)
Diff:
$(git diff)
체크 항목:
- 명백한 버그
- 기본 코드 품질
- 간단한 개선 제안
결과는 3가지로 분류:
OK: 문제 없음
MINOR: 사소한 개선 가능
ISSUE: 즉시 수정 필요
각 파일별로 간단히 요약.
시간 제한: 30초
"
```
결과:
```text
✅ UserService.java - OK
⚠️ UserController.java - MINOR
- Line 45: 매직 넘버 사용 (상수로 대체 권장)
❌ PaymentService.java - ISSUE
- Line 78: NullPointerException 가능성
```
시간: 빠름 (10-30초)
용도: 개발 중 수시로 체크High Effort - PR 전 꼼꼼한 리뷰:
---
description: "Codex로 PR 전 전문 리뷰 (high effort)"
---
PR 생성 전 전문적인 코드 리뷰를 수행해주세요.
실행:
```bash
BASE_BRANCH=${1:-develop}
codex --effort high "
이 PR을 리뷰해줘.
Base: $BASE_BRANCH
Head: $(git branch --show-current)
커밋:
$(git log $BASE_BRANCH..HEAD --oneline)
전체 변경사항:
$(git diff $BASE_BRANCH..HEAD)
리뷰 기준:
1. 보안 (XSS, SQL Injection, 권한)
2. 성능 (N+1, 메모리 누수, 알고리즘)
3. 테스트 (커버리지, 엣지 케이스)
4. 설계 (SOLID, DRY, 응집도)
5. 가독성 (네이밍, 주석, 구조)
우선순위별 분류:
- CRITICAL: 반드시 수정 (보안, 데이터 손실)
- HIGH: 강력 권장 (버그, 성능 저하)
- MEDIUM: 권장 (코드 품질)
- LOW: 선택 (스타일, 일관성)
각 이슈마다:
- 파일명과 라인
- 문제 설명
- 해결 방법
- 예시 코드
GitHub PR Comment 형식으로 출력.
"
```
결과 (GitHub Markdown):
```markdown
## 🔍 Codex Code Review
### ⚠️ CRITICAL (1)
**PaymentService.java:78**
```java
// ❌ 현재 코드
payment.setAmount(request.getAmount());
orderRepository.save(order);
// 문제: 트랜잭션 없음. 결제 실패 시 주문은 저장됨
```
**해결책:**
```java
@Transactional
public Payment processPayment(PaymentRequest request) {
Payment payment = paymentRepository.save(...);
Order order = orderRepository.save(...);
return payment;
}
```
### 🔴 HIGH (3)
**UserController.java:45**
```java
// ❌ N+1 쿼리 발생
users.forEach(user -> {
user.getOrders().size(); // 각 user마다 쿼리 실행
});
```
**해결책:**
```java
// ✅ Fetch Join
@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders")
List<User> findAllWithOrders();
```
... (계속)
```
시간: 보통 (1-3분)
용도: PR 생성 전 필수XHigh Effort - 프로덕션 배포 전 최종 검증:
---
description: "Codex로 프로덕션 배포 전 최종 감사 (xhigh effort)"
---
프로덕션 배포 전 최종 보안 감사를 수행해주세요.
실행:
```bash
RELEASE_BRANCH=${1:-release/v1.0}
codex --effort xhigh "
프로덕션 배포 전 최종 감사.
릴리스 브랜치: $RELEASE_BRANCH
포함 커밋: $(git rev-list --count main..$RELEASE_BRANCH)개
전체 코드베이스:
$(find src -name '*.java' | xargs cat)
환경 설정:
$(cat application*.yml)
의존성:
$(cat pom.xml)
집중 검사 항목:
1. 보안 취약점
- OWASP Top 10
- 민감정보 노출
- 권한 우회
- API 키 하드코딩
2. 데이터 무결성
- 트랜잭션 경계
- 동시성 제어
- 데이터 검증
3. 가용성
- 에러 핸들링
- Circuit Breaker
- Retry 로직
- Timeout 설정
4. 성능
- 쿼리 최적화
- 캐싱 전략
- 리소스 관리
5. 모니터링
- 로깅
- 메트릭
- 알람
CRITICAL 이슈만 보고.
각 이슈는 CVE 참조 포함.
배포 GO/NO-GO 판단 포함.
상세 보고서 형식.
"
```
결과:
```markdown
# 프로덕션 배포 전 보안 감사 리포트
## Executive Summary
- 검사 파일: 147개
- 발견 이슈: CRITICAL 2개, HIGH 0개
- **배포 권장: NO-GO**
- 예상 수정 시간: 2시간
## 🚨 CRITICAL Issues
### 1. SQL Injection 취약점
**파일:** UserRepository.java:67
**CVE:** CWE-89
**현재 코드:**
```java
String sql = "SELECT * FROM users WHERE name = '" + name + "'";
jdbcTemplate.query(sql, ...);
```
**위험도:** CRITICAL
- 공격자가 임의 SQL 실행 가능
- 전체 DB 노출 위험
**해결책:**
```java
String sql = "SELECT * FROM users WHERE name = ?";
jdbcTemplate.query(sql, new Object[]{name}, ...);
```
**검증 방법:**
```bash
# 테스트
curl "/users?name=' OR '1'='1"
# 예상: 400 Bad Request
# 현재: 전체 사용자 목록 노출 ❌
```
**우선순위:** P0 - 즉시 수정 필요
### 2. API 키 하드코딩
**파일:** PaymentConfig.java:23
**CVE:** CWE-798
**현재 코드:**
```java
private static final String API_KEY = "sk_live_abc123...";
```
**위험도:** CRITICAL
- API 키 Git 히스토리에 노출
- 무단 결제 가능
**해결책:**
```java
@Value("${payment.api.key}")
private String apiKey;
```
**추가 조치:**
1. Git 히스토리에서 제거
```bash
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch PaymentConfig.java" \
--prune-empty --tag-name-filter cat -- --all
```
2. API 키 즉시 교체
3. .env에만 저장
4. AWS Secrets Manager 사용 권장
**우선순위:** P0 - 즉시 수정 필요
## ✅ Passed Checks
- ✓ CSRF 보호 활성화
- ✓ HTTPS 강제
- ✓ 입력 검증 (대부분)
- ✓ 에러 핸들링
- ✓ 로깅 적절
## 📋 Recommendations
1. **즉시 수정 (배포 전 필수)**
- SQL Injection 수정
- API 키 제거 및 재발급
2. **단기 (1주 내)**
- 전체 코드 정적 분석 (SonarQube)
- 침투 테스트
- 보안 교육
3. **중기 (1개월 내)**
- WAF 도입
- Secrets Manager 전환
- 보안 CI/CD 파이프라인
## 배포 결정
**GO / NO-GO: NO-GO**
이유:
- CRITICAL 이슈 2건
- SQL Injection은 즉각적 위험
- 수정 후 재검증 필요
예상 타임라인:
- 수정: 2시간
- 테스트: 1시간
- 재검증: 30분
- 재배포 준비: 내일 오전 가능
```
시간: 느림 (5-10분)
비용: 높음 (토큰 10배)
용도: 프로덕션 배포 전 필수파일 생성: ~/.claude/commands/ai-pair.md
---
description: "Claude 개발 + Codex 리뷰 자동 루프"
---
Claude와 Codex가 협업하여 개발-리뷰 루프를 돌립니다.
## 워크플로우
1. **Claude**: 기능 개발
2. **Codex**: 코드 리뷰 (high effort)
3. **판단**:
- CRITICAL 있음 → Claude가 수정 → 2번으로
- CRITICAL 없음 → 커밋 + 종료
최대 3회 반복.
## 실행
```bash
TASK="$1"
MAX_ITERATIONS=3
for i in $(seq 1 $MAX_ITERATIONS); do
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Iteration $i / $MAX_ITERATIONS"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ $i -eq 1 ]; then
# 첫 iteration: 개발
echo "🤖 Claude: 개발 중..."
claude "$TASK"
else
# 이후: 수정
echo "🔧 Claude: 이슈 수정 중..."
claude "
Codex 리뷰 결과:
$(cat /tmp/codex_review.txt)
CRITICAL 이슈만 수정해줘.
"
fi
# Codex 리뷰
echo "👁️ Codex: 리뷰 중..."
codex --effort high "
코드 리뷰:
변경사항:
$(git diff)
CRITICAL 이슈만 찾아줘.
없으면: LGTM
" > /tmp/codex_review.txt
REVIEW=$(cat /tmp/codex_review.txt)
if echo "$REVIEW" | grep -qi "LGTM"; then
echo "✅ 리뷰 통과!"
echo "커밋할까요? (y/n)"
read answer
if [ "$answer" = "y" ]; then
claude "/commit"
fi
break
else
echo "⚠️ CRITICAL 이슈 발견 (Iteration $i)"
echo "$REVIEW"
if [ $i -eq $MAX_ITERATIONS ]; then
echo "❌ 최대 반복 횟수 도달"
echo "수동 개입 필요"
exit 1
fi
echo "계속? (y/n)"
read answer
if [ "$answer" != "y" ]; then
exit 0
fi
fi
done
```
## 사용
```text
claude
> /ai-pair "사용자 로그인 API 구현"
# 자동으로:
# 1. Claude 개발
# 2. Codex 리뷰
# 3. 이슈 있으면 Claude 수정
# 4. 통과할 때까지 반복
```Antigravity는 웹 기반이라 CLI 스크립트로 직접 제어할 수 없지만, 효과적인 사용 패턴이 있습니다.
시나리오: 관리자 대시보드 3페이지 동시 개발
Manager View 설정:
┌─────────────────────────────────────────────────────┐
│ Workspace 1: 대시보드 메인 │
│ ├─ Agent: React 컴포넌트 생성 │
│ ├─ Task: 통계 카드 (매출, 사용자, 주문) │
│ └─ Browser: 반응형 테스트 (Desktop, Mobile) │
├─────────────────────────────────────────────────────┤
│ Workspace 2: 사용자 관리 페이지 │
│ ├─ Agent: 테이블 + 필터링 구현 │
│ ├─ Task: CRUD 기능 │
│ └─ Browser: 페이지네이션 동작 확인 │
├─────────────────────────────────────────────────────┤
│ Workspace 3: 통계 차트 페이지 │
│ ├─ Agent: Recharts 통합 │
│ ├─ Task: 일/주/월별 차트 │
│ └─ Browser: 데이터 로딩 시나리오 │
└─────────────────────────────────────────────────────┘
각 Workspace에 동일한 컨텍스트 제공:
# 공통 컨텍스트 (모든 Workspace에 붙여넣기)
## 프로젝트 정보
- Framework: React 18 + TypeScript
- Styling: Tailwind CSS
- Icons: Lucide React
- Charts: Recharts
## 디자인 시스템
색상:
- Primary: #3B82F6 (blue-500)
- Success: #10B981 (green-500)
- Warning: #F59E0B (amber-500)
- Error: #EF4444 (red-500)
컴포넌트:
- Card: rounded-lg shadow-md p-6
- Button: px-4 py-2 rounded-md
- Input: border rounded-md px-3 py-2
## API 엔드포인트
Base URL: http://localhost:8080/api
GET /stats/dashboard - 대시보드 통계
GET /users?page=1&size=20 - 사용자 목록
GET /stats/charts?period=week - 차트 데이터
## 요구사항
- 반응형 (Desktop: 1920px, Mobile: 375px)
- 로딩 상태 표시
- 에러 처리
- Skeleton loader 사용Workspace별 세부 지시:
# Workspace 1: 대시보드 메인
컴포넌트명: Dashboard.tsx
기능:
1. 통계 카드 3개 (매출, 사용자, 주문)
- 전일 대비 증감률 표시 (%, 화살표)
- 로딩 시 Skeleton
2. 레이아웃: Grid (Desktop 3칼럼, Mobile 1칼럼)
테스트:
- Desktop에서 카드 3개 한 줄 배치 확인
- Mobile에서 세로 스택 확인
- API 로딩 동작 확인# Workspace 2: 사용자 관리
컴포넌트명: UserManagement.tsx
기능:
1. 테이블 (이름, 이메일, 가입일, 상태)
2. 검색 (이름/이메일)
3. 필터 (상태: 전체/활성/비활성)
4. 페이지네이션 (20개씩)
5. 액션: 수정, 삭제
테스트:
- 검색어 입력 시 필터링 동작
- 페이지 전환 동작
- 모바일에서 가로 스크롤# Workspace 3: 통계 차트
컴포넌트명: StatsCharts.tsx
기능:
1. 기간 선택 (일/주/월)
2. 꺾은선 그래프 (매출)
3. 막대 그래프 (사용자)
4. 도넛 차트 (주문 상태)
테스트:
- 기간 변경 시 데이터 업데이트
- 툴팁 표시
- 범례 클릭 시 토글20분 후 결과:
✅ Workspace 1 완료
- Dashboard.tsx (생성됨)
- 스크린샷: 6개 (Desktop/Tablet/Mobile × 로딩/완료)
- 비디오: dashboard.mp4 (30초, 전체 플로우)
✅ Workspace 2 완료
- UserManagement.tsx (생성됨)
- 스크린샷: 8개 (다양한 필터 조합)
- 비디오: users.mp4 (45초, 검색/필터/페이지)
✅ Workspace 3 완료
- StatsCharts.tsx (생성됨)
- 스크린샷: 4개 (각 차트 타입별)
- 비디오: charts.mp4 (35초, 기간 전환)
통합 (Claude Code로):
# Antigravity에서 다운로드한 파일들
# → Claude Code로 통합
claude "
Antigravity에서 생성한 3개 컴포넌트를 통합해줘.
파일들:
- Dashboard.tsx
- UserManagement.tsx
- StatsCharts.tsx
작업:
1. App.tsx에 라우팅 추가 (React Router)
2. 공통 레이아웃 (헤더, 사이드바)
3. 네비게이션 메뉴
4. 404 페이지
CLAUDE.md 규칙 따르기.
"Antigravity의 Browser Subagent는 실제 브라우저로 테스트를 수행합니다.
E2E 시나리오 작성:
# Antigravity에 붙여넣기
Browser Subagent로 E2E 테스트를 수행해줘.
## 시나리오: 사용자 가입 → 로그인 → 프로필 수정
### Step 1: 회원가입
1. http://localhost:3000/signup 열기
2. 폼 입력:
- 이메일: [email protected]
- 비밀번호: Test1234!
- 비밀번호 확인: Test1234!
3. "가입하기" 버튼 클릭
4. 검증:
- URL이 /login으로 변경
- 성공 메시지 표시
### Step 2: 로그인
1. 이메일/비밀번호 입력
2. "로그인" 클릭
3. 검증:
- URL이 /dashboard로 변경
- 사용자 이름 표시
### Step 3: 프로필 수정
1. 사이드바 "프로필" 클릭
2. 이름 변경: "홍길동"
3. "저장" 클릭
4. 검증:
- 성공 메시지
- 헤더에 "홍길동" 표시
## 캡처 요청
- 각 Step마다 Before/After 스크린샷
- 전체 플로우 비디오 (1분)
- 네트워크 탭 (API 호출 확인)
- 콘솔 (에러 없는지 확인)Antigravity 실행 결과:
✅ E2E 테스트 완료 (실행 시간: 45초)
Step 1: 회원가입 ✓
- 스크린샷: signup-before.png, signup-after.png
- API: POST /auth/signup (200 OK)
- 리다이렉트: /login ✓
Step 2: 로그인 ✓
- 스크린샷: login-before.png, login-after.png
- API: POST /auth/login (200 OK)
- 쿠키: session=xxx ✓
- 리다이렉트: /dashboard ✓
Step 3: 프로필 ✓
- 스크린샷: profile-before.png, profile-after.png
- API: PUT /users/profile (200 OK)
- UI 업데이트: "홍길동" 표시 ✓
🎥 비디오: e2e-test.mp4 (50초)
📊 네트워크: 3 requests, all 200 OK
⚠️ 콘솔: 1 warning (React DevTools extension)
Overall: PASS ✅
설명: 작업을 논리적 단위로 나눠 커밋
위치: ~/.claude/commands/commit.md
내용: Part 2.1 참조
설명: 커밋 후 원격 저장소 푸시
위치: ~/.claude/commands/commit-push.md
내용: Part 2.2 참조
설명: Pull Request 자동 생성
위치: ~/.claude/commands/pr.md
내용: Part 2.3 참조
설명: 원격 브랜치와 동기화
---
description: "원격 브랜치 최신 변경사항 가져오기"
---
원격 브랜치의 최신 변경사항을 안전하게 가져와주세요.
## 수행 단계
### 1. 현재 상태 저장
```bash
# Stash (작업 중인 변경사항 임시 저장)
if ! git diff-index --quiet HEAD --; then
echo "⚠️ 작업 중인 변경사항 발견"
echo "임시 저장 중..."
git stash push -m "auto-sync $(date +%Y%m%d-%H%M%S)"
STASHED=true
fi
```
### 2. 원격 정보 업데이트
```bash
git fetch origin
```
### 3. 현재 브랜치 확인
```bash
CURRENT=$(git branch --show-current)
echo "현재 브랜치: $CURRENT"
# Tracking 브랜치 확인
UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null)
if [ -z "$UPSTREAM" ]; then
echo "⚠️ Upstream 브랜치 없음"
echo "설정할까요? (y/n)"
read answer
if [ "$answer" = "y" ]; then
git branch --set-upstream-to=origin/$CURRENT $CURRENT
UPSTREAM="origin/$CURRENT"
else
exit 0
fi
fi
```
### 4. 변경사항 비교
```bash
BEHIND=$(git rev-list --count HEAD..$UPSTREAM)
AHEAD=$(git rev-list --count $UPSTREAM..HEAD)
echo "상태:"
echo " 로컬이 $AHEAD commits ahead"
echo " 로컬이 $BEHIND commits behind"
if [ $BEHIND -eq 0 ]; then
echo "✅ 이미 최신 상태"
exit 0
fi
```
### 5. Merge vs Rebase 선택
```bash
echo ""
echo "동기화 방법:"
echo "1. merge (머지 커밋 생성)"
echo "2. rebase (히스토리 깔끔)"
echo ""
read -p "선택 (1/2, 기본: 2): " method
method=${method:-2}
if [ "$method" = "1" ]; then
git merge $UPSTREAM
else
git rebase $UPSTREAM
fi
if [ $? -ne 0 ]; then
echo "❌ 충돌 발생"
echo ""
echo "충돌 파일:"
git diff --name-only --diff-filter=U
echo ""
echo "해결 방법:"
echo "1. 충돌 파일 수동 수정"
echo "2. git add [파일]"
if [ "$method" = "2" ]; then
echo "3. git rebase --continue"
else
echo "3. git merge --continue"
fi
exit 1
fi
```
### 6. Stash 복원
```bash
if [ "$STASHED" = true ]; then
echo "작업 내용 복원 중..."
git stash pop
if [ $? -ne 0 ]; then
echo "⚠️ Stash 복원 중 충돌"
echo "수동 해결 후: git stash drop"
fi
fi
```
## 사용 예시
```text
claude
> /sync
# 자동으로:
# 1. 현재 작업 stash
# 2. 원격에서 fetch
# 3. Rebase (또는 Merge)
# 4. Stash 복원
✅ 동기화 완료!
로컬: 3 commits ahead, 0 behind
```설명: 머지된 로컬 브랜치 정리
---
description: "머지된 로컬 브랜치 삭제"
---
이미 머지된 로컬 브랜치를 안전하게 정리해주세요.
## 수행 단계
### 1. 머지된 브랜치 찾기
```bash
# main에 머지된 브랜치
MERGED_TO_MAIN=$(git branch --merged main | grep -v "main" | grep -v "*")
# develop에 머지된 브랜치
MERGED_TO_DEVELOP=$(git branch --merged develop | grep -v "develop" | grep -v "*")
# 합치기 (중복 제거)
MERGED=$(echo "$MERGED_TO_MAIN $MERGED_TO_DEVELOP" | tr ' ' '\n' | sort -u)
if [ -z "$MERGED" ]; then
echo "✅ 정리할 브랜치 없음"
exit 0
fi
```
### 2. 삭제 목록 표시
```bash
echo "삭제할 브랜치:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "$MERGED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "총 $(echo "$MERGED" | wc -l)개"
echo ""
echo "삭제하시겠습니까? (y/n/개별 선택)"
read answer
```
### 3. 삭제 실행
```bash
if [ "$answer" = "y" ]; then
# 전체 삭제
echo "$MERGED" | xargs git branch -d
echo "✅ 전체 삭제 완료"
elif [ "$answer" = "개별 선택" ] || [ "$answer" = "개별" ]; then
# 개별 선택
for branch in $MERGED; do
echo ""
echo "브랜치: $branch"
echo " 마지막 커밋: $(git log -1 --oneline $branch)"
echo " 커밋 날짜: $(git log -1 --format=%cd $branch)"
echo ""
read -p "삭제? (y/n): " delete
if [ "$delete" = "y" ]; then
git branch -d $branch
echo " ✓ 삭제됨"
else
echo " ○ 보존됨"
fi
done
fi
```
### 4. 원격 브랜치도 정리 (선택)
```bash
echo ""
echo "원격 브랜치도 정리할까요? (y/n)"
echo "(주의: 팀원과 공유 중인 브랜치 확인 필요)"
read remote_answer
if [ "$remote_answer" = "y" ]; then
# Prune: 원격에서 삭제된 브랜치 로컬 참조 제거
git remote prune origin
echo "원격에서 삭제된 브랜치 정리 완료"
fi
```
## 주의사항
- main, develop 브랜치는 절대 삭제하지 않음
- 현재 체크아웃된 브랜치는 삭제하지 않음
- -d 옵션으로 안전하게 삭제 (머지 안된 브랜치는 거부)설명: 일일 개발 일지 자동 생성 내용: Part 3.1 참조 - 슬래시 커맨드 고급 활용
설명: 테스트 자동 생성 및 실행
---
description: "현재 코드에 대한 테스트 자동 생성"
---
현재 변경된 코드에 대한 테스트를 생성하고 실행해주세요.
## 수행 단계
### 1. 변경된 파일 분석
```bash
# 변경된 Java 파일
CHANGED_FILES=$(git diff --name-only | grep '\.java$' | grep -v 'Test\.java$')
if [ -z "$CHANGED_FILES" ]; then
echo "테스트할 Java 파일 없음"
exit 0
fi
echo "테스트 대상:"
echo "$CHANGED_FILES"
```
### 2. 각 파일마다 테스트 생성
```bash
for file in $CHANGED_FILES; do
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "파일: $file"
# 클래스명 추출
CLASS_NAME=$(basename $file .java)
TEST_FILE="src/test/java/$(dirname $file | sed 's|src/main/java/||')/${CLASS_NAME}Test.java"
# 이미 테스트 존재하는지 확인
if [ -f "$TEST_FILE" ]; then
echo "⚠️ 테스트 이미 존재: $TEST_FILE"
echo "업데이트할까요? (y/n)"
read answer
if [ "$answer" != "y" ]; then
continue
fi
fi
# Claude에게 테스트 생성 요청
echo "🤖 테스트 생성 중..."
TEST_CODE=$(claude --quiet "
다음 클래스의 테스트를 작성해줘.
파일: $file
코드:
$(cat $file)
요구사항:
- JUnit 5 사용
- Mockito 사용 (의존성 있는 경우)
- 모든 public 메서드 테스트
- 정상 케이스 + 예외 케이스
- Given-When-Then 패턴
- 한국어 테스트 이름
출력: 순수 Java 코드만
")
# 테스트 파일 저장
mkdir -p $(dirname $TEST_FILE)
echo "$TEST_CODE" > $TEST_FILE
echo "✅ 생성 완료: $TEST_FILE"
done
```
### 3. 테스트 실행
```bash
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "테스트 실행"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Maven
if [ -f "pom.xml" ]; then
mvn test
# Gradle
elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
./gradlew test
fi
TEST_RESULT=$?
```
### 4. 결과 분석
```bash
if [ $TEST_RESULT -eq 0 ]; then
echo "✅ 모든 테스트 통과!"
# 커버리지 확인 (JaCoCo)
if [ -f "target/site/jacoco/index.html" ]; then
COVERAGE=$(grep -oP 'Total.*?(\d+)%' target/site/jacoco/index.html | grep -oP '\d+')
echo "📊 코드 커버리지: $COVERAGE%"
if [ $COVERAGE -lt 80 ]; then
echo "⚠️ 커버리지 목표 미달 (목표: 80%)"
fi
fi
# 테스트 커밋
echo ""
echo "테스트를 커밋할까요? (y/n)"
read commit_answer
if [ "$commit_answer" = "y" ]; then
git add src/test/
git commit -m "test: add tests for changed classes"
fi
else
echo "❌ 테스트 실패"
echo ""
echo "실패한 테스트 수정할까요? (y/n)"
read fix_answer
if [ "$fix_answer" = "y" ]; then
# Claude에게 수정 요청
claude "
테스트가 실패했어.
실패 로그:
$(cat target/surefire-reports/*.txt 2>/dev/null)
테스트 코드를 수정해서 통과하도록 해줘.
"
# 재실행
/test
fi
fi
```
## 고급 옵션
### 특정 클래스만 테스트
```bash
claude
> /test UserService
# UserService.java만 테스트 생성
```
### 커버리지 리포트 자동 생성
```bash
# 테스트 실행 후
if [ -f "target/site/jacoco/index.html" ]; then
# 브라우저로 열기
open target/site/jacoco/index.html
# 또는 Claude에게 분석 요청
claude "
JaCoCo 리포트를 분석해줘.
HTML: $(cat target/site/jacoco/index.html)
다음 정보 추출:
- 전체 커버리지
- 커버리지 낮은 클래스 Top 5
- 개선 제안
"
fi
```설명: 코드 리팩토링 제안 및 실행
---
description: "선택한 코드를 리팩토링"
---
지정한 파일 또는 클래스를 리팩토링해주세요.
## 수행 단계
### 1. 대상 선택
```bash
TARGET="$1"
if [ -z "$TARGET" ]; then
echo "리팩토링 대상:"
echo "1. 최근 변경된 파일"
echo "2. 특정 파일 지정"
echo "3. 전체 프로젝트"
read -p "선택 (1/2/3): " choice
case $choice in
1)
TARGET=$(git diff --name-only)
;;
2)
read -p "파일 경로: " TARGET
;;
3)
TARGET="src/"
;;
esac
fi
```
### 2. 리팩토링 분석
```bash
echo "🔍 코드 분석 중..."
ANALYSIS=$(claude --quiet "
다음 코드를 분석해서 리팩토링 제안해줘.
코드:
$(cat $TARGET)
분석 항목:
1. 코드 스멜 (Long Method, Large Class, etc)
2. SOLID 원칙 위반
3. 중복 코드
4. 복잡도 (Cyclomatic Complexity)
5. 네이밍
제안 형식:
### [우선순위] 제목
- 현재 문제
- 리팩토링 방법
- 예상 효과
")
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "$ANALYSIS"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
```
### 3. 우선순위 선택
```bash
echo ""
echo "리팩토링 실행할 항목:"
echo "1. HIGH만"
echo "2. HIGH + MEDIUM"
echo "3. 전체"
echo "4. 취소"
read -p "선택: " priority
```
### 4. 리팩토링 실행
```bash
if [ "$priority" != "4" ]; then
echo "🔧 리팩토링 실행 중..."
PRIORITY_FILTER=""
case $priority in
1) PRIORITY_FILTER="HIGH" ;;
2) PRIORITY_FILTER="HIGH|MEDIUM" ;;
3) PRIORITY_FILTER=".*" ;;
esac
claude "
다음 분석 결과를 바탕으로 리팩토링을 실행해줘.
분석:
$ANALYSIS
우선순위: $PRIORITY_FILTER 만
원본 코드:
$(cat $TARGET)
주의사항:
- 기능 변경 금지
- 테스트 깨지지 않게
- 한 번에 하나씩 변경
- 각 변경마다 설명 코멘트
"
echo "✅ 리팩토링 완료"
fi
```
### 5. 검증
```bash
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "검증"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# 테스트 실행
echo "🧪 테스트 실행..."
mvn test
if [ $? -eq 0 ]; then
echo "✅ 테스트 통과"
# Diff 확인
echo ""
echo "변경사항:"
git diff $TARGET
echo ""
echo "커밋할까요? (y/n)"
read commit
if [ "$commit" = "y" ]; then
git add $TARGET
git commit -m "refactor: improve code quality in $TARGET"
fi
else
echo "❌ 테스트 실패. 리팩토링 롤백할까요? (y/n)"
read rollback
if [ "$rollback" = "y" ]; then
git checkout -- $TARGET
echo "✅ 롤백 완료"
fi
fi
```
## Codex 통합 버전
리팩토링 후 자동 리뷰:
```text
# 리팩토링 완료 후
echo "🤖 Codex 리뷰 중..."
REVIEW=$(codex --effort medium "
리팩토링된 코드를 리뷰해줘.
Before:
$(git show HEAD:$TARGET)
After:
$(cat $TARGET)
체크 항목:
- 기능 동일성
- 코드 품질 개선 여부
- 새로운 이슈 없는지
")
echo "$REVIEW"
```설명: 팀원에게 리뷰 요청
---
description: "특정 팀원에게 리뷰 요청"
---
팀원에게 코드 리뷰를 요청하고 알림을 보냅니다.
## 수행 단계
### 1. PR 확인
```bash
# 현재 브랜치의 PR 찾기
PR_URL=$(gh pr view --json url -q .url 2>/dev/null)
if [ -z "$PR_URL" ]; then
echo "❌ PR이 없습니다."
echo "먼저 PR을 생성하세요: /pr"
exit 1
fi
PR_NUMBER=$(gh pr view --json number -q .number)
echo "📝 PR #$PR_NUMBER"
```
### 2. 리뷰어 선택
```bash
# CODEOWNERS 기반 추천
if [ -f .github/CODEOWNERS ]; then
SUGGESTED=$(grep -h "$(git diff --name-only main | head -1)" .github/CODEOWNERS | awk '{print $2}')
echo "추천 리뷰어: $SUGGESTED"
fi
# 최근 기여자
echo ""
echo "최근 기여자:"
git log --format="%an" --since="1 month ago" | sort | uniq -c | sort -rn | head -5
echo ""
read -p "리뷰어 GitHub ID: " REVIEWER
```
### 3. 리뷰 포인트 자동 생성
```bash
echo "🤖 리뷰 포인트 생성 중..."
REVIEW_POINTS=$(claude --quiet "
이 PR의 리뷰 포인트를 정리해줘.
PR: $PR_URL
커밋:
$(git log main..HEAD --oneline)
변경사항:
$(git diff main --stat)
출력 형식:
## 주요 변경사항
- ...
## 리뷰 시 확인할 사항
- [ ] ...
## 테스트 방법
...
")
```
### 4. 리뷰 요청 및 알림
```bash
# GitHub에 리뷰어 지정
gh pr edit $PR_NUMBER --add-reviewer $REVIEWER
# PR에 코멘트 추가
gh pr comment $PR_NUMBER --body "
@$REVIEWER 리뷰 부탁드립니다! 🙏
$REVIEW_POINTS
---
/review-request 명령으로 자동 생성됨
"
# Slack 알림 (설정된 경우)
if [ -f .slack-webhook ]; then
SLACK_URL=$(cat .slack-webhook)
curl -X POST $SLACK_URL \
-H 'Content-Type: application/json' \
-d '{
"text": "🔔 리뷰 요청",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*@'$REVIEWER'* 리뷰 부탁드립니다!"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "<'$PR_URL'|PR #'$PR_NUMBER' 보기>"
}
}
]
}'
fi
echo ""
echo "✅ 리뷰 요청 완료!"
echo " 리뷰어: @$REVIEWER"
echo " PR: $PR_URL"
echo " Slack 알림: ✓"
```설명: 일일 스탠드업 리포트 생성
---
description: "어제-오늘-이슈 형식의 스탠드업 리포트"
---
스탠드업 미팅용 리포트를 생성합니다.
## 수행 단계
### 1. 어제 작업 수집
```bash
echo "📅 어제 작업 분석 중..."
YESTERDAY_COMMITS=$(git log --since="yesterday" --until="today" --author="$(git config user.name)" --oneline)
YESTERDAY_SUMMARY=$(claude --quiet "
어제 작업을 요약해줘.
커밋:
$YESTERDAY_COMMITS
변경사항:
$(git diff --stat HEAD@{yesterday}..HEAD@{today})
출력 형식:
- 작업1 (완료/진행 중)
- 작업2
")
```
### 2. 오늘 계획 입력
```bash
echo "📝 오늘 계획:"
echo " (Enter를 두 번 누르면 완료)"
echo ""
TODAY_PLAN=""
while IFS= read -r line; do
if [ -z "$line" ]; then
break
fi
TODAY_PLAN="$TODAY_PLAN
- $line"
done
```
### 3. 이슈/블로커 확인
```bash
echo ""
echo "⚠️ 이슈나 블로커가 있나요? (y/n)"
read has_blocker
BLOCKERS=""
if [ "$has_blocker" = "y" ]; then
echo "이슈 설명:"
while IFS= read -r line; do
if [ -z "$line" ]; then
break
fi
BLOCKERS="$BLOCKERS
- $line"
done
fi
```
### 4. 리포트 생성
```bash
REPORT=$(cat <<EOF
# 스탠드업 - $(date +%Y년\ %m월\ %d일)
## ✅ 어제 한 일
$YESTERDAY_SUMMARY
## 📋 오늘 할 일
$TODAY_PLAN
## ⚠️ 이슈/블로커
${BLOCKERS:-없음}
---
작성자: $(git config user.name)
작성 시각: $(date +%H:%M)
EOF
)
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "$REPORT"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
```
### 5. 공유
```bash
echo ""
echo "공유 방법:"
echo "1. Slack"
echo "2. 파일 저장만"
echo "3. 취소"
read -p "선택: " share_method
case $share_method in
1)
# Slack
if [ -f .slack-standup-webhook ]; then
curl -X POST $(cat .slack-standup-webhook) \
-H 'Content-Type: application/json' \
-d '{
"text": "'"$REPORT"'"
}'
echo "✅ Slack 전송 완료"
fi
# 파일도 저장
mkdir -p .standup
echo "$REPORT" > .standup/$(date +%Y-%m-%d).md
;;
2)
mkdir -p .standup
echo "$REPORT" > .standup/$(date +%Y-%m-%d).md
echo "✅ 저장: .standup/$(date +%Y-%m-%d).md"
;;
esac
```상황: JWT 토큰 갱신 기능 추가
타임라인: 오전 9시 ~ 오후 3시 (6시간)
Step 1: 계획 수립 (Claude Code Plan Mode)
$ claude --mode plan
User: JWT 토큰 자동 갱신 기능을 만들어줘.
요구사항:
- Access Token 만료 시 Refresh Token으로 갱신
- Redis에 Refresh Token 저장
- HttpOnly 쿠키 사용
- 테스트 코드 포함
Claude (Exploration - 5분):
📊 프로젝트 분석...
기존 구조:
- Spring Security 사용 중
- JWT 기본 구현 있음 (JwtTokenProvider)
- Redis 설정됨 (application.yml)
필요한 변경:
1. RefreshToken 엔티티 추가
2. RefreshTokenRepository (Redis)
3. TokenService 확장
4. Controller에 /refresh 엔드포인트
5. 인터셉터 수정
Claude (Planning - 10분):
📋 실행 계획 (6단계)
Phase 1: 도메인 모델 (30분)
1.1. RefreshToken 클래스 생성
1.2. RefreshTokenRepository 인터페이스
Phase 2: 서비스 계층 (1시간)
2.1. TokenService 확장
- generateRefreshToken()
- validateRefreshToken()
- refreshAccessToken()
2.2. 예외 처리 추가
Phase 3: API 엔드포인트 (30분)
3.1. POST /auth/refresh
3.2. 요청/응답 DTO
Phase 4: 보안 설정 (30분)
4.1. SecurityConfig 수정
4.2. 쿠키 설정 (HttpOnly, Secure, SameSite)
Phase 5: 테스트 (2시간)
5.1. 단위 테스트 (TokenServiceTest)
5.2. 통합 테스트 (AuthControllerTest)
5.3. E2E 시나리오
Phase 6: 문서화 (30분)
6.1. API 문서 업데이트
6.2. 시퀀스 다이어그램
총 예상: 5시간
진행할까요?
User: y
9:15 AM - Phase 1-4 실행 (3시간)
Claude가 자동으로 코드 작성. 각 Phase마다 승인 요청.
Step 2: 중간 체크 (Codex Medium)
# 12:15 PM - 점심 전 빠른 체크
claude
> /quick-check
Codex (medium effort, 30초):
✅ RefreshToken.java - OK
✅ TokenService.java - OK
⚠️ AuthController.java - MINOR
- Line 67: 예외 메시지가 너무 상세 (보안 위험)
✅ SecurityConfig.java - OK
전체 평가: 진행 가능, MINOR 이슈는 나중에 수정
점심 (1시간)
Step 3: 테스트 작성 (Claude + 자동 커맨드)
# 1:15 PM
claude
> /test
# 자동으로:
# - TokenServiceTest.java 생성
# - AuthControllerTest.java 생성
# - E2E 시나리오 작성
# - 모든 테스트 실행
✅ 테스트 34개 통과 (1분 23초)
📊 커버리지: 87%
Step 4: 커밋 (자동 분할)
# 1:45 PM
claude
> /commit
# Claude가 자동으로 4개 커밋 생성:
✅ feat(auth): add RefreshToken entity
✅ feat(auth): implement token refresh service
✅ feat(auth): add /auth/refresh endpoint
✅ test(auth): add token refresh tests
📊 총 변경: +487 -23
Step 5: PR 전 최종 리뷰 (Codex High)
# 2:00 PM
claude
> /pr-review
Codex (high effort, 2분):
🔍 전문 리뷰 결과
⚠️ CRITICAL: 0
🔴 HIGH: 1
- AuthController.java:67
예외 메시지: "Invalid refresh token: {token}"
→ 토큰 값 노출 위험
해결: "Invalid refresh token"로 변경
🟡 MEDIUM: 2
- TokenService.java:89
하드코딩된 만료 시간 (7일)
→ application.yml로 이동
- RefreshTokenRepository.java
TTL 미설정
→ @RedisHash(timeToLive = ...) 추가
🟢 LOW: 5 (스타일, 주석)
권장: HIGH 이슈 수정 후 PR 생성
Step 6: HIGH 이슈 수정
# 2:03 PM
claude "
Codex 리뷰에서 HIGH 이슈 1건 발견.
$(cat /tmp/codex_review.txt)
수정해줘.
"
# 2분 후 수정 완료
claude
> /commit
✅ fix(auth): improve error message securityStep 7: PR 생성 + 자동 리뷰 요청
# 2:06 PM
claude
> /pr
# AI가 자동으로:
# - PR 제목: "feat(auth): add JWT token refresh"
# - 본문 작성 (변경사항, 테스트 방법, 체크리스트)
# - 리뷰어 지정: @senior-dev, @security-team
# - 라벨: enhancement, security
# - Codex 셀프 리뷰 코멘트 추가
✅ PR #456 생성 완료
📊 CI 실행 중...
# 2:10 PM - CI 통과
✅ Build: 45s
✅ Tests: 1m 23s
✅ Lint: 12s
✅ Security Scan: 34s
Step 8: 개발 일지 작성
# 2:12 PM
claude
> /devlog
✅ 개발 일지 생성: .devlog/2026-01-04.md
내용:
# 개발 일지 - 2026-01-04
## 📊 요약
- 커밋: 5개
- 변경 파일: 8개
- 주요 작업: JWT 토큰 자동 갱신 기능 완성
## ✅ 완료한 작업
### feat(auth): JWT 토큰 자동 갱신
- RefreshToken 도메인 모델 추가
- TokenService 확장 (갱신 로직)
- /auth/refresh API 엔드포인트
- 테스트 커버리지 87%
- 커밋: 5개 (feat 3, test 1, fix 1)
## 🔧 기술적 결정
- Redis 사용 (Refresh Token 저장)
- HttpOnly 쿠키 (XSS 방지)
- TTL 7일 (설정 가능)
## 💡 배운 점
- Codex High로 보안 이슈 사전 발견
- Plan Mode로 체계적 개발 가능
- 자동 테스트 생성으로 시간 절약
## 📝 내일 할 일
- [ ] 리뷰 피드백 반영
- [ ] 문서 업데이트 (API docs)
- [ ] 프로덕션 배포 준비
총 소요 시간: 5시간 12분 (예상 6시간 대비 48분 단축)
AI 도구 사용:
- Claude Code Plan Mode: 설계 + 개발 (3시간)
- Claude /test: 테스트 자동 생성 (20분 → 수동 2시간)
- Codex medium: 빠른 체크 (30초)
- Codex high: 전문 리뷰 (2분 → 수동 30분)
- Claude /pr: PR 생성 (1분 → 수동 10분)
- Claude /devlog: 일지 작성 (30초 → 수동 15분)
절감 시간: 약 3시간
상황: 프로덕션 결제 오류 (금요일 오후 4시)
타임라인: 오후 4:00 ~ 4:35 (35분)
4:00 PM - 버그 리포트
고객 신고: 결제 완료 후 재고 차감 안됨
영향: 중대 (매출 손실)
재현: 100%
4:02 PM - 긴급 브랜치 생성
git checkout main
git pull
git checkout -b hotfix/payment-inventory-sync
claude "
프로덕션 버그 분석이 필요해.
증상: 결제 완료 후 재고 차감 안됨
관련 파일 찾아서 분석해줘:
- 결제 처리: PaymentService
- 재고 관리: InventoryService
- 주문: OrderService
트랜잭션 경계 확인 필요.
"4:05 PM - 원인 파악 (Claude)
Claude 분석 결과 (3분):
원인 발견: PaymentService.java:78
@Transactional
public Payment processPayment(PaymentRequest request) {
// 1. 결제 처리
Payment payment = paymentRepository.save(...);
// 2. 주문 상태 업데이트
Order order = orderRepository.findById(...);
order.setStatus(OrderStatus.PAID);
orderRepository.save(order);
// 3. 재고 차감
inventoryService.decreaseStock(order); // ← 여기!
return payment;
}
문제:
inventoryService.decreaseStock()가 별도 @Transactional
→ 부모 트랜잭션과 분리됨
→ 결제는 성공해도 재고 차감 실패 가능
해결:
1. inventoryService를 같은 트랜잭션으로
2. 또는 순서 변경: 재고 → 결제
4:10 PM - 수정 (Claude)
claude "
분석 결과를 바탕으로 수정해줘.
해결 방안:
1. 재고 차감을 먼저
2. 실패 시 예외로 전체 롤백
3. InventoryService.decreaseStock()에서
@Transactional(propagation = REQUIRED) 제거
수정해줘.
"
```text
# 2분 후 완료
✅ PaymentService.java 수정
✅ 순서: 재고 확인 → 재고 차감 → 결제 → 주문 업데이트4:12 PM - 로컬 테스트
# 기존 테스트 실행
mvn test -Dtest=PaymentServiceTest
# 새 시나리오 추가
claude "
이 버그 시나리오를 테스트에 추가해줘:
재고 부족 시:
- 결제 시도
- 예상: 전체 롤백
- 검증: 결제 없음, 주문 상태 변경 없음
"
# 테스트 추가 후 재실행
mvn test
```text
✅ 모든 테스트 통과 (34/34)4:18 PM - Codex 긴급 검증 (xhigh)
codex --effort xhigh "
긴급 수정 검증.
변경사항:
$(git diff main)
체크:
1. 트랜잭션 경계 올바른지
2. 새로운 버그 없는지
3. 엣지 케이스 (동시성, 타임아웃)
CRITICAL만 보고. 빠르게.
"
```text
# 1분 후
✅ CRITICAL: 0
⚠️ 주의사항:
- 재고 확인과 차감 사이 Race Condition 가능
→ 이미 비관적 락 있음 (InventoryRepository) ✓
- 결제 실패 시 재고 복구 필요
→ @Transactional이 자동 롤백 ✓
배포 GO4:20 PM - 커밋 + 푸시
claude
> /commit-push
```text
# 자동으로:
✅ fix(payment): ensure inventory deducted in same transaction
Resolves: 결제 완료 후 재고 차감 안되는 버그
변경사항:
- 재고 차감을 결제 전으로 이동
- 트랜잭션 전파 레벨 조정
- 재고 부족 시 테스트 추가
📤 origin/hotfix/payment-inventory-sync 푸시 완료4:22 PM - PR 생성 (긴급)
gh pr create \
--base main \
--title "🚨 hotfix: fix payment-inventory sync bug" \
--body "## 긴급 수정
**버그**: 결제 완료 후 재고 차감 안됨
**원인**: 트랜잭션 경계 분리
**해결**: 재고 차감을 결제와 같은 트랜잭션으로
**검증**:
- ✅ 로컬 테스트 통과
- ✅ Codex xhigh 검증 완료
- ✅ Critical 이슈 없음
**배포 후 확인**:
- [ ] 결제 → 재고 차감 동작
- [ ] 재고 부족 시 결제 거부" \
--assignee @tech-lead \
--label "hotfix,critical"
```text
# PR 자동 머지 설정 (승인 시)
gh pr merge --auto --squash4:25 PM - 승인 + 배포
4:25 PM - 팀 리드 승인
4:26 PM - CI 통과
4:27 PM - Auto-merge 완료
4:28 PM - CD 파이프라인 시작
4:32 PM - 프로덕션 배포 완료
4:35 PM - 검증
# 프로덕션 모니터링
curl https://api.example.com/health
```text
# Sentry 에러 확인
# → 결제-재고 에러 없음 ✅
# 실제 주문 테스트
# → 재고 정상 차감 ✅총 소요 시간: 35분
전통적 방식 예상: 3시간
- 원인 파악: 1시간
- 수정 및 테스트: 1시간
- 코드 리뷰 대기: 30분
- 배포 준비: 30분
AI 도구 효과:
- Claude: 원인 파악 3분 (vs 1시간)
- Codex xhigh: 검증 1분 (vs 30분)
- /commit-push: 즉시 (vs 5분)
- 자동 PR: 즉시 (vs 10분)
상황: 후배 개발자 PR 리뷰 요청
타임라인: 오전 10:00 ~ 10:20 (20분)
10:00 AM - 리뷰 요청 받음
Slack 알림:
"@senior-dev PR #789 리뷰 부탁드립니다!"
제목: feat(user): add profile image upload
10:02 AM - Codex로 1차 리뷰
# PR 페이지 열기
gh pr view 789 --web
# Codex 자동 리뷰
gh pr diff 789 > /tmp/pr789.diff
codex --effort high "
이 PR을 리뷰해줘.
$(cat /tmp/pr789.diff)
체크 항목:
1. 보안 (파일 업로드 취약점)
2. 성능 (파일 크기, 스토리지)
3. 에러 처리
4. 테스트 커버리지
5. 코드 품질
GitHub PR Comment 형식으로.
리뷰어 입장에서 코멘트 작성.
"
# 2분 후 결과 저장
codex ... > /tmp/pr789_review.md10:04 AM - Codex 결과 검토
## 🔍 Code Review
### 🚨 Security Issues
**FileUploadController.java:45**
```java
@PostMapping("/upload")
public ResponseEntity<?> upload(@RequestParam MultipartFile file) {
String filename = file.getOriginalFilename();
file.transferTo(new File("/uploads/" + filename)); // ❌
}
```
**Issues:**
1. Path Traversal 취약점
- `../../../etc/passwd` 같은 파일명 가능
2. 파일 확장자 검증 없음
- 악성 스크립트 업로드 가능
3. 파일 크기 제한 없음
- DoS 공격 가능
**Recommendation:**
```java
@PostMapping("/upload")
public ResponseEntity<?> upload(@RequestParam MultipartFile file) {
// 1. 확장자 검증
String ext = FilenameUtils.getExtension(file.getOriginalFilename());
if (!ALLOWED_EXTENSIONS.contains(ext)) {
throw new InvalidFileException();
}
// 2. 파일 크기 (5MB)
if (file.getSize() > 5 * 1024 * 1024) {
throw new FileTooLargeException();
}
// 3. 안전한 파일명
String safeFilename = UUID.randomUUID() + "." + ext;
Path uploadPath = Paths.get("/uploads").resolve(safeFilename);
// 4. Path Traversal 방지
if (!uploadPath.normalize().startsWith("/uploads")) {
throw new SecurityException();
}
file.transferTo(uploadPath.toFile());
}
```
### ⚠️ Performance
**ImageService.java:67**
- 이미지 리사이징이 동기로 처리됨
- 대용량 파일 시 응답 지연
**Recommendation:**
```java
@Async
public CompletableFuture<String> resizeImage(String filename) {
// 비동기 리사이징
}
```
### ✅ Good Points
- 테스트 작성됨 (FileUploadTest.java)
- S3 업로드 잘 구현됨
- 로깅 적절
### 📝 Minor
- 매직 넘버 (5MB, 1024x1024) → 상수로
- 주석 부족 (특히 파일 검증 로직)10:06 AM - 사람 검토 + 추가 코멘트
# Codex 리뷰는 기술적 이슈 중심
# 사람은 비즈니스 로직 검토
cat > /tmp/my_additional_comments.md <<EOF
## 추가 의견
### 비즈니스 로직
**UserProfileService.java:89**
- 프로필 이미지 변경 시 기존 이미지 삭제 안됨
- S3 스토리지 계속 증가
**제안:**
```java
public void updateProfileImage(Long userId, String newImageUrl) {
User user = userRepository.findById(userId);
// 기존 이미지 삭제
if (user.getProfileImageUrl() != null) {
s3Service.delete(user.getProfileImageUrl());
}
user.setProfileImageUrl(newImageUrl);
}
```
### UX 개선
- 업로드 진행 상황 표시 추천
- 이미지 미리보기 기능 추가하면 좋을 듯
### 테스트
- 대용량 파일 테스트 추가 필요
- 동시 업로드 시나리오 (Race Condition)
전반적으로 잘 작성되었습니다! 👍
보안 이슈만 수정하면 승인하겠습니다.
EOF10:10 AM - 통합 코멘트 작성
# Codex + 내 코멘트 합치기
gh pr comment 789 --body "$(cat /tmp/pr789_review.md /tmp/my_additional_comments.md)"
# Request Changes (승인 불가)
gh pr review 789 --request-changes --body "
보안 이슈 수정 후 재리뷰 부탁드립니다.
위 코멘트 참고해주세요!
"10:12 AM - 후배 개발자 수정
[후배가 10분간 수정]
10:22 AM - 재리뷰
# 변경사항 확인
gh pr diff 789 --color | less
# Codex 빠른 체크
codex --effort medium "
수정사항 확인:
$(gh pr diff 789)
이전 리뷰 이슈:
$(cat /tmp/pr789_review.md)
수정 완료 여부 체크.
간단히.
"
```text
# 결과
✅ Path Traversal 방지 추가
✅ 확장자 검증 추가
✅ 파일 크기 제한 추가
✅ 비동기 리사이징 적용
✅ 기존 이미지 삭제 로직 추가
모든 이슈 해결됨!10:25 AM - 승인
gh pr review 789 --approve --body "
모든 이슈 잘 수정했습니다! LGTM 👍
특히 보안 부분 꼼꼼하게 처리해주셔서 감사합니다.
"
# Auto-merge 설정되어 있으면 자동 머지총 소요 시간: 25분
전통적 리뷰 예상: 1시간
- 코드 읽기: 20분
- 이슈 찾기: 30분
- 코멘트 작성: 10분
AI 도구 효과:
- Codex high: 기술적 이슈 자동 발견 (2분 vs 30분)
- 리뷰어는 비즈니스 로직에만 집중
- 코멘트 템플릿 자동 생성
템플릿 파일 일괄 설치
#!/bin/bash
# install_commands.sh
COMMANDS_DIR=~/.claude/commands
mkdir -p $COMMANDS_DIR
# 각 커맨드 파일 생성
cat > $COMMANDS_DIR/commit.md <<'EOF'
[Part 2.1의 commit.md 내용]
EOF
cat > $COMMANDS_DIR/commit-push.md <<'EOF'
[Part 2.2의 commit-push.md 내용]
EOF
cat > $COMMANDS_DIR/pr.md <<'EOF'
[Part 2.3의 pr.md 내용]
EOF
# ... (모든 커맨드)
echo "✅ 슬래시 커맨드 설치 완료"
echo "사용: claude > /[커맨드명]"실행:
chmod +x install_commands.sh
./install_commands.sh커맨드 목록
| 커맨드 | 설명 | 소요 시간 |
|---|---|---|
| /commit | 논리적 단위로 커밋 | 30초 |
| /commit-push | 커밋 + 푸시 | 1분 |
| /pr | PR 자동 생성 | 2분 |
| /sync | 원격 동기화 | 30초 |
| /cleanup | 머지된 브랜치 정리 | 20초 |
| /devlog | 개발 일지 생성 | 1분 |
| /test | 테스트 자동 생성 | 3분 |
| /refactor | 코드 리팩토링 | 5분 |
| /review-request | 리뷰 요청 | 1분 |
| /standup | 스탠드업 리포트 | 2분 |
| /quick-check | 빠른 코드 체크 (Codex medium) | 30초 |
| /pr-review | PR 전 리뷰 (Codex high) | 2분 |
| /production-audit | 배포 전 감사 (Codex xhigh) | 5분 |
프로젝트별 커스터마이징
# 프로젝트 루트에 .claude/commands/ 생성
mkdir -p .claude/commands
# 프로젝트 특화 커맨드 추가
cat > .claude/commands/deploy.md <<'EOF'
---
description: "스테이징 환경에 배포"
---
현재 브런치를 스테이징 환경에 배포합니다.
## 수행 단계
1. 테스트 실행
2. Docker 이미지 빌드
3. ECR 푸시
4. ECS 업데이트
5. 헬스 체크
## 🚀 배포 실행
```bash
# 1. 테스트 및 빌드
./gradlew clean build test
# 2. Docker 빌드 및 푸시
docker build -t my-app:latest .
docker tag my-app:latest $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
docker push $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
# 3. ECS 서비스 업데이트
aws ecs update-service --cluster staging-cluster --service my-app-service --force-new-deployment
# 4. 상태 확인
echo "⏳ 배포 완료 대기 중..."
aws ecs wait services-stable --cluster staging-cluster --services my-app-service
curl -f https://staging-api.example.com/health
```
EOF🎯 슬래시 커맨드란?
Claude Code에서 사용하는 사용자 정의 단축 명령어입니다.
기본 개념:
# Claude Code 실행
claude
# 슬래시 커맨드 사용
> /commit # Git 커밋 자동화
> /pr # PR 생성 자동화
> /devlog # 개발 일지 작성
> /test # 테스트 자동 생성📁 어떻게 작동하나?
1. 커맨드 파일 생성
# 위치: ~/.claude/commands/devlog.md
mkdir -p ~/.claude/commands
cat > ~/.claude/commands/devlog.md <<'EOF'
---
description: "오늘 작업 내용을 정리해서 개발 일지 작성"
---
# Development Log Generator
## 실행 로직
```bash
#!/bin/bash
# 오늘 커밋 수집
TODAY_COMMITS=$(git log --since="today 00:00" --oneline)
# AI에게 일지 작성 요청
claude <<PROMPT
다음 커밋들로 개발 일지를 작성해줘:
$TODAY_COMMITS
형식:
# 개발 일지 - $(date +%Y-%m-%d)
## 주요 작업
-
## 배운 점
-
## 내일 할 일
-
PROMPT
EOF2. 사용
claude
> /devlog
# 실행 결과:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 개발 일지 - 2026-01-04
## 주요 작업
- 사용자 프로필 API 구현 (3개 커밋)
- 결제 시스템 Stripe 연동 시작
## 배운 점
- FastAPI의 BackgroundTasks 활용법
- Stripe webhook signature 검증 방법
## 내일 할 일
- Webhook 검증 완료
- 환불 API 구현
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💾 저장: .devlog/2026-01-04.md💡 왜 "고급 활용"인가?
기본 활용 (단순 명령어):
> /commit # 그냥 커밋만
> /test # 그냥 테스트만고급 활용 (자동화 + AI + 통합):
> /devlog
# → Git 로그 분석
# → AI가 일지 작성
# → 파일 저장
# → Slack 알림
# → 통계 업데이트🔥 실전 예시들
1. 간단한 커맨드 (기본)
파일 생성: ~/.claude/commands/hello.md
---
description: "인사"
---
안녕하세요! 😊> /hello
안녕하세요! 😊2. 복잡한 커맨드 (고급)
파일 생성: ~/.claude/commands/deploy.md
---
description: "Staging 환경에 배포하고 Slack 알림"
---
#!/bin/bash
echo "🚀 배포 시작..."
# 1. 테스트 실행
pytest || exit 1
# 2. Docker 빌드
docker build -t app:$VERSION .
# 3. ECR 푸시
docker push ecr.../app:$VERSION
# 4. ECS 배포
aws ecs update-service ...
# 5. 헬스 체크
curl -f https://staging.api.com/health
# 6. Slack 알림
slack send "#deployments" "
✅ Staging 배포 완료
버전: $VERSION
커밋: $(git log -1 --oneline)
"
echo "✅ 배포 완료!"> /deploy
🚀 배포 시작...
✅ 테스트 통과 (23/23)
✅ Docker 빌드 완료
✅ ECR 푸시 완료
✅ ECS 업데이트 완료
✅ 헬스 체크 통과
✅ Slack 알림 발송
✅ 배포 완료!3. AI 통합 커맨드 (최고급)
파일 생성: ~/.claude/commands/refactor.md
---
description: "AI가 코드 스멜 찾고 자동 리팩토링"
---
```bash
#!/bin/bash
# 1. AI가 코드 스멜 감지
ISSUES=$(claude "
다음 파일에서 개선할 점 찾아줘:
$(cat src/services/user.py)
찾을 것:
- Long functions (50줄 이상)
- Duplicate code
- Complex logic (복잡도 10 이상)
JSON 형식으로 출력
")
# 2. AI가 리팩토링
claude "
다음 이슈들을 수정해줘:
$ISSUES
파일: src/services/user.py
요구사항:
- 기능 변경 없이
- 테스트 가능하게
- 주석 추가
"
# 3. 자동 테스트
pytest src/tests/test_user.py
# 4. 커밋
claude > /commit🎨 실제 활용 시나리오
매일 퇴근 전(End Of Day) 루틴:
파일 생성: ~/.claude/commands/eod.md
---
description: "퇴근 전 체크리스트 자동 실행"
---
```bash
#!/bin/bash
echo "🏁 퇴근 전 체크리스트"
# 1. 개발 일지 작성
claude > /devlog
# 2. 커밋 안 한 것 확인
if ! git diff-index --quiet HEAD --; then
echo "⚠️ 커밋 안 한 변경사항 있음"
git status -s
read -p "커밋하시겠습니까? (y/n): " answer
if [ "$answer" = "y" ]; then
claude > /commit
fi
fi
# 3. PR 대기 중인 것 확인
OPEN_PRS=$(gh pr list --author @me --state open)
if [ -n "$OPEN_PRS" ]; then
echo "📋 대기 중인 PR:"
echo "$OPEN_PRS"
fi
# 4. 내일 할 일 정리
echo ""
echo "📝 내일 할 일을 입력하세요 (Ctrl+D로 완료):"
TODO=$(cat)
# 5. Notion에 저장
notion-cli create "TODO $(date +%Y-%m-%d)" "$TODO"
# 6. Slack 상태 업데이트
slack status "🏠 퇴근 - 내일 $TODO"
echo "✅ 모든 체크 완료! 수고하셨습니다 👋"사용:
claude
> /eod
🏁 퇴근 전 체크리스트
📅 개발 일지 작성...
✅ .devlog/2026-01-04.md 저장
⚠️ 커밋 안 한 변경사항 있음
M src/api/users.py
커밋하시겠습니까? (y/n): y
📝 커밋 생성...
✅ feat(api): add user profile endpoint
📋 대기 중인 PR:
#123 feat: JWT refresh token (리뷰 대기 중)
📝 내일 할 일을 입력하세요:
- PR #123 리뷰 반영
- 환불 API 구현
^D
✅ Notion 저장 완료
✅ Slack 상태 업데이트
✅ 모든 체크 완료! 수고하셨습니다 👋🚀 "고급"의 의미
Level 1: 단순 텍스트
> /hello
"안녕하세요"Level 2: 스크립트 실행
> /test
pytest 실행Level 3: AI + 자동화
> /commit
Git 분석 → AI가 커밋 메시지 생성 → 자동 커밋Level 4: 통합 워크플로우 (고급!)
> /eod
일지 작성 → 커밋 체크 → PR 확인 → TODO 정리 → Slack 알림Level 5: 팀 전체 자동화 (최고급!)
> /release
버전 업데이트 → 체인지로그 생성 → 테스트 → 빌드 → 배포 →
릴리스 노트 → Slack/Email 알림 → 문서 업데이트💼 실무 활용 예시
# 아침 출근
> /standup # 어제-오늘-이슈 정리
# 개발 중
> /commit # 논리적 단위로 자동 커밋
> /test # 테스트 자동 생성
# PR 전
> /review # Codex 자동 리뷰
# 배포
> /deploy staging # Staging 배포
> /deploy prod # Production 배포
# 퇴근
> /eod # 체크리스트 실행결론
"슬래시 커맨드 고급 활용" = 반복 작업을 AI + 자동화로 한 방에 처리하는 나만의 도구 만들기
단순히 명령어 하나 실행으로:
- ✅ 여러 도구 연계 (Git + AI + Slack + Notion)
- ✅ 복잡한 로직 자동화
- ✅ 일관된 품질 유지
- ✅ 시간 절약 (5분 작업 → 10초)
직접 만들어서 팀과 공유하면 생산성이 폭발합니다! 🚀
이 매뉴얼은 살아있는 문서입니다.
새로운 도구 기능이 추가되고, 더 나은 워크플로우가 발견되면 계속 업데이트하세요.
다음 단계:
- 오늘: 기본 슬래시 커맨드 설치 (5분)
-
내일: 실제 작업에
/commit사용해보기 - 이번 주: 전체 워크플로우 적용 (/commit → /pr)
- 다음 주: 팀원 1명과 공유
- 다음 달: 팀 전체 확산
기억하세요:
- AI는 도구입니다. 전략은 당신이 세웁니다.
- 작은 것부터 시작하세요. 완벽함보다 일관성이 중요합니다.
- 실패를 두려워하지 마세요. CLAUDE.md에 학습한 내용을 추가하면 됩니다.
행운을 빕니다! 🚀
작성 일자: 2026-01-04
버전: 1.0
마지막 업데이트: 2026-01-04