☰ 분류

리팩터링 방향 상의하는 프롬프트

복잡해진 코드를 어떻게 정리할지 계획을 세웁니다. 한 번에 갈아엎지 않고 단계로 쪼개, 중간에 멈춰도 동작하게 합니다.

분류개발 › 코딩
태그분석검토개발자코드
프롬프트 (영어 본문 · 답은 한국어로 옵니다)
Plan a refactor of this code. ***Do not rewrite it.*** Plan only.

1. **Name the problems concretely.** Not "it is complex" — what, and why that is a problem.
2. Per problem, the direction **and what it gains and costs.**
3. Set the order:
   - ***It has to work after every step.*** **Do not plan a single big replacement**
   - Lowest risk first
   - If there are no tests, which tests have to exist first
4. **Name what should not be touched.** Working code does not get changed without a reason.
5. ***Judge whether this refactor is worth doing now. If it is not, say so.***
붙여 넣으면 맨 아래에 채울 칸(환경 · 코드 · 이유 · 테스트)이 나옵니다

어떤 프롬프트인가

한 번에 갈아엎는 리팩터링 계획은 중간에 멈추면 아무것도 못 쓰게 된다. 이 프롬프트는 각 단계 후에도 동작하도록 위험도 순으로 순서를 잡고, 손대지 말아야 할 부분을 따로 지목한다. 지금 할 값어치가 없으면 없다고 말한다.

모델 비교

ChatGPT는 정책 변경을 분리해 가장 안전하고 구체적이다. Gemini는 충실하지만 현행 동작 변경과 근거 없는 공수 추정이 아쉽고, [C]는 제공되지 않았다.

ChatGPT종합 1위
46/ 50

+ 현행 동작 보존과 정책 변경 분리가 특히 정확하다.

- 고액 확인 공통화는 이번 목표에 다소 불필요하다.

Gemini
39/ 50

+ 구체적 문제와 단계별 안전망을 명확히 제시했다.

- 미지원 수단 예외 추가가 현행 보존 원칙과 충돌한다.

기준ChatGPTGemini앞선 모델
지시 준수108ChatGPT +25%
정확성96ChatGPT +50%
구체성109ChatGPT +11%
구성·가독성99동점
분량 적정성87ChatGPT +14%

gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-24). 측정값이 아니라 AI 심사 결과입니다.

답 전문 보기

같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.

넣은 입력
환경: Node.js 18 + Express, 결제 모듈(paymentService.js), 실서비스 운영 중, 개발자 2명, 배포는 하루 1~2회

코드: // paymentService.js
function processPayment(order, method) {
  if (method === 'card') {
    if (order.amount > 500000) {
      verifyOwner(order.userId);
    }
    chargeCard(order);
  } else if (method === 'kakaopay') {
    if (order.isSubscription) {
      chargeKakaoRecurring(order);
    } else {
      chargeKakaoOnce(order);
    }
  } else if (method === 'bank') {
    if (order.amount > 500000) {
      verifyOwner(order.userId);
    }
    requestBankTransfer(order);
  } else if (method === 'point') {
    if (order.userPoint < order.amount) throw new Error('포인트 부족');
    deductPoint(order);
  }
  logPayment(order, method);
}

이유: 네이버페이를 새로 추가해야 하는데 이 if-else 분기가 8단계까지 얽혀 있어서 어디에 끼워 넣어야 할지 모르겠고, 잘못 건드리면 기존 카카오페이 결제가 깨질까봐 무섭습니다.

테스트: 테스트 코드 없음. 배포 전에 QA 담당자가 카드/카카오페이/계좌이체 3가지 시나리오를 스테이징에서 수동으로 결제해보는 게 전부입니다.
gpt-5.6-luna (codex CLI · 에이전트 하네스) · 실행일 2026-09-24

현재는 “대규모 구조 개선”보다 네이버페이 추가를 안전하게 가능하게 만드는 최소 refactor가 적절합니다. 운영 중이고 개발자가 2명뿐이므로, 자동 회귀 테스트를 먼저 확보한 뒤 작은 단위로 진행해야 합니다.

구체적인 문제

1. 결제수단 선택과 결제수단별 업무가 한 함수에 섞여 있음

processPayment가 다음을 모두 담당합니다.

  • 결제수단 판별
  • 고액 결제자 확인
  • 구독/일회성 분기
  • 잔액 검증
  • 실제 결제 호출
  • 결제 로그 기록

네이버페이를 추가할 때 기존 조건문을 직접 수정해야 하므로, 카카오페이 분기나 공통 로그 위치를 잘못 건드릴 위험이 큽니다.

  • 방향: 결제수단별 처리를 이름 있는 핸들러로 분리한 뒤, 결제수단과 핸들러를 매핑합니다.
  • 얻는 것: 네이버페이를 별도 핸들러로 추가할 수 있고, 기존 결제수단의 변경 범위가 작아집니다.
  • 비용: 함수와 파일 내 구조가 늘어나며, 핸들러 등록 누락 같은 새로운 실수가 생길 수 있습니다.

2. 고액 결제 확인 로직이 카드와 계좌이체에 중복됨

다음 로직이 두 곳에 반복됩니다.

if (order.amount > 500000) {
  verifyOwner(order.userId);
}

금액 기준이나 확인 정책이 바뀌면 두 분기를 모두 찾아 수정해야 하며, 한쪽만 수정될 가능성이 있습니다.

  • 방향: 고액 결제 확인을 작은 공통 함수로 추출합니다.
  • 얻는 것: 정책 변경 지점이 하나가 되고, 카드와 계좌이체의 동작 차이를 테스트하기 쉬워집니다.
  • 비용: 단순한 로직이 함수 호출 뒤로 한 단계 감춰집니다. 공통화가 실제로 필요한 결제수단 범위를 계속 관리해야 합니다.

3. 카카오페이 내부 분기가 결제수단 분기와 같은 함수에 중첩됨

kakaopay 안에서 다시 isSubscription을 검사합니다. 새 결제수단이 추가되거나 카카오페이의 결제 유형이 늘어나면 중첩이 계속 깊어집니다.

  • 방향: 카카오페이 핸들러 안에서만 구독/일회성 분기를 처리하도록 경계를 만듭니다.
  • 얻는 것: 최상위 함수는 “결제수단 선택”에 집중하고, 카카오페이의 정책은 카카오페이 코드 안에 모입니다.
  • 비용: 기존 함수에서 로직이 이동하므로 호출 순서와 예외 동작을 테스트로 고정해야 합니다.

4. 알 수 없는 method도 결제 로그가 기록됨

현재 지원하지 않는 결제수단이면 실제 결제는 하지 않지만 마지막의 logPayment(order, method)는 실행됩니다. 이것이 의도된 동작인지 불명확합니다. 잘못된 요청을 성공적으로 처리한 것처럼 보일 수 있습니다.

  • 방향: 이번 refactor에서 임의로 동작을 바꾸지 말고, 현재 동작을 테스트로 먼저 고정합니다. 이후 별도 정책 변경으로 “지원하지 않는 결제수단은 즉시 오류” 여부를 결정합니다.
  • 얻는 것: 구조 refactor와 비즈니스 정책 변경을 분리해 장애 원인을 추적하기 쉽습니다.
  • 비용: 당장은 이상해 보이는 동작을 그대로 유지해야 합니다.

5. 로그의 실행 시점이 중요한데 명시적으로 보호되어 있지 않음

결제 함수에서 예외가 발생하면 logPayment는 실행되지 않습니다. 반면 정상적으로 결제가 끝나면 모든 결제수단에서 로그가 실행됩니다. 이 동작은 결제 감사 로그인지, 시도 로그인지에 따라 의미가 달라집니다.

  • 방향: 이번에는 로그 위치를 바꾸지 않고 현재 성공/실패 시점을 테스트로 고정합니다.
  • 얻는 것: 카카오페이 동작을 보존하면서 안전하게 구조만 바꿀 수 있습니다.
  • 비용: 로그 정책의 문제는 별도 작업으로 남습니다.

테스트가 먼저 필요한 이유

현재 자동 테스트가 없으므로 코드 이동 자체가 카카오페이 회귀를 검출하지 못합니다. refactor 전에 최소한 다음 동작을 자동화해야 합니다.

  • 카드 일반 금액: chargeCard 호출, verifyOwner 미호출
  • 카드 50만 원 초과: verifyOwner 후 chargeCard
  • 카카오페이 일회성: chargeKakaoOnce만 호출
  • 카카오페이 구독: chargeKakaoRecurring만 호출
  • 계좌이체 일반/고액: 각각의 확인 동작
  • 포인트 잔액 부족: 오류 발생, deductPoint 미호출
  • 포인트 결제 성공: deductPoint 호출
  • 모든 정상 결제: logPayment 호출
  • 결제 함수가 실패할 때: 현재의 로그 동작을 명확히 고정
  • 알 수 없는 결제수단: 현재 동작을 테스트로 고정

외부 결제 API를 실제로 호출하지 않는 단위 테스트여야 합니다. chargeKakaoOnce 등을 가짜 함수나 mock으로 대체해 호출 순서와 호출 여부를 검증합니다. Node.js 18의 node:test와 assert를 사용할 수 있으므로, 별도 테스트 프레임워크를 도입하는 것부터 시작할 필요는 없습니다.

권장 진행 순서

각 단계는 별도 커밋으로 만들고, 각 단계 후 테스트와 기존 QA 시나리오를 통과시킵니다.

1단계: 현재 동작을 테스트로 고정

코드 구조는 바꾸지 않고 characterization test를 작성합니다.

  • 목표: “현재 무엇을 하는가”를 기록
  • 위험: 낮음
  • 완료 조건: 위 시나리오가 자동으로 재현됨

이 단계가 끝나면 테스트가 없는 상태로 구조를 옮기지 않아도 됩니다.

2단계: 고액 확인 로직만 공통 함수로 추출

예를 들어 verifyHighAmountOrder(order) 같은 내부 함수를 만들고, 카드와 계좌이체가 이를 호출하게 합니다.

  • 카드와 계좌이체의 테스트는 그대로 유지
  • 금액 기준과 호출 순서는 변경하지 않음
  • 별도 커밋 및 테스트

3단계: 결제수단별 처리 본문을 내부 함수로 추출

카드, 카카오페이, 계좌이체, 포인트 처리 내용을 각각 이름 있는 핸들러로 옮깁니다. 처음에는 기존 if-else 안에서 해당 핸들러를 호출하게 해도 됩니다.

즉, 한 번에 dispatch 구조로 바꾸지 않고 다음처럼 점진적으로 진행합니다.

  • 카드 분기만 카드 핸들러 호출
  • 테스트
  • 카카오페이 분기만 카카오페이 핸들러 호출
  • 테스트
  • 나머지 결제수단도 동일하게 진행

이렇게 하면 각 커밋 후에도 기존 if-else가 남아 있어 동작 경로를 비교하기 쉽습니다.

4단계: 네이버페이 핸들러를 먼저 별도로 추가

네이버페이의 실제 요구사항을 정한 뒤 별도 핸들러를 추가합니다.

확정해야 할 사항은 다음입니다.

  • 일회성 결제만 지원하는지
  • 구독 결제를 지원하는지
  • 50만 원 초과 시 소유자 확인이 필요한지
  • 실패 시 어떤 오류를 반환하는지
  • logPayment를 기존 결제수단과 같은 방식으로 기록하는지

네이버페이만 추가하고 기존 카드·카카오페이 로직은 변경하지 않는 것이 안전합니다. 네이버페이 단위 테스트를 먼저 추가한 후 라우팅에 연결합니다.

5단계: 모든 분기가 핸들러를 호출하게 된 후 dispatch map으로 변경

기존 결제수단의 동작이 핸들러로 옮겨지고 테스트가 통과한 뒤에만 다음 구조로 바꿉니다.

const handlers = {
  card: handleCard,
  kakaopay: handleKakaoPay,
  bank: handleBank,
  point: handlePoint,
  naverpay: handleNaverPay
};

processPayment는 다음 역할만 담당하게 합니다.

  1. 핸들러 조회
  2. 핸들러 실행
  3. 기존 로그 동작 유지

이때 알 수 없는 결제수단의 처리 방식은 별도 합의 전까지 바꾸지 않습니다.

6단계: 스테이징 QA 보강

자동 테스트 통과 후 기존 수동 QA에 네이버페이를 추가합니다.

  • 카드
  • 카카오페이
  • 계좌이체
  • 포인트
  • 네이버페이
  • 실패 및 중복 요청 등 운영상 중요한 케이스

배포 후에는 결제수단별 성공률과 오류 로그를 확인할 수 있어야 합니다.

이번에 건드리지 말아야 할 것

다음은 명확한 장애나 요구사항이 발견되지 않는 한 변경하지 않는 것이 좋습니다.

  • chargeCard, chargeKakaoOnce, chargeKakaoRecurring, requestBankTransfer, deductPoint의 내부 구현
  • 외부 결제 API 호출 방식
  • order 객체의 필드명과 구조
  • 결제 금액 기준 500000
  • 카카오페이의 구독/일회성 판정 규칙
  • logPayment의 형식과 저장 위치
  • Express 라우팅, 미들웨어, 인증 흐름
  • 오류 메시지와 오류 타입
  • 결제 트랜잭션, 재시도, idempotency 정책

이 항목들은 현재 작업의 목적이 아니며, 함께 바꾸면 장애 원인을 분리하기 어려워집니다.

지금 refactor할 가치가 있는가

가치는 있습니다. 네이버페이 추가가 예정되어 있고, 현재 구조에서는 결제수단을 추가할 때 기존 분기를 직접 수정해야 하므로 운영 리스크가 반복될 가능성이 높습니다.

다만 지금 할 범위는 다음으로 제한하는 것이 좋습니다.

  1. 현재 동작 자동 테스트 추가
  2. 중복 고액 확인 로직 정리
  3. 결제수단별 핸들러 분리
  4. 네이버페이 추가
  5. 테스트가 확보된 뒤 dispatch map으로 정리

결제 시스템 전체 재설계, 외부 API 추상화, 오류 정책 개편, 로그 시스템 변경까지 동시에 진행하는 것은 현재 팀 규모와 배포 빈도에 비해 위험하고, 이번 네이버페이 추가에 필요한 범위를 넘어섭니다.

같은 분류의 프롬프트

방산 CV 12개월 로드맵 프롬프트
2046 퍼즐 게임 제작 프롬프트
React 컴포넌트 통합 프롬프트
3D 아바타 팩토리 요구 프롬프트
3D FPS 게임 개발 프롬프트