Skip to content
isdnetworks
Go back

중간 역할은 어느 쪽에도 없다

한 계정에서 필터 하나가 안 보인다는 요청이 왔다. 다른 필터는 정상이었다.

Table of contents

Open Table of contents

증상 — 안 보이던 필터 하나

보이는 것과 안 보이는 것이 갈렸다.

브랜드 필터   보임
소속 필터    안 보임

소속 필터 만 없으니 권한 문제로 보고 그 계정의 role 부터 봤다. 다른 필터가 멀쩡하니 화면 전체의 문제는 아니었다.

권한 체계는 셋이었다.

본사 관리자
운영 관리자
소속 계정

본사 관리자운영 관리자소속 계정 중 어디냐로 화면이 갈리는 구조였다.

원인 — 부정으로 된 판정

화면 쪽 판정 코드를 봤다.

isHeadOfficeManager() {
    return !this.is_operation_manager && !this.is_provider;
}

is_operation_manageris_provider 도 아니면 본사 관리자로 정의돼 있다.

문제의 계정은 이랬다.

role                 지점관리자
is_operation_manager true
provider_id          NULL

is_operation_manager 가 참이고 provider_id 는 비어 있다.

중간 역할이 삼켜진다

이 계정에 판정을 적용해 봤다.

isHeadOfficeManager  →  !true && !false  →  false
isProvider           →  provider_id 없음  →  false

isHeadOfficeManagerisProvider 도 거짓이라 어느 쪽에도 안 속한다.

<div v-if="isHeadOfficeManager">
  <소속 필터 />
</div>

v-ifisHeadOfficeManager 를 보고 있으니 그 필터가 안 보인다.

같은 v-if 로 감싼 것이 여럿이면 전부 함께 사라지는데 그 아래 다른 요소도 안 보이고 있었다. 아무도 요청하지 않아 그것은 모르고 있었다.

하나로 신고된 증상이 실제로는 여러 개였다.

조치 — 세 상태를 열거

부정으로 정의한 구조 자체가 문제였다.

A = !B && !C

B도 C도 아닌 것을 전부 A로 보는데 새 역할이 생기면 그 전제가 깨진다.

<div v-if="isHeadOfficeManager || isBranchManager">

isBranchManager 를 더해 대상을 명시적으로 적는 쪽으로 바꿨다.

권한 분기를 추가할 때의 규칙도 적어 뒀다. 판정 하나만 검사하면 중간 역할이 누락되므로 세 상태를 모두 열거해 대상이 어디에 속하는지 명시한다.

열거하면 역할이 하나 더 늘어도 그 자리에서 정해야 하므로 조용히 빠지지 않는다. 새 값을 어디에 넣을지 고르는 일이 강제된다.

제약 — 중간인 범위

그 역할이 무엇을 볼 수 있는지도 확인했다.

SELECT id, name FROM providers WHERE operation_id = ?;

operation_id 로 묶인 소속들만 본다.

운영 ID 5  →  소속 A, 소속 B, 소속 C

전체도 아니고 하나도 아니고 그 묶음이다.

본사 관리자   →  전체 소속
중간 역할     →  묶인 소속만
소속 계정     →  필터 자체가 불필요 (자기 것만)

셋이 다르므로 하나의 v-if 로 못 만들고 역할별 분기가 필요하다.

필터를 보이게 하는 것과 그 필터가 맞는 범위를 내는 것은 각각 다른 작업이라 보이게만 하고 끝냈으면 틀린 범위를 보여 줬을 것이다.

교훈 — 부정 정의를 만나면

이 건에서 얻은 습관이 있다.

isX() { return !isY && !isZ; }

이런 것을 보면 Y도 Z도 아닌 것이 정말 X뿐인지를 묻는다.

대개 아니고 시간이 지나면 중간이 생기며 그때 이 정의가 조용히 틀리기 시작한다.

부정으로 정의하면 새 값이 자동으로 어느 한쪽에 편입되는데 그 편입이 의도와 다를 수 있다. 코드는 아무 신호도 안 주므로 화면에서 무언가 안 보일 때야 드러난다.

계정을 조회하면서 하나 더 확인한 것도 있다. 이름으로 찾으려 했는데 그 컬럼에 인덱스가 없었다.

SHOW INDEX FROM managers;
-- name 인덱스 없음

managers 가 몇 천 건이라 전수 훑기도 안전했지만 email 처럼 인덱스가 있는 컬럼으로 찾는 편이 낫다.

정리


Share this post on:

Previous Post
단건 실행은 스코프를 안 거친다
Next Post
로컬에서만 붙던 서비스