Skip to content
isdnetworks
Go back

상태를 바꾸는 게터

정책에 기본 금액 3,000원을 입력했는데 다른 화면에서는 0원으로 표시된다는 문의가 왔다.

Table of contents

Open Table of contents

증상 — 3,000과 0이 함께 있는 상태

DB 부터 봤다.

SELECT initial_delivery_fee, delivery_fee FROM policies WHERE id = ?;
initial_delivery_fee  3000
delivery_fee             0

initial_delivery_feedelivery_fee 둘 다 값이 있는데 서로 다르다.

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

정책 목록      initial_delivery_fee   →  3,000
연동 상세      delivery_fee           →  0

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

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

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

get deliveryFee() {
    if (this.policy.feePolicy === 'free') {
        this.policy.fee = 0;                    // ← 대입
    } else {
        this.policy.fee = this.policy.initialFee;  // ← 대입
    }
    return this.policy.fee;
}

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

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

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

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

사용자가 기본 금액 3,000 입력
사용자가 유형을 '무료'로 선택

게터가 호출되며 fee = 0 대입

저장

initial_delivery_fee = 3000
delivery_fee = 0

입력한 3,000은 initial_delivery_fee 에 남고 delivery_fee 는 0이 된다.

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

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

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

기본 금액  →  반품·교환 비용 산정 기준
청구액     →  실제로 고객에게 받는 금액

feePolicyfree 이면 delivery_fee 가 0인 것이 맞다.

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

대응 — 안내와 표시 추가

문의에는 안내로 답했다.

배송비 종류가 무료이므로 실제 청구 배송비가 0원으로 표시되는 것이 정상입니다.
입력하신 기본 배송비 3,000원은 반품·교환 비용 산정 기준으로만 사용됩니다.

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

개선 대상도 함께 적었는데 로직이 아니라 표시를 늘리는 쪽이었다.

[표시 전]  청구액 0원
[표시 후]  청구액 0원 (기본 3,000원 · 무료 배송)

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

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

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

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

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

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

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

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

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

정리


Share this post on:

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