상위 상품의 옵션 재고를 고치면 마켓에도 자동으로 반영되게 하는 기능을 설계했다. 재고를 바꾸면 channel_jobs 에 UPDATE 작업을 만들면 되는데 아무 때나 만들면 안 되는 조건들이 있었다.
Table of contents
Open Table of contents
조사 — 이미 있던 두 겹
판매 중지된 상품이나 승인이 안 난 상품이나 정지된 업체 것을 걸러야 했다. 그래서 검증을 어디까지 짜야 하는지부터 확인했다. ChannelJobHandler::validate() 를 읽으니 supplier_status 와 재고와 approval_status 와 판매 금지와 정지 업체와 edit_lock 까지 열 가지가 이미 있었다.
ProductService 쪽에도 상위 레벨 검증이 따로 있었는데 마지막 작업이 SUSPEND 면 새 작업을 거부하고 sync_enabled 가 켜져 있는지를 확인하고 있었다. 검증이 이미 두 겹이었다.
판단 기준 — 중복 구현을 안 한 이유
두 가지 방법이 있었는데 새 기능 앞에 조건을 한 벌 더 쓰는 것과 중복 구현하지 않고 ChannelJobHandler 를 그대로 부르는 것이다. 뒤쪽을 골랐다. 이유는 내가 짜려던 검증이 전부 이미 있어서다. 대신 핸들러가 거부한 이유가 새 기능 쪽 로그에는 안 남으므로 거부 사유를 되돌려 받는 처리를 넣는 것을 감수했다.
중복 검증의 문제는 두 벌이 갈린다는 것이다. 나중에 조건이 추가되면 한쪽만 바뀌고 그때부터 두 경로의 동작이 달라진다.
상위 검증이 지키던 것
특히 상위 레벨의 첫 검증이 중요했다. 마지막 작업이 SUSPEND 면 새 작업을 거부하는 조건이 중지 상태를 보호하고 있었다.
이것이 없으면 재고를 올리는 순간 중지된 상품이 다시 마켓에 올라간다. 의도한 중지가 풀리는 것이 가장 나쁜 시나리오인데 이미 막혀 있었다.
주의 — 자식 상태가 만드는 조합
하위 검증을 자세히 보니 channel_products 의 재고와 status 를 보고 있었다. 그러면 마켓상품이 SOLD_OUT 일 때 상위에서 재고를 올려도 자식 상태 때문에 거부돼 작업이 안 생긴다.
재고를 올려도 마켓에 반영되지 않는 조합이다. 이것은 버그가 아니라 정해야 할 것이었는데 SOLD_OUT 에서 재고를 올리면 자동으로 ON_SALE 로 전환할 것인지가 정책 판단이기 때문이다. 전환하면 편하지만 의도치 않은 재개가 생길 수 있다. 전환 안 하면 운영자가 따로 바꿔야 한다.
결과를 붙인 보고
그래서 이 기능의 검증 로직은 추가 구현이 불필요하다고 적고 자동 전환 여부는 별도 설계 판단이 필요하다고 적었다. 거기에 한 문장을 더 붙였다.
전환하지 않으면 재고를 올려도 마켓에 반영되지 않는다는 것이다. 그것이 없으면 판단하는 쪽이 그냥 두자고 한다. 나중에 재고를 올렸는데 왜 안 팔리느냐는 문의가 나온다. 선택지마다 결과를 붙여야 판단이 된다. 이 조사의 결과가 안 짜도 된다였고 새로 짤 뻔한 검증 십여 개를 안 짰으며 읽는 김에 자식 상태 게이트라는 함정도 미리 발견했다.
정리
- 기능을 붙이기 전에 기존 검증 범위를 읽는다
- 검증이 이미 있으면 중복 구현하지 않고
ChannelJobHandler호출에 맡긴다 - 중복 검증은 조건이 추가될 때 한쪽만 바뀐다
- 하위 검증이 자식 상태를 보면 상위 조작이 안 먹는 조합이 생긴다
- 그런 조합은 버그가 아니라 정해야 할 정책이다
- 선택지마다 결과를 붙인다
- 판단 필요라고만 쓰면 그냥 넘어간다
- 읽어서 안 짜도 된다가 나오는 것이 좋은 결과다