Skip to content
isdnetworks
Go back

상태를 바꾸는 게터

(수정됨)

출금 수수료 정책에 기본 수수료 0.0005 BTC 를 입력했는데 다른 화면에서는 0 으로 표시된다는 문의가 왔다.

Table of contents

Open Table of contents

증상 — 0.0005 와 0 이 함께 있는 상태

DB 부터 봤다.

SELECT base_fee, fee FROM fee_policies WHERE id = ?;
base_fee   0.00050000
fee        0.00000000

base_fee 와 fee 둘 다 값이 있는데 서로 다르다.

각 화면이 무엇을 표시하는지 확인하니 보는 컬럼이 갈려 있었다.

정책 목록      base_fee   →  0.0005
회원 상세      fee        →  0

같은 fee_policies 행인데 화면마다 다른 컬럼을 읽고 있었다.

원인 — 값을 대입하는 계산 게터

생성 화면의 코드를 열었다.

get withdrawFee() {
    if (this.policy.feePolicy === 'waived') {
        this.policy.fee = 0;                    // ← 대입
    } else {
        this.policy.fee = this.policy.baseFee;  // ← 대입
    }
    return this.policy.fee;
}

withdrawFee 는 계산해서 돌려주는 자리인데 this.policy.fee 에 값을 쓰고 있었다.

get 은 읽어서 계산한 값을 돌려주는 자리이고 읽는 쪽은 아무것도 안 바뀔 것으로 기대한다. 여기서는 읽는 동작이 다른 속성을 바꾸는 부수효과를 갖고 있었다.

전체 흐름 — 0이 저장된 경위

순서를 늘어놓으니 앞뒤가 맞았다.

운영자가 기본 수수료 0.0005 입력
운영자가 유형을 '면제'로 선택
    ↓
게터가 호출되며 fee = 0 대입
    ↓
저장
    ↓
base_fee = 0.0005
fee = 0

입력한 0.0005 는 base_fee 에 남고 fee 는 0 이 된다.

화면을 그리는 동안 withdrawFee 가 불리고 그때 대입이 일어난다. 사용자가 한 조작은 feePolicy 선택 하나인데 그것이 저장될 값까지 바꿔 놓은 것이다.

판단 기준 — 버그가 아니었다

두 컬럼의 뜻이 서로 달랐다.

기본 수수료  →  등급 할인율과 면제 한도를 계산하는 기준
청구액       →  실제로 회원 잔액에서 떼는 금액

feePolicy 가 waived 이면 fee 가 0 인 것이 맞다.

입력한 0.0005 는 사라진 것이 아니라 base_fee 에 다른 용도로 남아 있었다. 그러면 고칠 것은 계산이 아니라 그 사실이 화면에 안 보인다는 쪽이 된다.

대응 — 안내와 표시 추가

문의에는 안내로 답했다.

수수료 유형이 면제이므로 실제 청구 수수료가 0 으로 표시되는 것이 정상입니다.
입력하신 기본 수수료 0.0005 BTC 는 등급 할인과 면제 한도 계산의 기준으로만 사용됩니다.

정상입니다만 적으면 납득이 안 되므로 어디에 쓰이는지를 붙였다.

개선 대상도 함께 적었는데 로직을 고치는 것 대신 표시를 늘리는 쪽을 골랐다. 이유는 값은 설계대로인데 그 값이 어디 쓰이는지가 화면에 없어서다.

[표시 전]  청구액 0
[표시 후]  청구액 0 (기본 0.0005 · 면제 등급)

같은 데이터인데 base_fee 를 함께 보여 주면 오해가 없어진다.

회원 상세 모달에 기본 수수료 항목이 안 나오는 것이 혼란의 원인이었다. 화면이 가진 값을 다 보여 주지 않으면 사용자는 없어진 것으로 읽는다.

교훈 — 읽기와 쓰기를 나눈다

게터의 부수효과는 따로 적어 두었다.

get displayFee() {
    return this.policy.feePolicy === 'waived' ? 0 : this.policy.baseFee;
}

// 저장 직전에 별도로
prepareForSave() {
    this.policy.fee = this.displayFee;
}

displayFee 는 계산만 하고 대입은 prepareForSave 에서 한 번만 한다.

화면에 보여 줄 값과 저장할 값을 한 곳에서 처리하니 편했을 것이다. 대신 값을 확인했더니 값이 바뀌는 상태가 되어 디버깅할 때 짚기가 어려웠다.

조사 방법 자체는 단순했다. 저장 쪽과 표시 쪽을 각각 따라간 것이고 표시 쪽만 봤으면 왜 0인지에서 막혔을 것이다.

정리


Share this post on:

Previous Post
카나리 전에 다른 토큰을 센다
Next Post
플래그 하나를 두 기능이 쓴다