수수료 정산 1원 오차, 반올림 정책 통일로 해결
목차
수수료 계산이 또 1원씩 어긋남
수수료 정산 결과가 가맹점별로 1~3원씩 어긋난다는 신고가 또 올라옴. 횟수가 누적돼서 더는 미룰 수 없었음. 원인 파보니 단순 버그가 아니라 구조 문제였음.
원인: scale 제각각
BigDecimal scale이 레이어마다 다르게 박혀있었음. 중간에서 반올림이 두 번 일어나는 구조라 끝자리가 흔들림.
| 레이어 | scale | 반올림 |
|---|---|---|
| 입력 받는 쪽 | 4 | HALF_UP |
| 계산 유틸 | 6 | HALF_EVEN |
| 저장 컬럼 | 2 | 자동 |
HALF_UP과 HALF_EVEN이 섞여 있는 것도 문제. 같은 0.5라도 결과가 갈림. 쓰던 사람마다 취향대로 깐 흔적이 그대로 남아있었음.
수정 방향
- 도메인 전체 scale을 6으로 통일, 저장 직전 단계에서만 2로 절사
- 반올림 모드는 HALF_UP 한 가지로 통일. 회계 정합성이 우선이라 통계적 반올림은 포기
- 컬럼 정의도 새 scale에 맞춰 DECIMAL(15,6)으로 ALTER. 기존 컬럼은 백업 컬럼으로 한 사이클 더 유지
old: rate.multiply(amount).setScale(2, HALF_UP)
new: rate.multiply(amount).setScale(6, HALF_UP)
// 영속화 직전 한 번만 2로 절사
잔존 코드 제거
수수료 정책이 두 번 바뀌면서 안 쓰는 메소드, 안 타는 분기, 주석 처리된 옛 계산식이 잔뜩 남아있었음. 이번에 같이 청소.
- 사용처 0건인 헬퍼 메소드 4개 삭제
- 6개월 전 폐기된 등급 코드 분기문 제거
- "// TODO: 추후 협의" 박힌 채로 호출되던 더미 계산식 제거
호출 그래프 다시 그려봤더니 죽은 코드가 생각보다 많았음. 살아있는 척하는 코드가 제일 위험함. 신규 입사자가 그걸 참고해서 새 분기 추가하면 그 순간부터 진짜 살아남.
검증
- 단위 테스트 케이스 30개 중 28개가 기존 결과와 1원 단위 일치. 차이 나는 2개는 scale 통일로 보정된 의도된 케이스
- 운영 데이터 샘플 1만 건 dry-run, 차이 발생 건은 모두 +1원 보정 방향. 누락분이 채워지는 형태라 회계 쪽 합의도 받음
남은 숙제
scale 통일은 됐지만 선차감/후정산 라벨링은 아직 손 못 댐. 표시 금액과 실제 차감 금액이 다른 케이스에서 사용자 혼동이 계속 들어오는 중. 다음 사이클에 정리 예정.
끝
댓글 0
첫 댓글 달아줘.