개발 slecs

파트너 포탈에 결제 잔액 조회 기능 추가

목차

파트너 포탈에 결제 잔액 조회 기능을 추가했다. 변경된 파일은 내부 클래스 하나, 뷰/스타일 파일 하나. 숫자만 보면 작은 작업인데, 실제로는 쿼리 레벨부터 다시 잡아야 했다.

기존 대시보드 API는 파트너사가 필요한 잔액 데이터를 내려주지 않았다. 화면이 없었다기보다, 그 데이터 자체가 설계에 포함되지 않았던 것. 그래서 단순히 JSP 한 장 추가하는 게 아니라 백엔드 엔드포인트를 새로 만들고, 집계 쿼리를 짜고, 권한 인터셉터를 통과시키는 흐름 전체를 붙여야 했다. 사이드바 메뉴 활성화도 포함해서.

금융 도메인에서 '화면 하나 추가'가 의미하는 것

결제 관련 기능을 만들다 보면 숫자 하나가 틀리는 순간 신뢰가 흔들린다는 걸 계속 체감하게 된다. 특히 파트너사가 보는 잔액은 내부 정산 화면에서 보이는 값과 반드시 일치해야 한다. "대충 비슷한 것 같다"는 검증이 아님.

그래서 설계할 때 가장 먼저 따진 게 데이터 출처였다. 같은 숫자가 시스템 내에서 두 곳 이상에서 조회된다면, 쿼리 두 개가 정확히 같은 집합을 바라보는지 확인해야 한다. 집계 기준이 살짝 다르거나 NULL을 다루는 방식이 다르면 숫자가 미묘하게 달라진다. 이게 운영 중에 발견되면 단순 버그가 아니라 신뢰 이슈가 된다.

실시간 갱신 여부도 결정해야 했다. 폴링이냐 이벤트 기반이냐는 데이터의 성질에 따라 다른데, 잔액처럼 "방금 결제가 들어왔으면 반영이 되어야 하는" 데이터는 폴링이 더 단순하고 안전하다. 이벤트 기반은 빠르지만 놓치는 케이스가 생기기 쉽고, 그걸 보완하는 코드가 결국 더 복잡해진다. 여기선 실시간 요구사항이 강하지 않아서 갱신 버튼 + AJAX 조합으로 정리했다.

예외 케이스 방어는 별도로 정리해뒀다.

케이스 처리 방향
잔액 데이터가 NULL 0으로 렌더링, 서버 오류 응답과 구분
파트너 계정이지만 잔액 미조회 권한 인터셉터에서 403, 화면 진입 자체 차단
API 응답 지연 / 타임아웃 로딩 상태 표시 후 재시도 유도
데이터가 비어 있는 신규 파트너 빈 상태 UI 별도 처리, "데이터 없음" 명시

쿼리도 실행 계획을 사전에 확인했다. 대시보드에서 실행되는 쿼리는 파트너가 로그인할 때마다 돌아가는 거라서, 풀 스캔이 들어가 있으면 나중에 반드시 문제가 생긴다. 파트너 수가 늘어날수록 부하가 선형으로 올라가기 때문에 인덱스 타는지 먼저 확인하고 들어갔다.

구현 흐름: 뒤에서 앞으로

실제 구현 순서는 백엔드 먼저, 프론트 나중이었다. 화면을 먼저 그리면 API 스펙이 화면에 끌려다니는 경향이 있어서, 내부 클래스에서 데이터 구조를 확정하고 엔드포인트를 만든 다음에 JSP를 연결했다.

대략적인 흐름:

[파트너 로그인]
  → 사이드바 메뉴 렌더링 (잔액 조회 메뉴 활성화)
  → /partner/balance 요청
  → 권한 인터셉터 통과 확인
  → BalanceService.getBalance(partnerId)
  → 집계 쿼리 실행
  → JSON 응답
  → AJAX로 화면 업데이트

내부 클래스를 하나 수정한 게 이 흐름의 중간 어딘가다. 기존 서비스 클래스에 메서드를 추가하는 방식으로 갔는데, 완전히 새 클래스를 만들 정도로 책임이 분리되는 케이스는 아니었다. 잔액 조회는 기존 파트너 도메인 컨텍스트 안에서 자연스럽게 확장되는 기능이라서.

JSP + AJAX 조합은 지금 보면 구식처럼 느껴질 수 있는데, 포탈 전체가 이 스택으로 되어 있으면 굳이 이 기능만 다른 방식으로 뽑을 이유가 없다. 기술 스택은 일관성도 중요함. 코드를 리뷰하는 사람이나 나중에 유지보수하는 사람 입장에서, 화면마다 다른 방식으로 되어 있으면 더 피곤하다. 새로 도입하는 기술은 그 부채를 감당할 수 있는 범위에서 결정해야 한다.

검증 방식과 커밋 습관

구현 후 직접 화면에서 돌려봤다. 잔액이 맞게 나오는지만 확인한 게 아니라, 내부 정산 화면에서 보이는 값과 나란히 놓고 cross-check했다. 화면이 달라도 숫자가 같아야 하는 경우는 반드시 이렇게 비교해봐야 한다. 한 화면에서 맞아 보여도 다른 화면에서 다른 값이 나오면 어딘가에서 집계 기준이 어긋난 것이다.

검증 루틴은 이 정도를 기본으로 가져간다:

  • 변경 전에 현재 동작을 메모해두거나 스크린샷을 남긴다
  • 수정 후 같은 케이스로 다시 확인한다
  • 관련 화면이 있으면 숫자를 cross-check한다
  • 경계값(0, NULL, 음수, 최대값)을 직접 넣어봤는지 체크한다

커밋 메시지는 "무엇을 했는지"보다 "왜 했는지"를 담으려 한다. Add balance inquiry API보다는 파트너 포탈 잔액 미노출 해결 - 기존 API가 잔액 필드를 내려주지 않아 신규 엔드포인트 추가 쪽이 나중에 git blame 찍었을 때 의미가 있다. "무엇을"은 diff를 보면 다 나오니까 메시지에 중복으로 쓸 필요가 없다.

작은 커밋을 자주 하는 습관도 이번에 다시 유효하다고 느꼈다. 백엔드 추가, 쿼리 수정, 프론트 연동을 한 커밋에 묶어버리면 나중에 뭔가 틀렸을 때 어디서 깨진 건지 찾기 훨씬 어렵다. 논리적으로 독립된 단위로 쪼개두면 문제 발생 시 범위가 줄어들고, 코드 리뷰도 맥락이 명확해진다.

사내 포탈 기능이라 외부에서 보이는 변화는 없지만, 파트너사 입장에서는 대시보드에 숫자 하나가 생긴 것. 작은 변화처럼 보여도 SQL 집계, 예외 처리, 화면 렌더링, 권한 체크가 다 엮여 있어서 어느 하나 빠지면 특정 계정에서만 이상한 화면이 나타나거나, 내부 값과 숫자가 틀리거나, 권한 없는 접근이 허용되거나. 금융/결제 도메인에서 "대충 맞는 것 같다"로 넘어가면 반드시 다시 돌아온다. 그래서 꼼꼼함이 기본값이어야 한다는 걸 이번 작업에서도 다시 확인했다.

댓글 0

첫 댓글 달아줘.