잘 아는 영역을 하나 고르세요 — 프런트엔드 코드, API 설계, SQL 쿼리, 문서 — 그리고 그 영역의 리뷰 스킬을 만듭니다.
레벨 1: 자기만의 리뷰 스킬 만들기요구사항:
- 리뷰 차원 최소 3개
- 차원마다 구체적인 점검 항목 3~5개
- 명확한 출력 형식 (통과, 살펴볼 것, 반드시 고칠 것)
- 실제 사례 최소 2개로 테스트
학습 목표:
- 여러 단계로 이루어진 워크플로를 구성하는 법 익히기
- 체크리스트 패턴이 어떻게 적용되는지 이해하기
- 보조 파일 사용에 익숙해지기
- 실전에 바로 쓸 수 있는 복잡한 스킬 하나 만들기
코드 리뷰는 교과서에 나올 법한 구조화된 워크플로입니다.1
이 케이스 스터디에서 다루는 것:
무엇을 쓰기 전에, 이 스킬이 무엇을 점검할 책임을 지는지 먼저 정합니다.
우리 코드 리뷰 스킬이 다루는 세 가지 차원:
의도적으로 점검하지 않는 것:
이번에는 보조 파일을 써서 리뷰 규칙을 정리합니다.2
파일을 나누는 이유:
checklists/naming.md:
checklists/error-handling.md:
문제를 여럿 심어 둔 스니펫을 준비합니다.
스킬을 호출합니다.
출력에는 다음이 포함되어야 합니다.
process, data, x, y가 모두 너무 뭉뚱그려져 있다const/let 대신 var를 쓴다=== 대신 ==를 쓴다data가 null인지, 배열이 맞는지 전혀 확인하지 않는다item.value가 존재하는지 확인하지 않는다첫 실행에서 흔히 드러나는 것:
계속 개선하기:
다음 레슨에서는 고급 패턴으로 넘어갑니다. 개인 스킬과 프로젝트 스킬, 버전 관리, 그리고 팀 협업입니다.
Anthropic 엔지니어링 블로그: Equipping agents for the real world with Agent Skills — https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills ↩
Anthropic 플랫폼 문서: Agent Skills overview — https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview ↩ ↩2
Claude Code skills: .NET 워크플로와 재사용 가능한 프롬프트 — https://codewithmukesh.com/blog/skills-claude-code/ ↩
요구사항:
각각 무엇을 찾아냈는지 비교하고 다음을 적습니다.
mkdir -p ~/.claude/skills/code-review
mkdir -p ~/.claude/skills/code-review/checklists
touch ~/.claude/skills/code-review/SKILL.md
touch ~/.claude/skills/code-review/checklists/naming.md
touch ~/.claude/skills/code-review/checklists/error-handling.md
---
name: code-review
description: 코드 변경을 네이밍 컨벤션, 에러 처리, 잠재적 버그, 유지보수성 문제 관점에서 리뷰한다. PR 리뷰나 일반적인 코드 품질 점검에 사용
---
# 코드 리뷰 어시스턴트
팀의 컨벤션과 확립된 관행에 비추어 코드 변경을 체계적으로 리뷰한다.
## 입력 형식
다음 중 무엇이든 받는다.
- Git diff 출력
- 완전한 소스 파일
- 코드 조각 (함수 또는 클래스)
- PR 링크 (먼저 도구로 PR 내용을 읽을 것)
## 리뷰 흐름
다음 순서로 리뷰를 진행한다.
### 1. 컨벤션 점검
`checklists/naming.md`를 참조해 각 항목을 차례로 확인한다.
- **변수명**: 의미가 분명하고, 팀 컨벤션(camelCase, snake_case 등)과 일관적인가
- **함수명**: 동사로 시작하고, 의도를 분명히 드러내는가
- **클래스명**: 명사이고, 단일 책임에 부합하는가
- **상수명**: 모두 대문자, 언더스코어 구분인가
**기준:** 모든 이름은 코드에 익숙하지 않은 사람에게도 그 용도를 알려 줘야 한다
### 2. 에러 처리 점검
`checklists/error-handling.md`를 참조해 다음을 확인한다.
- **예외 포착**: try/catch가 있는가, 그리고 올바른 예외 타입을 잡고 있는가
- **에러 반환값**: 함수가 에러를 올바르게 처리하고 전파하는가
- **엣지 케이스**: 빈 입력, null, undefined, 빈 배열이 처리되는가
- **리소스 정리**: 파일, 커넥션, 락이 제대로 해제되는가
**기준:** 실패할 수 있는 것에는 에러 처리가 필요하다
### 3. 잠재적 문제 점검
- **null/undefined 접근**: 존재하지 않는 프로퍼티나 메서드에 닿을 수 있는가
- **타입 안전성**: 암묵적 타입 변환의 위험은 없는가
- **동시성**: 경쟁 상태나 교착 상태의 위험은 없는가
- **보안 구멍**: SQL 인젝션, XSS, CSRF, 비밀정보 유출
**기준:** 런타임 에러나 보안 위험을 낳을 수 있는 코드는 지적한다
### 4. 유지보수성 점검
- **함수 길이**: 50줄을 넘으면 분리를 제안한다
- **중복**: 세 번 이상 나타나는 로직은 추출을 제안한다
- **중첩 깊이**: 3단계를 넘으면 리팩터링을 제안한다
- **주석 품질**: 복잡한 로직이 설명되어 있는가
**기준:** 다른 개발자가 이 코드를 쉽게 읽고 바꿀 수 있어야 한다
## 출력 형식
리뷰 결과는 다음 구조로 보고한다.
### ✅ 통과
- [점검 항목] - 기준을 충족함
### ⚠️ 살펴볼 것
- **위치**: `file:line`
- **문제**: 정확히 무엇이 잘못됐는지
- **영향**: 이것이 무엇으로 이어질 수 있는지
- **제안**: 어떻게 개선할지
### 🔴 반드시 고칠 것
- **위치**: `file:line`
- **문제**: 정확히 무엇이 잘못됐는지
- **위험**: 왜 이대로 내보낼 수 없는지
- **제안**: 구체적인 수정 방법
### 📊 종합 평가
- 코드 품질: 우수 / 무난 / 개선 필요
- 주요 문제: [가장 중요한 2~3건]
- 권장 우선순위: [무엇부터 고칠지]
## 참고 사항
- **맥락 부족**: 조각이 불완전하면 주변 코드가 더 필요할 수 있다고 말한다
- **프레임워크 관용구**: 문제처럼 보여도 프레임워크 특유의 패턴일 수 있다 — "확인 필요"로 표시한다
- **테스트 코드**: 테스트에서는 타당한 범위에서 기준을 완화한다 (예: 함수 길이)
- **아무것도 없을 때**: 모든 점검을 통과하면 "✅ 리뷰 통과, 뚜렷한 문제를 찾지 못했습니다"를 출력한다
# 네이밍 컨벤션 체크리스트
## 변수명
**좋은 예:**
- `userCount`: 사용자 수임이 분명하다
- `isAuthenticated`: 불리언은 is/has/can으로 시작한다
- `maxRetryAttempts`: 의미와 단위를 함께 밝힌다
**나쁜 예:**
- `x`, `temp`, `data`: 너무 뭉뚱그려져 있다
- `flag`, `status`: 어떤 상태를 담는지 말해 주지 않는다
- `getUserInfo2`: 숫자 접미사는 보통 중복이 있다는 뜻이다
## 함수명
**좋은 예:**
- `calculateTotalPrice()`: 동사 더하기 명사, 동작과 그 대상을 모두 밝힌다
- `validateUserInput()`: 무엇을 하는지와 무엇에 대해 하는지를 말한다
- `fetchUserProfile()`: `fetch`가 비동기임을 알려 준다
**나쁜 예:**
- `process()`: 너무 뭉뚱그려져 있다, 무엇을 처리하는가
- `doStuff()`: 의도를 전혀 표현하지 못한다
- `handleData()`: `handle`도 `data`도 너무 넓다
## 클래스명
**좋은 예:**
- `UserRepository`: 책임을 밝히는 명사 (사용자 데이터 읽기와 쓰기)
- `PaymentProcessor`: 결제를 처리하는 것임이 분명하다
- `EmailValidator`: 이메일 검증이라는 책임을 밝힌다
**나쁜 예:**
- `Manager`, `Helper`, `Utility`: 접미사가 너무 뭉뚱그려져 아무 의미가 없다
- `DataClass`: 어떤 데이터인지 말해 주지 않는다
# 에러 처리 체크리스트
## 반드시 점검해야 할 시나리오
### 1. 외부 의존성 호출
- API 요청 (네트워크 실패, 타임아웃, 4xx/5xx 응답)
- 데이터베이스 쿼리 (연결 실패, 쿼리 타임아웃, 제약 조건 위반)
- 파일 작업 (파일 없음, 권한 부족, 디스크 가득 참)
### 2. 사용자 입력
- 빈 입력, null, undefined
- 형식이 잘못된 입력
- 범위를 벗어난 값
### 3. 데이터 변환
- JSON 파싱 (형식이 잘못된 입력)
- 타입 변환 (문자열에서 숫자로 변환 실패)
- 날짜 파싱 (유효하지 않은 날짜 형식)
## 에러 처리 패턴
**잡아서 처리하기:**
```javascript
try {
const data = await fetchUser(id);
return processData(data);
} catch (error) {
logger.error('Failed to fetch user', { id, error });
return null; // 또는 커스텀 에러를 던진다
}
```
**호출 전에 확인하기:**
```javascript
if (!user) {
throw new Error('User not found');
}
const profile = user.getProfile(); // 안전 — user는 확실히 null이 아니다
```
## 흔한 실수
**문제:** 빈 catch 블록
```javascript
try {
riskyOperation();
} catch (e) {
// 여기서 아무 일도 일어나지 않는다 — 에러가 삼켜진다
}
```
**수정:** 최소한 로그는 남긴다
```javascript
try {
riskyOperation();
} catch (e) {
logger.error('Operation failed', e);
throw e; // 또는 에러 상태를 반환한다
}
```
function process(data) {
var result = [];
for (var i = 0; i < data.length; i++) {
var item = data[i];
if (item.type == "A") {
var x = item.value * 2;
result.push(x);
} else if (item.type == "B") {
var y = item.value / 2;
result.push(y);
} else {
result.push(item.value);
}
}
return result;
}
/code-review
[위 코드를 붙여넣기]