← 모든 글

코드 리뷰 룰을 3번 바꾸면서 배운 것

코드 리뷰 규칙을 세 번 바꾸며 겪은 실패와 깨달음. 결제·정산 팀 시각으로 본 리뷰의 실질 목적과 지속 가능한 프로세스 설계의 핵심을 정리했다.

왜 결제·정산 코드에서 리뷰 규칙이 더 중요한가

결제와 정산 시스템을 다루는 팀에게 코드 리뷰는 단순한 품질 게이트가 아니다. 배포된 버그 하나가 오정산으로 이어지고, 그것이 고객 클레임과 환불 처리, 최악의 경우 금융 관련 보고 의무로 연결되는 파이프라인이 존재하기 때문이다. 일반적인 웹 서비스에서 UI 버그 하나가 "UX 불편"으로 끝난다면, 정산 로직 버그 하나는 "데이터 재처리 이틀"로 돌아온다. 우리가 리뷰 규칙을 세 번 바꾸는 동안 내내 의식했던 것은 이 비용의 비대칭성이었다.

실제로 우리 팀은 2버전 규칙으로 전환하기 전, 리뷰 없이 머지된 자동이체 배치 코드에서 소수점 처리 오류를 경험했다. 건당 금액 오차는 1원이었지만, 수천 건 규모의 배치에서 발생한 오차를 건별로 조정 처리하는 공수가 이틀을 넘겼다. 코드 한 줄을 리뷰하는 데 5분만 투자했다면 잡을 수 있었던 실수였다. 이 경험은 우리가 단순히 "리뷰를 잘 하자"가 아니라, "어떤 규칙이 위기 상황에서도 리뷰를 지속시키는가"를 고민하게 만든 출발점이다.

1버전: 규칙 없이 시작 — "세 명이면 괜찮겠지"의 함정

초창기에 별도 규칙을 만들지 않은 이유는 합리적으로 들렸다. 세 명짜리 팀에서 프로세스 오버헤드를 최소화하고, 서로 맥락을 충분히 공유하고 있다는 신뢰. 처음 몇 달은 실제로 잘 돌아갔다. PR이 생기면 슬랙에서 바로 "봤어?"라고 물어보면 됐고, 피드백은 빠르게 왔다.

문제는 이 방식이 "팀이 여유로울 때만" 작동하는 구조적 취약성을 가진다는 것이다. 마감이 다가오면 리뷰는 자연스럽게 뒤로 밀렸고, "긴급하니까 자체 머지"가 월 2~3회 반복됐다. 이 코드들은 대부분 무사히 배포됐지만, 문제가 생겼을 때가 치명적이었다. 리뷰 없이 배포된 코드는 나중에 디버깅할 때 "이게 왜 이렇게 됐지?"라는 질문에 아무도 답할 수 없는 상태가 된다. 코드 공동 소유가 아니라 코드 고아가 생겨나는 것이다. 결제·자동화 코드에서 코드 고아는 특히 위험하다. 로직을 아는 사람이 한 명뿐이고 그 사람이 자리를 비우면, 배치 잡 하나가 멈춰도 손댈 수 없는 상황이 만들어진다.

2버전: 엄격한 규칙 — 프로세스가 목적이 된 순간

반성 끝에 체계를 만들었다. 최소 1명 승인 필수, 5개 항목 체크리스트(테스트 작성 여부·에러 핸들링·로깅·보안 체크·문서 업데이트), 커버리지 미달 PR은 CI에서 차단. 의도는 좋았지만 결과는 달랐다.

두 달 뒤 PR 큐에 78개 PR이 쌓인 채로 리뷰어 한 명이 2박 3일 출장을 떠났다. 리뷰 한 건에 3040분이 걸리다 보니, 체크리스트를 "채우는" 행위 자체가 목적이 됐고 실제 로직 버그는 오히려 놓쳤다. 가장 아이러니한 케이스는 커버리지 게이트가 안전을 방해한 상황이었다. 긴급 핫픽스 PR이 테스트 커버리지 미달로 CI 블락을 먹으면서 실제 운영 장애가 30분 더 연장됐다. 규칙이 배포 속도와 품질을 동시에 떨어뜨린 순간이었다. 이 실패에서 배운 것은, 무거운 프로세스는 위기가 오면 제일 먼저 건너뛰게 된다는 단순한 사실이다. 위기 때 지켜지지 않는 규칙은 평상시에도 형식만 남는다.

3버전: 지금 쓰는 방식 — 두 가지만 남겼다

현재 규칙은 두 가지다. 승인 없이는 머지하지 않는다, 그리고 주 리뷰어 한 명이 코어 피드백을 담당한다. 단순해 보이지만, 두 규칙 각각에 팀이 합의한 명시적 정의가 붙어 있다는 점이 핵심이다.

"승인"의 기준은 "내가 이렇게 짰을까?"가 아니라 "이 코드가 배포되면 안 되는 이유가 있는가?"다. 스타일 차이, 개인 선호, 더 나은 최적화 가능성은 승인 기준에서 제외했다. 배포 블락 사유는 세 가지로 좁혔다: 로직 버그, 금액·정산 관련 엣지케이스 미처리, 되돌릴 수 없는 데이터 변경. 리뷰어는 이 세 가지에만 집중하면 되고, 실제로 평균 리뷰 시간이 3040분에서 1015분으로 줄었다. "주 리뷰어 1인" 원칙은 작성자의 인지 부하를 줄이기 위한 장치다. 세 명이 동시에 코멘트를 달면 작성자는 누구의 의견을 우선할지 판단하는 메타 작업이 생긴다. 나머지 팀원은 [Optional] 레이블로 한두 줄 이내 코멘트만 달 수 있고, 이는 승인 블락 요소가 아니다.

결제·자동화 현장의 실제 적용 시나리오

자동이체 실패 재시도 로직을 리팩터링했을 때를 구체적 예로 들어보자. 이 코드는 배치 잡에서 실패한 건들을 다음 날 재처리하는 로직으로, 이미 성공 처리된 건이 재시도 큐에 다시 들어갈 경우 중복 청구가 발생할 수 있는 엣지케이스가 숨어 있었다.

1버전 규칙이었다면 마감 압박에 자체 머지됐을 가능성이 충분했다. 2버전이었다면 체크리스트 다섯 항목을 채우느라 정작 "idempotency key가 올바르게 처리되고 있는가?"라는 핵심 질문을 놓쳤을 것이다. 3버전에서 주 리뷰어는 리뷰 시작 전에 딱 하나를 물었다. "중복 처리 방지 로직이 어디에 있어?" 작성자가 idempotency key 처리 코드를 가리켰고, 리뷰어는 그 부분만 10분 집중해서 확인했다. 전체 리뷰 시간 12분. 이 방식이 가능한 이유는 리뷰의 목적이 "모든 것을 검증"에서 "가장 위험한 것을 검증"으로 바뀌었기 때문이다. 결제·정산 도메인에서 "가장 위험한 것"은 대부분 금액 계산, 상태 전이, 외부 API 연동 이 세 곳에 집중돼 있다.

바로 써먹을 수 있는 실행 시사점

승인 기준을 지금 당장 명문화하라. "코드가 좋은가?"가 아니라 "이 코드가 배포되면 안 되는 이유가 있는가?"로 기준을 뒤집는 것만으로 리뷰 시간이 절반 이하로 줄어든다. 팀에서 배포 블락 사유를 3개 이내로 합의해 문서화해두면, 리뷰어가 무엇을 봐야 하는지 매번 재해석할 필요가 없어진다.

결제·정산 코드에는 체크리스트 대신 위험 레이블을 붙여라. PR 제목이나 본문에 [금액 계산], [DB 마이그레이션], [외부 API 연동], [배치 잡] 같은 레이블을 달면, 리뷰어가 어디에 집중해야 하는지 즉시 파악할 수 있다. 무차별적 체크리스트보다 위험 구역을 명시하는 것이 실질적 버그 검출률을 높인다. 세 번째로, 프로세스의 재검토 주기를 미리 박아두어라. "이 규칙을 3개월 뒤에 재검토한다"는 문장 하나를 팀 위키에 적어두는 것이 생각보다 중요하다. 우리가 규칙을 세 번 바꿀 수 있었던 건 규칙을 신성시하지 않았기 때문이다. 현재의 두 가지 규칙도 팀 규모나 도메인이 바뀌면 다시 바뀔 것이다. 프로세스는 현재 팀의 상태를 반영하는 도구이지, 지켜야 할 목표가 아니다.

— by mings

* 위 링크는 인프런 affiliate 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

📚 추천 강의
한 입 크기로 잘라먹는 바이브코딩 (with Claude Code)
Claude Code로 바이브코딩, 개발자라면 꼭 들어야 할 필수 강의
강의 보러가기 →

* 위 추천 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.