개발 slecs

시스템 수익 대시보드에 파트너별 기여 현황 기능 추가

목차

system-revenue 영역에 파트너별 기여 현황 기능을 추가했다. 변경된 파일은 뷰/스타일 2개, 내부 클래스 1개, SQL 매퍼 1개로 수치만 보면 소박하지만, 실제로는 쿼리 설계부터 화면 렌더링까지 전 레이어를 건드린 작업이었음.

기존 수익 대시보드는 전체 집계 수치 중심으로 구성되어 있었다. 어느 파트너가 얼마나 기여하고 있는지를 파악하려면 별도 쿼리를 직접 돌리거나 엑셀로 뽑아야 했는데, 이게 반복 요청이 되니까 아예 화면에 녹이는 게 맞다고 판단했음. 단순히 테이블 하나 더 그리는 게 아니라 "이 숫자가 전체 합산과 일치하는가"를 보장해야 하는 작업이어서, UI보다 쿼리 설계를 먼저 잡았다.

SQL 매퍼부터 설계한 이유

금융/결제 도메인에서 집계 쿼리를 추가할 때 가장 경계하는 건 기존 집계와 결과가 달라 보이는 상황이다. 같은 데이터를 다른 방식으로 조회하면 반올림 차이, 타임존 경계, NULL 처리 방식에 따라 숫자가 미묘하게 달라질 수 있음. 그래서 파트너별 breakdown 쿼리를 작성할 때 기존 전체 합산 쿼리와 SUM을 맞춰보는 식으로 검증을 설계 단계에서 끼워 넣었다.

SQL 매퍼에서 신경 쓴 부분을 정리하면 이렇다:

  • 파트너 ID가 NULL인 레코드 처리 - COALESCE로 미지정 그룹으로 묶거나 명시적으로 제외할지 결정
  • 집계 범위(기간 파라미터) 기존 API와 동일하게 맞추기
  • 파트너가 0건인 경우 빈 결과 vs 0 반환 여부 - 화면에서 "데이터 없음"과 "0원"이 다르게 보여야 하면 구분 필요
  • 실행 계획 확인 - 파티션 인덱스를 타는지, Full Scan 경로가 없는지

쿼리를 짜고 나서 EXPLAIN으로 실행 계획을 한 번 뽑아 보는 게 습관인데, 집계 조건이 늘어날수록 옵티마이저가 예상과 다른 경로를 타는 경우가 종종 있다. 이번엔 기존 인덱스 범위 안에서 깔끔하게 처리됐음.

실시간 갱신 여부 결정

기능을 설계하면서 "이 데이터가 실시간으로 갱신되어야 하나"를 먼저 따졌다. 폴링으로 주기적으로 갱신할지, 이벤트 기반으로 수익 발생 시점에 밀어넣을지, 아니면 단순 요청 시 조회로 끝낼지.

파트너별 기여 현황은 운영 모니터링 성격이 강하고, 초 단위 실시간성이 필요한 데이터가 아니었다. 폴링이나 이벤트 파이프라인을 붙이면 인프라 복잡도만 올라가고 실제 사용 패턴과 맞지 않음. 그래서 요청 시 조회, 필요하면 캐시 레이어 추가 방향으로 결론을 냈다. 오버엔지니어링은 나중에 고치는 것보다 처음부터 안 하는 게 낫다.

내부 클래스에는 파트너별 기여 데이터를 가져오는 메서드를 추가했고, 기존 수익 조회 흐름과 독립적으로 호출되도록 설계했다. 의존성이 얽히면 테스트도 어렵고 이후 변경 시 영향 범위도 커지기 때문.

검증과 cross-check

구현하고 나서 화면에서 직접 확인하는 것과 별개로, 파트너별 합산이 전체 수익 집계와 일치하는지를 체크하는 게 이 작업의 핵심 검증 포인트였다.

확인 항목 방법
파트너별 합산 = 전체 합계 화면 수치 직접 비교
NULL/미매핑 파트너 처리 빈 파트너 케이스 직접 확인
기존 화면 수치 변화 없음 수정 전후 동일 조건 비교
권한 없는 접근 권한 다른 계정으로 접근 테스트

특히 기존 화면에서 보이던 숫자가 변하지 않았는지 확인하는 게 중요하다. 새 쿼리를 추가하면서 기존 쿼리에 조인이나 조건이 흘러 들어가는 실수는 생각보다 자주 일어나는 패턴이라, 관련 화면을 수정 전에 스크린샷이나 수치를 메모해 두고 수정 후 같은 케이스로 재확인하는 루틴을 유지하고 있음.


사내 서비스에서 기능 하나를 추가한다는 건 버튼 하나 올리는 게 아니라는 걸 이 작업을 하면서 또 실감했다. SQL 집계, 예외 처리, 화면 렌더링, 권한 체크가 모두 엮여 있어서 하나라도 빠뜨리면 숫자가 맞지 않거나 특정 조건에서 이상한 상태가 나타난다.

금융/결제 도메인은 특히 "대충 맞는 것 같다"로 넘기면 안 된다. 나중에 반드시 다시 돌아오는데, 그때는 원인 추적이 훨씬 어렵다. 처음에 꼼꼼하게 잡아두는 게 장기적으로 훨씬 싸게 먹힌다.

커밋은 논리적으로 독립된 단위로 쪼개는 습관을 유지하고 있다. 이번에도 SQL 매퍼 추가, 내부 클래스 메서드 추가, 뷰 연동 순서로 나눠서 올렸음. 문제가 생겼을 때 어느 변경에서 깨졌는지 bisect 하기가 훨씬 쉽고, 코드 리뷰할 때도 리뷰어 입장에서 맥락이 명확하다. 커밋 메시지는 "무엇을 했다"보다 "왜 이렇게 했다"를 담으려고 노력하는 중인데, 3개월 뒤 git log를 내가 다시 볼 때 "왜"가 없으면 맥락을 잃는다.

댓글 0

첫 댓글 달아줘.