테마 전환

AI로 레거시 코드 10,000줄 리팩터링: 한 달 분량을 2주 만에 끝낸 실제 회고

Easton editorial illustration: one tangled legacy code block transforming into three clean modules

10월 초에 긴급 프로젝트를 맡았습니다. 핵심 비즈니스 로직이 10,000줄에 이르는 Vue 2.x 주문 관리 시스템이었습니다. 테스트 커버리지는 10%도 되지 않았고, 상태 관리가 너무 뒤죽박죽이라 데이터 흐름을 파악하기조차 어려웠습니다. 게다가 3년 동안 아무도 감히 손대지 못한 코드였습니다. 팀 리더가 제시한 기한은 리팩터링과 배포까지 2주였습니다.

팀 리더가 제게 준 시간은 2주였습니다. 그 안에 리팩터링을 끝내고 배포해야 했습니다.

그때는 정말 무리한 요구라고 생각했습니다. 기존 방식으로 사람이 직접 리팩터링한다면 비즈니스 로직을 이해하는 데만 일주일이 걸리고, 그 뒤 조심스럽게 코드를 수정하고 테스트를 작성하고 검증해야 합니다. 30~40일로도 끝낼 수 있을지 확신하기 어려웠습니다. 하지만 현업 부서는 기다릴 수 없었습니다. 시스템이 너무 느려 사용자 불만까지 나오고 있었기 때문입니다.

그러다 얼마 전 친구가 추천한 Claude Code가 떠올랐습니다. 대규모 코드 리팩터링도 처리할 수 있다고 했습니다. 솔직히 당시에는 저도 불안했습니다. AI로 코드를 리팩터링해도 정말 괜찮을까? 잘못 고치면 어떻게 하지?

하지만 다른 선택지가 없었습니다. 한번 시도해 보기로 했습니다.

2주 뒤 배포 버튼을 누르고 모니터링 대시보드의 모든 지표가 초록색으로 정상 표시되는 모습을 보니 벅차지 않을 수 없었습니다. 전체 리팩터링은 14일 만에 끝났고, 운영 사고는 한 건도 없었습니다. API 응답 시간은 20% 개선됐고 버그 발생률은 40%나 줄었습니다.

이 글에서는 그 14일을 어떻게 보냈는지, 어떤 시행착오를 겪었는지, 어떤 경험을 바로 활용할 수 있는지 이야기해 보겠습니다. 비슷한 기술 부채를 해결해야 하거나 AI 보조 리팩터링에 관심이 있다면 도움이 될 것입니다.

14일
리팩터링 완료 기간
기존 방식은 35일 이상 필요
75%
테스트 커버리지
10%에서 향상
40%
버그 발생률 감소
20%
응답 시간 개선
Source: 실제 프로젝트 데이터

프로젝트 배경: 이 프로젝트는 대체 얼마나 엉망이었나

먼저 프로젝트가 얼마나 엉망이었는지 이야기해 보겠습니다.

이 시스템은 회사의 핵심 주문 관리 시스템으로, 하루 평균 약 5,000건의 주문을 처리했습니다. 주문 생성, 결제, 배송 추적, 사후 처리 등 10여 개의 비즈니스 프로세스가 얽혀 있었습니다. 코드는 2022년 초 Vue 2.x로 작성됐습니다. 당시 담당 프론트엔드 개발자는 코드를 작성한 뒤 퇴사했고, 이후 네 명이 차례로 유지보수하면서 각자 패치를 덧붙였습니다. 코딩 스타일도 전혀 통일돼 있지 않았습니다.

얼마나 심각했을까요? 이틀 내내 진단한 끝에 충격적인 문제들을 발견했습니다.

  1. 핵심 비즈니스 코드 10,000줄 중 가장 긴 단일 파일은 1,800줄이었고, 가장 비대한 OrderService.js에는 메서드가 47개나 있었습니다.
  2. 테스트 커버리지가 10% 미만이었습니다. 간단한 단위 테스트 몇 개뿐이었고, 핵심 비즈니스 로직은 전혀 검증하지 못했습니다.
  3. 상태 관리가 혼란스러웠습니다. Vuex, LocalStorage, SessionStorage, 전역 이벤트 버스라는 네 가지 방식을 섞어 써서 데이터 흐름을 도저히 추적할 수 없었습니다.
  4. 중복 코드가 넘쳐났습니다. 동일한 주문 상태 판정 로직이 복사·붙여넣기 된 곳만 23군데였습니다.
  5. 성능 문제가 있었습니다. 주문 목록 페이지를 불러오는 데 3~4초가 걸려 사용자 불만이 끊이지 않았습니다.

가장 골치 아픈 점은 시스템이 엉망이어도 계속 운영되고 있었다는 사실입니다. 매일 수천 명의 사용자가 이용하고 있어 과감하게 뜯어고치기가 어려웠습니다. 문제가 생기면 비즈니스가 곧바로 마비될 수 있었습니다.

기존 방식으로 리팩터링하면 얼마나 걸릴까?

화이트보드에 기존 리팩터링 방식에 필요한 단계를 적어 봤습니다.

  1. 비즈니스 로직 이해(예상 5~7일)
  2. 테스트 케이스 보강(예상 7~10일)
  3. 리팩터링 모듈 분리(예상 10~15일)
  4. 모듈별 리팩터링 및 검증(예상 8~12일)
  5. 통합 테스트와 점진적 배포(예상 5일)

계산해 보니 아무리 빨라도 35일은 필요했습니다. 시행착오로 인한 재작업 시간은 포함하지도 않은 수치였습니다.

하지만 제게 주어진 시간은 14일뿐이었습니다.

Claude Code를 선택한 이유

사실 AI를 사용하기로 결정하기 전까지 저도 확신이 없었습니다.

시중에는 AI 코딩 도구가 많습니다. GitHub Copilot은 계속 사용해 왔고, Cursor도 좋은 평가를 많이 들었습니다. Claude Code는 비교적 낯선 도구였습니다. 그렇다면 왜 최종적으로 Claude Code를 선택했을까요?

작은 실험을 해 봤습니다

반나절을 들여 프로젝트에서 가장 복잡한 함수를 하나 골랐습니다. 각종 경계 조건, 비동기 호출, 오류 처리가 들어간 200줄이 넘는 주문 상태 업데이트 로직이었습니다. 그런 다음 세 도구에 각각 리팩터링을 요청했습니다.

결과는 꽤 흥미로웠습니다.

  • GitHub Copilot: 제안이 단편적이었고 코드 자동 완성 도구에 더 가까웠습니다. 한 줄씩 방향을 제시해야 했기 때문에 이런 대규모 리팩터링에는 한계가 있었습니다.
  • Cursor: 성능은 좋았습니다. 제 의도를 이해했고 리팩터링 제안도 비교적 합리적이었습니다. 하지만 복잡한 비즈니스 로직을 처리할 때 가끔 맥락을 잘못 이해해 여러 번 다시 설명해야 했습니다.
  • Claude Code: 눈에 띄는 결과를 보여 줬습니다. 코드를 리팩터링하는 데 그치지 않고 잠재적인 버그 세 개를 능동적으로 찾아냈고, 리팩터링 전에 테스트 케이스부터 작성하라고 제안했으며, 상세한 리팩터링 단계까지 설명했습니다.

가장 중요한 부분은 컨텍스트 이해 능력이었습니다. Claude Code는 200K token 컨텍스트 윈도우를 지원합니다. 이것이 무엇을 의미할까요? 프로젝트의 핵심 코드를 한 번에 모두 입력할 수 있고, 개별 파일만 보는 것이 아니라 모듈 간의 관계까지 이해할 수 있다는 뜻입니다.

"Claude Code의 200K token 컨텍스트 윈도우에는 약 15만 자 분량의 코드를 담을 수 있어 중형 프로젝트 전체의 핵심 비즈니스 로직과 모듈 관계를 이해하기에 충분합니다."

리팩터링 실전: 14일을 어떻게 보냈나

이제 핵심 내용을 다루겠습니다. 14일 동안 진행한 구체적인 작업 단계와 겪었던 시행착오를 모두 소개하겠습니다.

사전 준비: 안전망 구축(Day 1-2)

리팩터링에서 가장 두려운 일은 문제를 만드는 것입니다. 따라서 첫 단계부터 코드를 서둘러 수정하지 않고 먼저 안전망을 구축했습니다.

작업 1: 테스트 케이스 보강

Claude Code에 처음 맡긴 작업은 테스트 케이스 생성이었습니다.

나: 다음은 주문 모듈의 핵심 코드입니다(코드 3,000줄 붙여넣기).
핵심 비즈니스 프로세스를 분석하고 완전한 테스트 케이스를 생성해 주세요.
주문 생성, 결제, 환불, 상태 전환 등의 시나리오를 중점적으로 다뤄 주세요.

솔직히 Claude의 결과는 기대 이상이었습니다. 단위 테스트를 생성했을 뿐만 아니라 비즈니스 시나리오별로 친절하게 분류하고, 각 테스트에 명확한 주석도 달았습니다. 경계 조건을 조금 수정한 것만으로 이틀 만에 테스트 커버리지를 10%에서 45%까지 높였습니다.

기존 방식이었다면 이 작업만 최소 일주일은 걸렸을 것입니다.

작업 2: 코드 진단

테스트로 기반을 다졌으니 다음 단계는 코드 문제를 전반적으로 진단하는 것이었습니다. Claude Code에 전체적인 ‘건강 검진’을 요청했습니다.

나: 이 프로젝트의 코드 품질 문제를 분석해 주세요.
코드 스멜, 중복 로직, 성능 병목, 잠재적인 버그를 중점적으로 살펴보고
상세한 진단 보고서를 작성해 주세요.

스캔이 끝난 뒤 20페이지 분량의 보고서를 받았습니다. 실제로 출력했더니 20페이지였습니다. 보고서에는 다음 내용이 담겨 있었습니다.

  • 코드 스멜 87개(지나치게 긴 함수, 너무 깊은 중첩, 일관성 없는 이름 등)
  • 중복 로직 23곳
  • 잠재적인 성능 문제 14개
  • 발생 가능성이 있는 버그 5개(이 중 2개는 나중에 실제 버그로 확인)

이 보고서가 그대로 리팩터링 로드맵이 됐습니다.

리팩터링 실행: 사람과 AI가 협업하는 기술(Day 3-10)

본격적인 리팩터링을 시작한 뒤 Claude Code와 협업하는 나름의 리듬을 서서히 찾아갔습니다.

리듬 1: 가장 고통스러운 부분부터 시작하기

처음 손댄 대상은 800줄짜리 processOrder 함수였습니다. 이 함수에는 매개변수 검증, 재고 확인, 할인 계산, 결제 호출, 알림 발송 등 주문 생성에 필요한 모든 로직이 한데 들어 있었습니다. 유지보수하기에는 악몽 같은 구조였습니다.

Claude에는 다음과 같이 요청했습니다.

나: 이 processOrder 함수는 지나치게 비대합니다. 다음 요구 사항에 맞춰 리팩터링해 주세요.
1. 단일 책임을 가진 작은 함수로 분리
2. 각 함수는 50줄 이내로 제한
3. 공통 로직은 유틸리티 클래스로 추출
4. 기존 기능과 100% 호환성 유지
5. 새 함수마다 해당 테스트 케이스 생성

Claude는 매우 상세한 리팩터링 방안을 제시하고 800줄을 여섯 개의 독립된 함수로 나눴습니다.

  • validateOrderParams() - 매개변수 검증
  • checkInventory() - 재고 확인
  • calculateDiscount() - 할인 계산
  • processPayment() - 결제 처리
  • sendNotifications() - 알림 발송
  • createOrder() - 주요 흐름 조정

각 함수의 책임이 명확해져 테스트하기도 훨씬 편해졌습니다. 이 함수 하나를 기존 방식으로 리팩터링했다면 3일은 걸렸겠지만, Claude Code를 사용하니 반나절 만에 끝낼 수 있었습니다.

품질 보증: 생략할 수 없는 검증 단계(Day 11-13)

코드를 고쳤다고 끝난 것이 아닙니다. 진짜 중요한 것은 검증입니다. 이 사흘 동안은 오직 다양한 테스트에 집중했습니다.

1단계: 자동화 테스트
먼저 전체 테스트 스위트를 실행했습니다.

  • 단위 테스트: 187개 케이스 모두 통과
  • 통합 테스트: 34개 시나리오, 통과율 100%
  • E2E 테스트: 핵심 비즈니스 프로세스 전체 실행

이 단계에서도 Claude Code의 도움이 컸습니다. 앞서 생성해 둔 테스트 케이스가 제대로 역할을 했습니다.

2단계: 코드 리뷰
Claude에 자동화 리뷰를 요청했더니 실제로 두 가지 문제를 찾아냈습니다. 하나는 변수 이름이 규칙에 맞지 않는 문제였고, 다른 하나는 비동기 호출에서 예외를 처리하지 않은 문제였습니다.

배포와 모니터링: 가장 긴장됐던 순간(Day 14)

10월 25일 금요일 오후 3시, 비즈니스 트래픽이 적은 시간이었습니다.

점진적 배포 전략을 선택했습니다.

  • 3:00 트래픽 5%에 배포하고 30분 동안 모니터링
  • 3:30 문제가 없어 10%로 확대
  • 4:00 30%로 추가 확대
  • 5:00 전체 배포

배포 내내 모니터링 대시보드를 지켜보느라 손에 땀이 났습니다. 팀원들도 모두 온라인으로 대기하면서 언제든 롤백할 준비를 했습니다.

모든 모니터링 지표가 초록색으로 표시되고 평균 API 응답 시간까지 450ms에서 360ms로 줄어든 것을 확인한 뒤에야 안도의 한숨을 내쉴 수 있었습니다.

최종 결과:

  • 운영 사고 0건
  • API 응답 시간 20% 개선
  • 버그 발생률 40% 감소
  • SonarQube 코드 품질 등급 C에서 A로 향상
  • 테스트 커버리지 10%에서 75%로 향상

효율적인 프롬프트 템플릿 모음

실전 경험을 바탕으로 정리한 네 가지 프롬프트 템플릿입니다. 복사한 뒤 필요한 부분만 바꿔 바로 사용할 수 있습니다.

템플릿 1: 코드 진단

[기술 스택]을 사용하는 [프로젝트 유형] 프로젝트가 있습니다.
다음은 핵심 비즈니스 코드입니다. [코드 붙여넣기]

다음 항목을 중심으로 전체적인 진단을 진행해 주세요.
1. 코드 스멜(지나치게 긴 함수, 너무 깊은 중첩, 일관성 없는 이름 등)
2. 중복 로직과 공통 코드로 추출할 수 있는 부분
3. 잠재적인 성능 병목
4. 발생 가능한 버그와 보안 취약점

상세한 보고서를 작성하고 우선순위에 따라 정렬해 주세요.

템플릿 2: 리팩터링 실행

다음 코드를 리팩터링해 주세요. [코드 붙여넣기]

리팩터링 요구 사항:
1. 단일 책임을 가진 작은 함수로 분리하고 각 함수는 [50]줄 이내로 제한
2. 중복 로직은 유틸리티 클래스로 추출
3. 이름을 개선하고 [팀 규칙] 준수
4. 기존 기능과 100% 호환성 유지
5. 새 함수마다 해당 테스트 케이스 생성

중요한 제약 조건:
- 비즈니스 로직은 변경하지 말고 코드 구조만 수정
- 명확한 설명이 없는 한 새 의존성 패키지 추가 금지
- 용도가 확실하지 않은 코드는 삭제하지 말고 제가 확인할 수 있도록 표시
- 프로젝트의 기존 코드 스타일 준수: [스타일 설명]

관련 컨텍스트:
[관련 호출부 코드와 데이터 구조 정의 등 붙여넣기]

템플릿 3: 테스트 생성

다음은 제 [모듈 이름]의 핵심 코드입니다. [코드 붙여넣기]

다음 요구 사항에 맞춰 완전한 테스트 케이스를 생성해 주세요.
1. [Jest/Vitest 등 테스트 프레임워크 이름] 사용
2. 주요 비즈니스 시나리오 다루기: [핵심 시나리오 나열]
3. 경계 조건 테스트 포함(null 값, 비정상 입력, 극값 등)
4. 예외 시나리오 테스트 포함(네트워크 타임아웃, API 오류 등)
5. 각 테스트 케이스에 테스트 목적을 설명하는 명확한 주석 추가

테스트 커버리지 목표: >70%

템플릿 4: 코드 리뷰

코드 리팩터링을 마쳤습니다. 다음 내용을 검토해 주세요.

기존 코드: [붙여넣기]
리팩터링 후 코드: [붙여넣기]

다음 항목을 중점적으로 확인해 주세요.
1. 새로운 버그나 로직 오류가 생겼는지
2. 성능 문제(불필요한 반복문이나 계산 등)가 있는지
3. [팀 규칙]을 준수하는지
4. 보안 취약점(SQL 인젝션, XSS 등)이 있는지
5. 이름과 주석이 명확하고 이해하기 쉬운지
6. 테스트 커버리지가 충분한지

상세한 검토 의견과 개선 방안을 제시해 주세요.

마치며

10월 초 이 작업을 맡았을 때의 불안감을 떠올리며 지금 리팩터링된 코드를 보면, 큰 고비를 넘기고 살아남은 듯한 기분이 듭니다.

14일, 코드 10,000줄. 엉망인 코드를 맡아 성공적으로 배포하기까지의 경험을 통해 AI 보조 개발을 완전히 새롭게 바라보게 됐습니다.

AI는 만능 해결책이 아닙니다. AI가 여러분 대신 의사결정을 하거나 비즈니스를 이해하거나 위험을 책임질 수는 없습니다. 하지만 매우 강력한 조력자입니다. 마치 경험 많은 시니어 엔지니어가 곁에 앉아 언제든 코드를 리뷰하고, 테스트를 생성하고, 문제를 지적해 주는 것과 같습니다.

진정한 효율 향상은 사람과 AI의 협업에서 나옵니다. 사람은 비즈니스에 대한 이해와 판단을 제공하고, AI는 실행 효율과 모범 사례를 제공합니다. 이렇게 협업하면 한 사람이 세 사람 분량의 일을 해내면서도 더 높은 품질을 달성할 수 있습니다.

비슷한 문제를 마주하고 있다면 다음과 같이 권하고 싶습니다.

  1. 시도를 두려워하지 마세요. 지금의 AI 도구는 충분히 성숙했습니다.
  2. 작은 단위로 빠르게 진행하세요. 작은 모듈 하나에서 시작해 AI의 작업 방식을 천천히 익히세요.
  3. 항상 경계하세요. AI는 강력하지만 완벽하지 않습니다. 사람의 검토는 절대 생략할 수 없습니다.
  4. 철저히 준비하세요. 테스트, 모니터링, 롤백 체계를 빠짐없이 마련해야 합니다.

기술 부채는 미룬다고 해결되지 않습니다. 일찍 갚을수록 빨리 편해집니다. Claude Code 같은 도구가 있다면 기술 부채를 갚는 일이 생각보다 고통스럽지 않고, 오히려 성취감까지 느낄 수 있습니다.


FAQ

AI로 코드를 리팩터링해도 믿을 만한가요? 버그가 생기지는 않나요?
AI 리팩터링에는 탄탄한 테스트와 사람의 검토가 함께 필요합니다.

이 사례에서는 다음과 같이 진행했습니다.
• 먼저 테스트 안전망을 구축했습니다(커버리지 10%에서 45%로 향상).
• 작은 단위로 빠르게 진행했습니다.
• 변경할 때마다 즉시 테스트했습니다.
• 그 결과 운영 환경에서 사고가 한 건도 발생하지 않았습니다.

핵심은 AI에 전적으로 의존하는 것이 아니라 사람과 AI가 협업하는 것입니다.
GitHub Copilot 대신 Claude Code를 선택한 이유는 무엇인가요?
Claude Code의 장점:
• 200K token 컨텍스트 윈도우를 제공합니다.
• 프로젝트 전체의 모듈 관계를 이해할 수 있습니다.
• 대규모 리팩터링에서 버그를 능동적으로 식별하고, 모범 사례를 제안하며, 상세한 리팩터링 단계를 제공합니다.

Copilot:
• 코드 자동 완성에 더 적합합니다.
• 복잡한 리팩터링에는 한계가 있습니다.
10,000줄의 코드를 14일 만에 리팩터링한 구체적인 과정은 무엇인가요?
네 단계로 진행했습니다.

Day 1-2 안전망 구축:
• 테스트 보강 및 문제 진단

Day 3-10 리팩터링 실행:
• 가장 고통스러운 부분부터 작은 단위로 빠르게 개선

Day 11-13 품질 보증:
• 자동화 테스트, 코드 리뷰, 샌드박스 검증

Day 14 점진적 배포
본문의 프롬프트 템플릿은 어떻게 사용하나요?
본문에서는 재사용 가능한 네 가지 템플릿을 제공합니다.
• 코드 진단
• 리팩터링 실행
• 테스트 생성
• 코드 리뷰

사용 방법:
• 각 템플릿에는 [프로젝트 유형], [기술 스택]과 같은 자리표시자가 있습니다.
• 해당 부분을 자신의 프로젝트 정보로 바꾸면 됩니다.

먼저 코드 진단 템플릿으로 프로젝트의 문제를 파악하는 것을 권합니다.
리팩터링 중 새로운 버그가 생기는 것을 어떻게 방지하나요?
다섯 가지 핵심 원칙이 있습니다.

1) 테스트 우선(테스트를 보강한 뒤 리팩터링)

2) 작은 단위로 빠르게 진행(한 번에 모듈 하나만 변경)

3) 자주 검증(변경 직후 테스트 실행)

4) 점진적 배포(트래픽 5%부터 시작)

5) 사람의 재검토(AI가 생성한 코드는 반드시 사람이 검토)

1분 읽기 · 게시일: 2025년 11월 25일 · 수정일: 2026년 9월 4일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog