사이드 프로젝트에 Claude Code /review를 붙여본 3주간의 기록
주문 API 사이드 프로젝트에 Claude Code /review와 claude-code-action을 적용하며 실제로 잡은 버그, 쓸데없는 지적, 설정 삽질을 정리한 경험입니다.

올해 초부터 주문 관리 API를 혼자 만들고 있습니다. Spring Boot + JPA 기반이고, 상품 등록부터 주문 처리, 정산까지 다루는 사이드 프로젝트입니다. 팀 프로젝트가 아니라 혼자 하는 거라 코드 리뷰를 받을 사람이 없었습니다. PR을 올려도 스스로 Approve 누르고 머지하는 게 전부였습니다.
그게 문제가 된 건 주문 목록 조회 API에서였습니다. 배포 후 로그를 보니 조회 한 번에 쿼리가 20개씩 나가고 있었습니다. @ManyToOne 기본 fetch 전략을 EAGER로 둔 채 넘어갔던 게 원인이었습니다. 이전에 N+1 문제로 삽질했던 경험이 있는데도 같은 실수를 반복한 거였습니다. 누군가 PR 단계에서 한 줄만 짚어줬으면 막을 수 있었을 일이었습니다.
그래서 Claude Code의 /review 기능을 써보기로 했습니다.
처음 돌렸을 때 — 기대 이상, 하지만
터미널에서 /review를 실행하면 현재 브랜치의 diff를 분석해서 리뷰 결과를 출력합니다. --comment 플래그를 붙이면 PR의 해당 코드 라인에 인라인 코멘트를 직접 달아줍니다.
# 터미널에 결과만 출력
/review
# PR에 인라인 코멘트를 직접 남기기
/review --comment주문 생성 로직을 리팩터링한 PR에 처음 돌려봤습니다. 실제로 달린 코멘트 중 유용했던 것들입니다.
첫 번째는 OrderService.createOrder()에서 @Transactional(readOnly = true)를 빼먹은 조회 메서드를 잡아준 것이었습니다. getOrderDetail()은 조회만 하는 메서드인데, 습관적으로 @Transactional만 붙이고 readOnly 옵션을 빠뜨렸습니다. 사소하지만 운영에서 커넥션 풀 관리에 영향을 주는 부분이라 고마웠습니다.
두 번째는 정산 금액 계산에서 BigDecimal 비교를 equals() 대신 compareTo()로 하라는 지적이었습니다. new BigDecimal("1.0").equals(new BigDecimal("1.00"))이 false를 반환하는 건 알고 있었지만, 막상 코드를 쓸 때는 무심코 equals()를 썼습니다.
세 번째는 예외 처리였습니다. 주문 상태 변경 메서드에서 잘못된 상태 전이가 들어오면 RuntimeException을 던지고 있었는데, 커스텀 예외를 쓰라는 코멘트가 달렸습니다. 이건 CLAUDE.md에 "RuntimeException 직접 사용 금지"라고 적어뒀던 규칙을 보고 지적한 것이었습니다.
쓸데없는 지적도 있었다
좋은 것만 있었던 건 아닙니다.
테스트 코드에서 변수명을 order1, order2로 지은 것에 대해 "의미 있는 이름을 사용하세요"라는 코멘트가 달렸습니다. 테스트 픽스처에서 order1, order2는 충분히 명확한 이름입니다. 이런 취향 수준의 지적이 한 PR에 3~4개씩 붙으면 정작 중요한 코멘트가 묻힙니다.
SettlementServiceTest에서는 given-when-then 구분을 위해 넣어둔 빈 줄에 대해 "불필요한 공백 라인입니다"라는 코멘트도 있었습니다. 이건 포매터가 처리할 영역이지 리뷰에서 다룰 내용이 아닙니다.
이 문제는 CLAUDE.md에 "하지 말 것"을 명시적으로 적으면서 해결했습니다. 리뷰에서 뭘 봐야 하는지보다, 뭘 보지 말아야 하는지를 적는 게 노이즈를 줄이는 데 더 효과적이었습니다.
## 리뷰 시 하지 말 것
- 테스트 코드의 변수명이나 가독성 스타일에 대한 코멘트 금지
- import 순서, 빈 줄 같은 포매팅 이슈 무시 (Formatter가 처리함)
- 단순 네이밍 취향 차이는 지적하지 않기이걸 추가한 뒤로 거짓 양성(False Positive)이 체감상 절반 이하로 줄었습니다.
설정 삽질 타임라인
로컬 /review --comment는 금방 돌아갔지만, GitHub Actions에 claude-code-action을 붙이는 과정은 순탄하지 않았습니다.
gh CLI 인증 문제. /review --comment는 내부적으로 gh CLI를 사용해서 PR에 코멘트를 답니다. 처음 실행했을 때 gh auth status가 통과하지 않아서 코멘트가 안 달렸습니다. 에러 메시지도 "코멘트를 달 수 없습니다" 정도여서, 원인이 gh 인증인지 PR 권한인지 헷갈렸습니다. gh auth login으로 토큰을 갱신하니 해결됐습니다.
Draft PR에 리뷰가 달리는 문제. claude-code-action을 처음 붙였을 때, Draft 상태의 PR에도 리뷰가 달렸습니다. 아직 작성 중인 코드에 "이 메서드는 미완성입니다" 같은 코멘트가 붙는 건 당연히 소용이 없습니다. workflow의 if 조건에 github.event.pull_request.draft == false를 추가해서 해결했습니다.
API Key 비용 예상 외. 처음에는 테스트 삼아 API Key 방식으로 연동했는데, PR 하나당 비용이 생각보다 나왔습니다. diff가 큰 PR에서는 입력 토큰만 수만 개가 들어갑니다. 결국 로컬에서 /review --comment를 쓰는 방식으로 전환했습니다. Claude Pro/Max 구독 범위 내에서 동작하니 추가 비용이 없습니다.
claude-code-action 설정
결국 안정적으로 정착한 workflow 설정입니다.
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
issue_comment:
types: [created]
jobs:
review:
if: |
(github.event_name == 'pull_request' && github.event.pull_request.draft == false) ||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude'))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
model: "claude-sonnet-4-20250514"@claude 멘션으로 추가 질문을 할 수 있는 것도 유용합니다. 리뷰 코멘트에 "이 부분을 이렇게 바꾸면 어떤 문제가 있어?"라고 물어보면 해당 맥락을 이해한 상태에서 답변을 달아줍니다.
비용 정리
| 방법 | 인증 | 비용 | 적합한 경우 |
|---|---|---|---|
/review --comment (로컬) | Pro/Max 구독 | 추가 비용 없음 | 개인 프로젝트 |
claude-code-action + API Key | ANTHROPIC_API_KEY | 토큰 종량제 | 팀 프로젝트, 완전 자동화 |
claude-code-action + OAuth | Max 구독 토큰 | 구독 내 포함 | Max 구독자 |
개인 프로젝트에서는 로컬 /review --comment를 PR 올리기 전에 습관적으로 실행하는 것만으로 충분했습니다. API Key 방식은 팀 단위로 쓸 때 의미가 있습니다.
3주 운영 후 느낀 것
사람의 리뷰를 대체하지는 못합니다. "이 할인율 계산이 기획 의도와 맞는지", "이 API 응답 구조가 프론트엔드에서 쓰기 편한지" 같은 판단은 여전히 사람의 영역입니다.
하지만 혼자 개발할 때 놓치기 쉬운 것들 -- readOnly 누락, BigDecimal 비교 실수, EAGER fetch 설정 -- 을 일관되게 잡아주는 건 확실합니다. AI 코딩 도구를 비교했을 때도 느꼈지만, 도구의 가치는 기능 목록이 아니라 기존 워크플로우에 얼마나 자연스럽게 녹아드는지에 달려 있었습니다. /review --comment 한 줄이면 끝나는 이 도구는 그 기준을 충족했습니다.
그리고 의외의 수확이 하나 있었습니다. CLAUDE.md에 리뷰 기준을 적는 과정 자체가 유익했습니다. "조회 메서드에는 readOnly를 붙여라", "RuntimeException을 직접 쓰지 마라" 같은 규칙들은 머릿속에만 있던 것들이었는데, 글로 적으니 일관되게 지킬 수 있게 됐습니다. AI 리뷰어를 설정하는 일이 결국 내 코딩 기준을 명문화하는 일이었습니다.
완벽한 도구는 아닙니다. 비즈니스 로직의 의도는 모르고, 취향 수준의 지적을 완전히 없앨 수는 없습니다. 그래도 혼자 개발하면서 PR을 셀프 머지하는 것보다는 한 단계 나은 안전망이 됐습니다.