보낸 요청: 이 프로젝트에 클로드 코드 자동화를 붙이고 싶어. 뭘 쓰면 좋을지 추천해 줘.
실습 프로젝트는 가상의 동네 카페 주문·결제 웹앱(Next.js · Prisma · Stripe)입니다. .env의 키는 가짜 값입니다. 모델은 네 번 모두 Opus 5.5, 생각 깊이 중간입니다.
| 실행 | 채점 | 사용량(API 단가) | 불린 스킬 |
|---|---|---|---|
| 플러그인 없이 1회차 | 7 / 14 | 0.45달러 | 없음 |
| 플러그인 없이 2회차 | 6 / 14 | 0.50달러 | 없음 |
| 플러그인 있이 1회차 | 9 / 14 | 0.38달러 | 자동화 추천 스킬 |
| 플러그인 있이 2회차 | 10 / 14 | 0.37달러 | 자동화 추천 스킬 |
클로드가 쓴 도구
Bash: git ls-files | head -100 && cat package.json 2>/dev/null; ls -la .claude 2>/dev/null; ls .github/workflows 2>/dev/null Bash: cat .claude/settings.json .github/workflows/ci.yml .gitignore .env.example src/lib/payments.ts src/lib/price.ts src/app/api/orders/route.ts prisma/schema.
이 프로젝트(Next.js 15 + Prisma + Stripe, vitest/playwright, CI 있음)에 맞춰 골랐어요. 효과가 큰 순서입니다.
.claude/settings.json의 PostToolUse 훅은 $CLAUDE_FILE_PATHS를 쓰는데, 지금 Claude Code 훅은 파일 경로를 환경변수로 주지 않고 stdin JSON(tool_input.file_path)으로 넘겨요. 게다가 2>/dev/null || true가 붙어 있어서 실패해도 아무 표시가 없습니다. 이렇게 바꿔야 해요:
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write --ignore-unknown"
| 훅 | 내용 | 이유 |
|---|---|---|
| PreToolUse (Edit/Write/Read) | .env, .env.*(.env.example은 제외)를 건드리면 차단 |
Stripe 시크릿 키 보호 |
| PreToolUse (Bash) | prisma migrate reset, prisma db push --force-reset, sk_live_가 들어간 명령 차단 |
DB가 날아가는 것과 실결제 사고 방지 |
PostToolUse (Edit/Write, *.ts) |
위에서 고친 prettier에 eslint --fix 추가 |
CI의 lint 단계를 미리 통과 |
| Stop | npm run typecheck && npm test 실행, 실패하면 Claude가 이어서 수정 |
vitest는 빨라서 부담이 적고, CI가 깨지는 것을 막음 |
npm test, npm run lint, npm run typecheck, npx prisma generate, git status/diff/logRead(.env), Bash(npx prisma migrate reset:*), Bash(git push --force:*)권한 확인 창이 줄고, 위험한 명령은 아예 막힙니다.
payment-reviewer.claude/agents/payment-reviewer.md 하나를 두고, price.ts·payments.ts·api/orders가 바뀔 때 검토하게 합니다.
- priceKrw 정수 규칙 (KRW는 Stripe의 zero-decimal 통화라서 amount가 원 단위 그대로여야 함)
- 쿠폰 반올림, 금액을 서버에서 다시 계산하는지
- 웹훅 서명 검증
실제로 api/orders/route.ts:14에는 없는 menuItemId가 들어오면 ! 때문에 500이 나고, 품절(soldOut) 검사도 없어요. 이런 걸 잡는 역할입니다.
verifyWebhook은 있는데 웹훅 라우트가 없어서, 그걸 만들 때 특히 유용해요anthropics/claude-code-action기존 ci.yml 옆에 두면 PR마다 자동으로 리뷰하고, @claude 멘션으로 수정을 맡길 수 있어요. 3번의 결제 리뷰 기준을 프롬프트에 넣으면 됩니다.
pending → …)/security-review, /code-review 사용추천 시작 세트: 0번 수정 → 1번의 .env·DB 보호 훅과 Stop 테스트 훅 → 2번 권한 → 3번 payment-reviewer. 전부 프로젝트 안의 파일만 바꾸면 돼서 바로 붙일 수 있어요. 원하시면 이 세트를 지금 적용해 드릴게요.
클로드가 쓴 도구
Bash: ls -la && cat package.json 2>/dev/null && ls .claude 2>/dev/null; find . -path ./node_modules -prune -o -type f -print | grep -v .git/ | head -60 Bash: for f in .claude/settings.json .github/workflows/ci.yml .gitignore .env.example prisma/schema.prisma src/lib/*.ts src/app/api/orders/route.ts tests/price. Bash: cat .claude/settings.json .github/workflows/ci.yml .gitignore .env.example prisma/schema.prisma src/lib/price.ts src/lib/payments.ts src/lib/db.ts src/app Bash: cat .claude/settings.json .github/workflows/ci.yml .gitignore .env.example prisma/schema.prisma src/lib/price.ts src/lib/payments.ts src/lib/db.ts src/app
이 프로젝트에 맞는 걸로 골랐습니다. 이미 설정된 것 중에 실제로는 동작하지 않는 게 하나 있어서 그것부터 말씀드릴게요.
.claude/settings.json의 PostToolUse 훅은 $CLAUDE_FILE_PATHS를 쓰고 있는데, Claude Code는 이런 환경변수를 제공하지 않습니다. 수정한 파일 경로는 stdin으로 들어오는 JSON(tool_input.file_path)으로 전달됩니다. 그래서 prettier에는 빈 문자열이 넘어가고, 에러가 나도 2>/dev/null || true 때문에 화면에 아무것도 안 뜹니다.
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write --ignore-unknown"
| 항목 | 내용 | 이유 |
|---|---|---|
| permissions.deny | Read(./.env*)를 막고 .env.example만 허용 |
.env에 Stripe 시크릿 키와 DB 비밀번호가 들어 있습니다. git에서는 빠져 있지만 Claude는 읽을 수 있습니다 |
| permissions.allow | npm test, npm run lint, npm run typecheck, npx prisma generate |
자주 쓰는 안전한 명령마다 승인 창이 뜨지 않게 합니다 |
| PreToolUse 차단 훅 | prisma migrate reset, prisma db push --force-reset, --accept-data-loss 차단 |
DB가 날아가는 명령을 Claude가 실수로 실행하지 못하게 합니다 |
| Stop 훅 | 작업이 끝날 때 npm run typecheck && npm test 실행, 실패하면 Claude가 계속 고치게 함 |
CI에서 하는 lint, typecheck, test를 로컬에서 미리 걸러냅니다 |
amount에 원 금액을 그대로 넣습니다(×100 하지 않음). Claude가 다른 통화 예제를 보고 실수하기 쉬운 부분이라 한 줄 적어 두는 게 좋습니다. 금액은 서버에서 DB 가격으로만 계산한다는 원칙도 같이 적어 두세요.payment-reviewer (.claude/agents/): src/lib/payments.ts, src/lib/price.ts, src/app/api/orders/ 쪽이 바뀌었을 때만 리뷰하는 전용 에이전트입니다. 지금 코드에도 이런 에이전트가 잡아낼 만한 게 이미 보입니다.route.ts의 items.find(...)!: 없는 메뉴 ID가 들어오면 500 에러로 죽습니다.soldOut(품절)인 메뉴도 주문이 됩니다.verifyWebhook은 있는데 웹훅 라우트가 없어서 주문 상태(status)가 pending에서 바뀌지 않습니다./security-review, 평소에는 /code-review를 쓰시면 됩니다..github/workflows/에 anthropics/claude-code-action을 추가하면 PR마다 자동 리뷰를 받거나, PR에서 @claude로 불러 쓸 수 있습니다. 지금 있는 ci.yml과 따로 동작합니다.우선순위로 추천하면 0번(훅 수정)과 1번(권한, DB 보호, Stop 훅)이 노력 대비 효과가 가장 큽니다. 그다음이 CLAUDE.md 보강과 payment-reviewer 에이전트입니다. MCP와 CI는 필요해지면 붙이셔도 됩니다.
원하시면 0~2번을 지금 바로 .claude/settings.json, CLAUDE.md, .claude/agents/에 적용하고 동작까지 확인해 드릴게요. 위에서 찾은 route.ts 버그 세 가지도 따로 고칠 수 있습니다.
클로드가 쓴 도구
Skill: claude-code-setup:claude-automation-recommender Bash: cat package.json; ls -la; ls -la .claude 2>/dev/null; git ls-files | head -100; ls .github/workflows 2>/dev/null Bash: for f in .claude/settings.json .claude/settings.local.json .github/workflows/ci.yml .gitignore .prettierrc eslint.config.mjs prisma/schema.prisma src/lib/ Bash: head -n 200 .claude/settings.json .claude/settings.local.json .github/workflows/ci.yml .gitignore .prettierrc eslint.config.mjs prisma/schema.prisma src/l
.claude/settings.json에 Prettier 자동 포맷 훅이 하나 있습니다. 그런데 이 훅이 실제로는 동작하지 않는 것으로 보입니다. 아래 훅 항목 1번에 이유를 적었습니다..claude/settings.json)1. 기존 포맷 훅 고치기 (가장 먼저 할 일)
- 지금 명령은 $CLAUDE_FILE_PATHS를 씁니다. Claude Code는 이 환경변수를 넣어주지 않고, 수정한 파일 경로를 stdin JSON의 tool_input.file_path로 넘깁니다.
- 그래서 Prettier가 빈 경로로 실행되고, 에러는 2>/dev/null || true에 묻혀서 아무 일도 안 일어나는 것처럼 보입니다.
- 고친 예시 (ESLint 수정까지 같이 실행):
json
"command": "jq -r '.tool_input.file_path' | xargs -I{} sh -c 'npx prettier --write \"{}\" && npx eslint --fix \"{}\"' 2>/dev/null || true"
2. 민감한 파일 수정 막기 (PreToolUse)
- .env에는 실제 STRIPE_SECRET_KEY와 DATABASE_URL이 들어 있습니다.
- .env*, package-lock.json, prisma/migrations/**를 Edit/Write하려고 하면 exit 2로 막는 훅을 권합니다. 마이그레이션 파일은 직접 고치지 말고 prisma migrate로만 만들게 하려는 목적입니다.
.claude/agents/)1. payments-reviewer: 결제·주문 코드 전담 리뷰어
- 이유: 돈이 오가는 경로가 src/app/api/orders/route.ts와 src/lib/payments.ts 두 곳에 몰려 있고, 지금 코드만 봐도 리뷰할 점이 바로 보입니다.
- 없는 menuItemId가 들어오면 ! 때문에 500 에러가 납니다.
- soldOut(품절) 체크를 하지 않습니다.
- verifyWebhook은 만들어져 있는데 웹훅 라우트가 아직 없습니다.
- 할 일: 금액 계산, 쿠폰 상한, Stripe 멱등성, 웹훅 서명 검증, 주문 상태 전이만 집중해서 봅니다.
2. test-writer: 테스트 작성 에이전트 - 이유: 지금 테스트는 단위 테스트 2개, e2e 1개뿐입니다. 주문 API와 쿠폰 반올림 같은 경계값 테스트를 Vitest와 Playwright 패턴에 맞춰 채우게 합니다.
.claude/skills/)1. krw-money: Claude만 쓰는 배경 지식 스킬 (user-invocable: false)
- 이유: CLAUDE.md의 "원 단위 정수" 규칙을 Stripe 맥락까지 넓혀 둡니다.
- 담을 내용:
- KRW는 Stripe에서 소수점 없는 통화(zero-decimal)라서 amount: totalKrw가 맞습니다. Claude가 "센트 단위겠지" 하고 *100을 붙이는 실수를 막습니다.
- 할인 반올림 규칙
- 금액 컬럼은 Int로만 둡니다.
2. /db-migrate: 사용자만 실행하는 스킬 (disable-model-invocation: true)
- 이유: schema.prisma 변경 → prisma migrate dev --name … → prisma generate → typecheck/test까지 한 번에 돌리고, 금액 필드가 Int인지도 검사합니다. DB에 영향을 주는 작업이라 직접 실행할 때만 돌게 합니다.
1. context7: 라이브러리 최신 문서 조회
- 이유: Next 15(async params, Route Handler), Prisma 6, Stripe 17은 API가 자주 바뀝니다. 학습 데이터에 남아 있는 옛날 사용법이 섞여 들어가지 않게 막아줍니다.
- 설치: claude mcp add context7 -- npx -y @upstash/context7-mcp
2. Stripe 공식 MCP: 반드시 테스트 키로만 연결
- 이유: PaymentIntent 조회, 웹훅 이벤트 확인, 테스트 결제 생성을 Claude가 직접 해볼 수 있어서 결제 흐름을 디버깅할 때 편합니다.
- 주의: .mcp.json으로 팀과 공유한다면 키는 환경변수로 넘기세요.
.env 차단 훅: 5분이면 되고 효과가 바로 나옵니다.krw-money 스킬과 payments-reviewer: 결제 사고를 예방합니다./db-migrate, Stripe MCP이번에는 분석만 했고 파일은 하나도 만들거나 바꾸지 않았습니다. 원하는 항목을 말씀해 주시면 바로 설정해 드릴게요. 특정 분야(예: 훅 더 보기, MCP 더 보기)로 추천을 더 받으셔도 됩니다.
클로드가 쓴 도구
Skill: claude-code-setup:claude-automation-recommender Bash: ls -la && cat package.json; ls -la .claude 2>/dev/null; git ls-files | head -100; ls .github/workflows 2>/dev/null Bash: for f in .claude/settings.json .claude/settings.local.json .gitignore .env.example .github/workflows/ci.yml prisma/schema.prisma src/app/api/orders/route. Bash: tail -n +1 .claude/settings.json .claude/settings.local.json .gitignore .env.example .github/workflows/ci.yml prisma/schema.prisma src/app/api/orders/rout
.claude/settings.json에 Prettier 훅이 하나 있음.claude/settings.json의 훅은 $CLAUDE_FILE_PATHS를 씁니다. 그런데 Claude Code는 이런 환경변수를 넘겨주지 않고, 수정한 파일 경로를 stdin JSON으로 전달합니다. 그래서 prettier --write ""가 실패하고, 뒤에 붙은 || true가 그 실패를 숨기고 있습니다. 직접 실행해 보지는 않았고 설정 내용만 보고 판단한 것입니다. 아래처럼 바꾸면 됩니다.
{ "type": "command",
"command": "f=$(jq -r '.tool_input.file_path // empty'); [ -n \"$f\" ] && npx prettier --write \"$f\" && npx eslint --fix \"$f\" 2>/dev/null; exit 0" }
| 훅 | 이유 |
|---|---|
| PostToolUse: Prettier와 ESLint 자동 실행 (위 수정안) | CI가 npm run lint에서 막히기 전에 수정 단계에서 바로 잡아줍니다 |
PreToolUse: .env와 package-lock.json 수정 차단 |
.env에 Stripe 시크릿 키와 DB 접속 정보가 들어 있습니다. 훅이 Read\|Edit\|Write에서 .env(.env.example은 제외)를 감지하면 exit 2로 막습니다 |
payment-security-reviewer (.claude/agents/payment-security-reviewer.md)
- 이유: 코드를 읽어 보니 결제 쪽에서 실제로 걱정되는 부분이 보였습니다.
- src/app/api/orders/route.ts가 coupon(최대 50%)을 클라이언트 요청에서 그대로 받습니다. 누구나 절반 가격으로 결제할 수 있다는 뜻입니다.
- 없는 menuItemId가 들어오면 ! 때문에 500 에러가 납니다.
- soldOut(품절) 메뉴인지 확인하지 않습니다.
- 웹훅 검증 함수(verifyWebhook)는 있는데 이를 쓰는 웹훅 라우트가 없습니다.
- 역할: 금액 계산, Stripe 호출, 주문 상태 전이를 바꾸는 diff만 골라 검토합니다. 금액이 원 단위 정수(priceKrw)인지, 서버가 금액을 신뢰할 수 있는지, 같은 요청이 두 번 와도 안전한지(멱등성)를 봅니다.
- 한 번만 점검하려면 내장 /security-review로도 충분합니다.
| 스킬 | 호출 방식 | 내용 |
|---|---|---|
/db-migrate .claude/skills/db-migrate/SKILL.md |
사용자만 (disable-model-invocation: true) |
스키마 수정 → prisma migrate dev --name <이름> → prisma generate → npm run typecheck && npm test. 아직 prisma/migrations 폴더가 없어서 첫 마이그레이션부터 절차를 고정해 두면 좋습니다 |
/gen-test |
사용자만 | 지정한 모듈의 vitest 테스트를 생성합니다. 현재 테스트가 price.test.ts의 2개뿐이라 주문 API와 결제 경계 테스트를 채우는 데 씁니다 |
| 서버 | 이유 | 설치 |
|---|---|---|
| Playwright | e2e 테스트를 쓰거나 고칠 때 Claude가 실제 브라우저로 /menu 등을 확인할 수 있습니다 |
claude mcp add playwright -- npx @playwright/mcp@latest |
| Stripe | PaymentIntent 조회, 테스트 결제 확인, Stripe 문서 검색 | claude mcp add --transport http stripe https://mcp.stripe.com (테스트 모드 키만 연결 권장) |
그 밖의 선택지:
- context7: Next 15와 React 19의 최신 문서를 조회합니다.
- Prisma MCP: npx prisma mcp. Prisma 6.6 이상이 필요한데 지금은 ^6.2라서 업그레이드가 먼저입니다.
/install-github-app으로 Claude GitHub Action을 붙이면 PR에서 @claude를 호출해 리뷰를 받을 수 있습니다.
이 스킬은 분석 전용이라 아직 파일은 하나도 바꾸지 않았습니다. 훅 수정과 .env 보호처럼 원하는 항목을 말씀해 주시면 바로 설정하겠습니다. 특정 분야의 추천을 더 보고 싶다면 "훅 더 추천해 줘"처럼 요청하시면 됩니다.
채점 기준과 항목별 점수는 원문 글에 있습니다.