개발 slecs

정산 순수익 집계 오류와 파트너 모드 동기화 버그 수정

목차

admin/system-revenue/total-summary 화면의 순수익 집계 수치가 맞지 않는다는 걸 인지한 건 관련 화면을 병렬로 띄워두고 숫자를 비교하다가였다. 단순히 "다르네" 수준이 아니라, 파트너 모드가 활성화된 케이스에서만 특정 금액이 누락되거나 중복 산입되는 패턴이 있었다. 폴링 주기와 맞물려 타이밍에 따라 결과가 달라지는 것도 확인했다. 이쪽 도메인은 숫자 하나 틀리면 신뢰가 먼저 무너지기 때문에 원인을 끝까지 파고들기로 했다.

원인 추적

기대값과 실제값을 체계적으로 비교하면서 쿼리를 좁혔다. SQL 매퍼 두 곳에서 문제가 있었는데, 하나는 집계 조건 자체가 틀렸고, 다른 하나는 파트너 모드 상태를 필터링하는 JOIN이 빠져 있었다. 두 쿼리가 독립적으로 돌면서 각자 정상처럼 보이다가, 합산 단계에서 어긋나는 구조였다.

파트너 모드 동기화 문제는 폴링 간격 사이에 상태 변경이 발생하면 내부 클래스가 이전 스냅샷을 기준으로 계산을 이어가는 탓이었다. 폴링이 완료되기 전에 렌더링이 트리거되면 오래된 값을 그대로 화면에 뿌리고 있었다.

원인을 파악하고 나면 수정 범위가 보인다. 이번엔 SQL 매퍼 2개, 내부 클래스 로직, 뷰/스타일 1개를 건드렸다.

수정 포인트와 패턴

SQL 집계 수정에서 중요한 건 "조건을 추가했을 때 기존 정상 케이스를 망가뜨리지 않는지"다. 파트너 모드가 없는 일반 케이스와 파트너 모드 활성 케이스를 각각 검증해야 해서, 쿼리 수정 후 케이스를 나눠서 비교했다.

-- 수정 전: 파트너 모드 구분 없이 전체 집계
SELECT SUM(revenue) - SUM(cost) AS net_revenue
FROM settlement s
WHERE s.settled_at BETWEEN :from AND :to

-- 수정 후: 파트너 모드 상태를 JOIN하여 분기
SELECT
  SUM(s.revenue) - SUM(s.cost)
  - COALESCE(SUM(p.partner_fee), 0) AS net_revenue
FROM settlement s
LEFT JOIN partner_config p
  ON s.account_id = p.account_id
  AND p.mode = 'ACTIVE'
  AND p.effective_at <= s.settled_at
WHERE s.settled_at BETWEEN :from AND :to

실제 코드와 완전히 동일하지 않지만, 구조적으로 이런 방향이었다. LEFT JOIN을 썼을 때 NULL을 COALESCE로 처리하지 않으면 파트너 미등록 케이스에서 집계가 날아가기 때문에 그 부분을 함께 챙겼다.

내부 클래스 쪽은 폴링 완료 콜백 이후에만 렌더링 트리거가 실행되도록 순서를 조정했다. 상태가 확정되지 않은 시점에 UI를 그리는 게 근본 문제였다.

버그 수정 체크리스트와 회고

이 작업을 하면서 내가 반복적으로 쓰는 체크 흐름이 있다.

단계 확인 내용
범위 확인 동일 로직이 다른 매퍼나 서비스에 중복 있는지
회귀 방지 수정이 기존 정상 케이스를 깨지 않는지
실동작 검증 해당 화면·API에서 직접 버그 재현 후 정상 확인
수치 cross-check 관련 화면 여러 곳의 숫자가 정합한지

귀찮아 보여도 이 흐름을 건너뛰면 결국 같은 버그로 다시 돌아오게 된다. 특히 "범위 확인" 단계에서 이번에도 비슷한 패턴이 다른 매퍼에 하나 더 있었는데, 당장 터진 게 아니라서 지나치기 쉬웠다. 위험하다고 판단해서 함께 수정했다.

금융/정산 도메인에서 일하다 보면 기능 하나가 단순히 화면에 버튼 추가로 끝나지 않는다는 걸 매번 체감한다. SQL 집계, 상태 머신, 예외 처리, 화면 렌더링, 권한 체크가 전부 얽혀 있어서, 어느 하나만 빠뜨려도 숫자가 어긋나거나 특정 케이스에서 이상한 화면이 나온다. "대충 맞는 것 같다"는 감각은 이쪽에선 통하지 않는다.

커밋도 이번엔 SQL 수정, 내부 클래스 수정, 뷰 수정을 각각 나눠서 올렸다. 논리적으로 독립된 단위로 쪼개두면, 나중에 어느 변경에서 문제가 터졌는지 찾는 시간이 크게 준다. 커밋 메시지엔 "무엇을 바꿨는지"보다 "왜 이 조건이 필요했는지"를 적으려고 의식적으로 노력 중이다. 6개월 뒤에 git blame 돌려봤을 때 내가 이해할 수 있어야 하니까.

수정 후 버그를 직접 재현해서 정상 동작을 확인했고, 파트너 모드 활성·비활성 각각에서 관련 화면의 합계가 일치하는 것도 비교했다. 이쪽 화면은 숫자 하나가 틀리면 신뢰가 먼저 흔들리는 영역이라, 검증에 들이는 시간을 아끼지 않는 게 맞다.

댓글 0

첫 댓글 달아줘.