한 계정에서 필터 하나가 안 보인다는 요청이 왔다. 다른 필터는 정상이었다.
Table of contents
Open Table of contents
증상 — 안 보이던 필터 하나
보이는 것과 안 보이는 것이 갈렸다.
브랜드 필터 보임
소속 필터 안 보임
소속 필터 만 없으니 권한 문제로 보고 그 계정의 role 부터 봤다. 다른 필터가 멀쩡하니 화면 전체의 문제는 아니었다.
권한 체계는 셋이었다.
본사 관리자
운영 관리자
소속 계정
본사 관리자 와 운영 관리자 와 소속 계정 중 어디냐로 화면이 갈리는 구조였다.
원인 — 부정으로 된 판정
화면 쪽 판정 코드를 봤다.
isHeadOfficeManager() {
return !this.is_operation_manager && !this.is_provider;
}
is_operation_manager 도 is_provider 도 아니면 본사 관리자로 정의돼 있다.
문제의 계정은 이랬다.
role 지점관리자
is_operation_manager true
provider_id NULL
is_operation_manager 가 참이고 provider_id 는 비어 있다.
중간 역할이 삼켜진다
이 계정에 판정을 적용해 봤다.
isHeadOfficeManager → !true && !false → false
isProvider → provider_id 없음 → false
isHeadOfficeManager 도 isProvider 도 거짓이라 어느 쪽에도 안 속한다.
<div v-if="isHeadOfficeManager">
<소속 필터 />
</div>
v-if 가 isHeadOfficeManager 를 보고 있으니 그 필터가 안 보인다.
같은 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 처럼 인덱스가 있는 컬럼으로 찾는 편이 낫다.
정리
- 권한이 셋인데 판정이 둘의 부정으로 돼 있으면 중간이 삼켜진다
- 중간 역할은 양쪽 판정이 다 거짓이 될 수 있다
- 그 판정 하나로 감싼 요소는 전부 함께 사라진다
- 하나로 신고된 증상이 실제로는 여러 개일 수 있다
- 분기를 추가할 때 세 상태를 모두 열거한다
- 열거하면 역할이 늘어도 조용히 빠지지 않는다
- 중간 권한은 볼 수 있는 범위도 중간이다
- 보이게 하는 것과 맞는 범위를 내는 것은 다른 작업이다
- 부정 정의를 만나면 예외 역할이 있는지 묻는다
- 새 값이 자동으로 편입되는데 그것이 의도와 다를 수 있다
- 자주 쓰는 조회는 인덱스가 있는 컬럼으로 한다