자동화 slecs

결제 출금 자동승인 관리자 제어

목차

admin-partner 영역에 출금요청 허용·자동승인 관리자 전용 제어를 이관하고, 트리 뷰를 새로 붙였다. 변경 파일은 내부 클래스 2개, 뷰/스타일 2개, SQL 매퍼 1개. 숫자로 보면 소박한데 실제 작업은 그렇지 않았다.

왜 이 기능이 필요했나

기존 화면과 API는 출금 흐름을 보여주긴 했지만, 관리자가 직접 "허용 여부"와 "자동승인 여부"를 제어하는 지점이 없었다. 운영 쪽에서 특정 파트너의 출금 조건을 즉각 바꿔야 하는 상황이 생겼을 때, 코드 배포 없이 처리할 방법이 없다는 게 문제였다. 관리자 페이지 어딘가를 뒤지거나, 직접 DB를 건드리거나 둘 중 하나였던 것.

그래서 이번에 제어권을 admin-partner 화면으로 명시적으로 올렸다. 단순 UI 추가가 아니라 쿼리 레벨부터 설계해서 정합성을 맞춰야 했다. 화면만 만들어 놓고 뒷단 상태가 따로 놀면 관리자는 버튼을 눌렀는데 실제로 아무것도 바뀌지 않는 상황이 생긴다. 그게 더 위험하다.

설계 시 신경 쓴 것들

금융/결제 도메인에서 데이터 정합성은 선택지가 아니다. 기본값이다. 새 기능을 붙일 때마다 체크하는 항목이 몇 개 있는데, 이번에도 그대로 따랐다.

항목 이번 판단
실시간 갱신 필요 여부 관리자 조작 즉시 반영, 폴링 불필요
NULL·빈 데이터 방어 파트너 설정 미존재 케이스 방어 처리
권한 없는 접근 admin-partner 롤 체크 레이어에서 차단
쿼리 실행 계획 기존 매퍼 패턴 따르고 실행계획 사전 확인

트리 뷰를 추가한 이유는 파트너가 계층 구조를 가지고 있어서다. 플랫 리스트로 보여주면 부모-자식 관계가 묻혀서, 상위 파트너 설정이 하위에 어떻게 전파되는지 한눈에 파악이 안 된다. 트리로 렌더링하면 계층 상태가 시각적으로 바로 보인다. UI 욕심이 아니라 운영 실수를 줄이기 위한 선택이다.

SQL 매퍼 쪽은 기존 패턴을 최대한 유지했다. 새 메서드를 추가할 때 기존 결과셋 구조와 살짝만 달라도 뷰에서 바인딩이 꼬이거나, 다른 화면에서 같은 데이터를 다른 값으로 보여주는 사고가 난다. 아래처럼 조회 결과를 명시적으로 타입 지정된 모델에 매핑하는 방식을 고수한 이유다.

<!-- SQL 매퍼 패턴 예시 (실제 코드 아님) -->
<select id="selectPartnerWithdrawalConfig" resultType="PartnerWithdrawalConfig">
    SELECT
        partner_id,
        allow_withdrawal,
        auto_approve_yn,
        updated_at
    FROM partner_withdrawal_config
    WHERE partner_id = #{partnerId}
</select>

resultType을 Map으로 때우면 편한데, 필드명 오타가 런타임에서야 터진다. 그냥 클래스 하나 더 만드는 게 낫다.

내부 클래스 2개에 메서드를 추가하면서 기존 로직과 충돌 여부도 확인했다. 특히 자동승인 상태 변경 시 기존 출금 대기 건들이 어떻게 처리되는지 흐름을 쭉 따라가봤다. 설정을 바꿨을 때 "이미 대기 중인 건"에 소급 적용이 되는지, 아니면 이후 건부터 적용되는지 - 이게 명확하지 않으면 숫자가 화면마다 달라진다.

구현하고 나서

구현 후 직접 화면에서 동작 확인했고, 관련 화면 숫자를 cross-check했다. 출금 집계가 나오는 화면이 2~3군데 있는데 각각 같은 값을 보여주는지 대조하는 게 필수다. 금융 도메인은 숫자 하나 틀리면 신뢰가 무너진다. "대충 맞는 것 같다"로 넘어가면 반드시 나중에 다시 돌아온다.

개발 방식으로 정해둔 루틴도 그대로 따랐다.

  • 변경 전 현재 화면 수치 메모
  • 수정 후 같은 케이스로 재확인
  • 관련 화면 있으면 숫자 cross-check
  • 커밋 메시지는 "무엇을"보다 "왜"를 담으려고 노력

커밋은 논리적으로 독립된 단위로 쪼갠다. SQL 매퍼 추가, 클래스 메서드 추가, 뷰 렌더링 연동을 한 커밋에 몰아넣으면, 나중에 숫자가 이상할 때 어느 지점에서 깨졌는지 추적이 힘들어진다. 작은 커밋이 귀찮아 보여도 디버깅 시간으로 따지면 훨씬 싸다.

사내 서비스 만들다 보면 기능 하나가 버튼 하나 추가로 끝나는 경우가 거의 없다는 걸 계속 체감한다. SQL 집계, 상태 처리, 예외 방어, 화면 렌더링, 권한 체크가 다 엮여 있고, 어느 하나만 빠뜨려도 특정 케이스에서 이상한 결과가 나온다. 이번 작업도 마찬가지였다.

댓글 0

첫 댓글 달아줘.