개발 slecs

쿠폰 매출 정산 대시보드 집계 버그 수정

목차

쿠폰 매출 정산 대시보드에서 숫자가 맞지 않는다는 걸 발견했다. recalculateCouponRevenue 산식에서 LEGACY 분 데이터가 빠져 있었고, 수정은 SQL 매퍼 파일 하나였지만 원인을 추적하는 데 시간이 제법 걸렸다.

정산 관련 숫자는 틀려도 화면이 그냥 돌아가는 게 문제다. 에러를 뱉지 않고 조용히 틀린 값을 보여준다. 그래서 발견이 늦어지고, 발견했을 때는 이미 어느 시점부터 틀렸는지 역추적해야 한다.

원인 추적 과정

기대값과 실제값을 먼저 뽑아봤다. 어느 화면에서 얼마만큼 차이가 나는지, 그리고 그 차이가 특정 조건(기간, 쿠폰 유형, 사용자 세그먼트)에 따라 달라지는지 확인했다.

차이가 LEGACY 데이터가 있을 때만 발생한다는 걸 좁히는 데 시간이 걸렸다. 신규 발급 쿠폰은 집계가 맞는데, 이전 방식으로 생성된 쿠폰은 합산에서 빠지고 있었다. SQL 쿼리를 열어보니 JOIN 조건이 현재 스키마 기준으로만 걸려 있었고 LEGACY 레코드를 걸러낼 필터가 없었다 - 정확히는 포함해야 할 LEGACY 분을 아예 JOIN 대상에서 제외하고 있었다.

집계 쿼리에서 흔히 나오는 패턴 실수다.

-- 수정 전: 현행 타입만 집계
SELECT
  SUM(c.discount_amount) AS coupon_revenue
FROM coupon_usage cu
JOIN coupon c ON c.id = cu.coupon_id
WHERE c.coupon_type = 'STANDARD'
  AND cu.used_at BETWEEN :start AND :end

-- 수정 후: LEGACY 타입 포함
SELECT
  SUM(c.discount_amount) AS coupon_revenue
FROM coupon_usage cu
JOIN coupon c ON c.id = cu.coupon_id
WHERE c.coupon_type IN ('STANDARD', 'LEGACY')
  AND cu.used_at BETWEEN :start AND :end

실제 코드가 이것보다 복잡하긴 했지만 핵심은 같다. recalculateCouponRevenue 함수가 호출하는 매퍼에서 LEGACY 케이스를 누락하고 있었고, 산식 자체는 맞았으나 입력값이 불완전했다.

수정 후 검증 방법

수정 전 수치를 먼저 메모해뒀다. 수정 후 같은 쿼리 조건으로 재실행해서 차이를 확인하고, 관련 화면이 두 곳 이상 있어서 양쪽 숫자가 동일하게 바뀌는지 cross-check했다.

버그 수정 시 확인하는 것들을 정리하면 이렇다.

체크 항목 이유
같은 로직이 다른 매퍼/함수에 중복돼 있는지 한 곳만 고치면 나머지에서 같은 버그 재발
정상 케이스가 회귀되지 않는지 필터 추가로 오히려 데이터가 과잉 집계될 수 있음
수정 범위의 시간적 경계 어느 시점 이전 데이터부터 영향받았는지
연관 화면/API에서 숫자 일치 정산 데이터는 대개 여러 진입점에서 참조됨

이 중 세 번째가 생각보다 중요하다. 이번처럼 LEGACY 데이터 누락이라면 해당 쿠폰이 처음 발급된 시점부터 집계가 틀렸을 수 있다. 화면에서 확인되는 기간 외에도 히스토리 데이터가 영향받았는지 별도로 봐야 했다.

금융/결제 도메인 버그의 특성

기능 버그와 결이 좀 다르다. UI 버그는 틀렸을 때 바로 눈에 보이지만, 집계 버그는 숫자를 의심하지 않으면 그냥 넘어간다. 그래서 발견 경로가 주로 "뭔가 이상한 것 같다"는 감에서 시작하거나, 외부에서 문의가 들어오고 나서야 확인하게 된다.

이게 왜 귀찮냐면, 수정 자체는 SQL 한 줄 추가일 수 있는데 "언제부터 틀렸나", "얼마나 차이가 났나", "다른 집계에도 영향이 있나"를 전부 확인해야 하기 때문이다. 수정보다 검증에 더 시간이 들어가는 경우도 많다.

그래서 커밋 메시지를 "수정"이 아니라 "왜 이 산식에 LEGACY를 포함해야 하는지"로 적으려 했다. 나중에 같은 함수를 건드릴 때 맥락이 없으면 다시 빼버릴 수 있다.

작은 단위로 커밋을 쪼개는 것도 같은 이유다. 이번에도 원인 분석 커밋, 산식 수정 커밋, 검증 쿼리 정리 커밋을 분리했다. 나중에 git log만 봐도 어느 시점에 어떤 판단으로 바꿨는지 따라갈 수 있다. 로직이 복잡한 도메인일수록 이게 나중에 빛을 발한다. 6개월 뒤에 같은 파일을 열었을 때 "왜 이렇게 돼 있지?"가 아니라 "아, 그때 이래서 바꿨구나"가 되려면 커밋 메시지가 문서 역할을 해야 한다.

사내 서비스라고 해서 정산 숫자에 관대해지면 안 된다. 내부 사람들이 그 숫자를 보고 의사결정을 하고 있기 때문이다.

댓글 0

첫 댓글 달아줘.