일기 slecs

출금 요청 코드 기술 부채 정리로 유지보수성 개선

목차

출금 요청 도메인은 서비스에서 가장 민감한 영역 중 하나다. 돈이 움직이는 흐름이라 기능 버그는 곧 장애로 직결되고, 그래서 역설적으로 코드를 건드리기가 제일 꺼려지는 곳이기도 하다. 그 결과 기능을 추가할 때마다 "일단 동작하게만" 만들어두고, 구조 개선은 나중으로 미루는 패턴이 반복됐다. 이번 작업은 그렇게 쌓인 것들을 한 번 털어낸 것.

어디서부터 손댈지 고르는 게 반 이상

기술 부채 정리에서 제일 어려운 건 막상 건드리는 게 아니라 어디서부터 건드릴지 고르는 거다. 손이 가는 데는 많은데, 한꺼번에 다 고치려 하면 PR 리뷰도 힘들고 무엇보다 "뭔가 잘못됐을 때 원인 찾기"가 너무 어려워진다. 이번엔 출금 요청 흐름에서 서로 논리적으로 묶이는 변경끼리 단위를 나눠서 진행했다.

정리 대상을 고를 때 기준으로 삼은 건 세 가지였다.

  • 이름만 봐서는 역할을 모르겠는 것: 변수명이나 함수명이 작성 당시 컨텍스트에서만 이해되는 케이스. 출금 관련 도메인에서 이런 게 쌓이면 신규 작업자가 코드 탐색에만 시간을 다 쓴다.
  • 같은 로직이 두 군데 이상 흩어진 것: 하나 수정하면 다른 하나를 빠트리는 패턴이 만들어진다. SQL 쿼리에서 특히 이런 게 많았음.
  • 파일 하나가 너무 많은 일을 하는 것: 컨트롤러가 비즈니스 로직을 들고 있거나, 뷰 레이어에서 데이터 가공을 하거나.

이 기준에 맞춰 이번에 손댄 파일은 총 3개. 작아 보이지만 이 정도 범위면 변경 후 검증이 현실적으로 가능하다.

실제로 뭘 바꿨나

변경 유형별로 정리하면 아래와 같다.

변경 유형 내용
중복 제거 SQL 쿼리 내 반복 조건 로직 통합
이름 변경 역할이 불명확한 변수·함수명 → 의도가 드러나는 이름으로
파일 삭제 호출되지 않는 dead code 제거
컨트롤러 분리 비즈니스 판단 로직을 컨트롤러 밖으로 이동
뷰 레이어 정비 네이밍 컨벤션 불일치 통일

코드 패턴 예시로 이름 변경 방향을 보면 이런 식이다.

# 변경 전: 이름에서 의도를 읽기 어렵다
def process(req, flag, tmp):
    if flag:
        tmp = calc(req.amount)
    ...

# 변경 후: 파라미터명만 봐도 역할이 드러난다
def process_withdrawal_request(request, is_manual_review, fee_amount):
    if is_manual_review:
        fee_amount = calculate_withdrawal_fee(request.amount)
    ...

SQL도 비슷하다. 조건 블록이 두 쿼리에 각각 있던 걸 공통 서브쿼리나 뷰로 빼내는 방식. 쿼리 중복은 방치할수록 "한 쪽만 수정하고 다른 쪽은 빠트리는" 버그가 나오기 딱 좋은 구조라 이번에 확실히 정리했음.

리팩토링은 결국 "다음 사람에 대한 배려"

변경 후 기존 출금 요청 기능이 이전과 동일하게 동작하는지 확인했고, 추가로 코드 탐색 시 체감도 확연히 달라졌다. 전에는 같은 기능을 고치려면 컨트롤러, 쿼리 파일, 뷰 쪽을 각각 열어서 관련 부분을 연결해 읽어야 했는데, 정리 후에는 수정 포인트가 명확하게 드러나서 작업 시간이 줄었다.

항목 정리 전 정리 후
출금 로직 탐색 시간 여러 파일 횡단 필요 수정 포인트 명확
쿼리 조건 수정 두 곳 동시에 손대야 함 단일 지점 수정
코드 리뷰 난이도 컨텍스트 파악 비용 높음 이름만 봐도 흐름 파악 가능
잠재적 버그 경로 중복 로직에서 발생 여지 있음 중복 제거로 경로 차단

리팩토링을 자주 하면서 느끼는 건, 코드는 처음부터 완벽하게 나올 수 없다는 거다. 요구사항도 바뀌고, 작업자의 이해도도 달라지고, 팀의 네이밍 컨벤션도 시간이 지나면 진화한다. 그래서 "한번 만들면 끝"이 아니라 주기적으로 다듬는 게 자연스러운 유지보수 사이클이라고 생각한다.

기술 부채를 미루면 이자가 붙는다는 표현이 있는데, 출금 도메인에서는 그 이자가 기능 수정 속도 저하 + 버그 위험 증가 + 신규 합류 시 온보딩 비용으로 돌아온다. 이번에 정리한 3개 파일은 그 이자를 조금 갚은 셈이다.

기능을 새로 추가하는 커밋이 아니라서 티가 잘 나진 않지만, 이런 작업이 쌓여야 다음에 기능을 넣을 때 속도가 붙는다. 그걸 알기 때문에 계속 하게 된다.

댓글 0

첫 댓글 달아줘.