한 업체의 마켓 연동이 실패한다는 문의를 받았고 처음에는 그 업체의 설정 문제로 보여서 계정 설정부터 뒤졌다.
Table of contents
Open Table of contents
없던 계정 레코드
채널별 카테고리 계정 레코드를 channel_id로 묶어 COUNT(*) 해 보니 한 채널 것만 있고 나머지 채널은 0건이었다. 연동하려는 채널의 계정이 없으니 전송이 막히는 것이 맞았다.
여기서 그 업체가 설정을 안 한 것으로 결론 내릴 수도 있었지만 한 가지를 먼저 확인하기로 했다.
검증 — 전체를 센 결과
이 업체만 그런지를 보려고 이관에 성공한 업체 전체를 집계했다. 성공한 업체가 백여 개였고 그중 해당 채널 외의 계정을 가진 업체를 GROUP BY seller_id로 세니 0개였다.
전원이 같은 상태라면 그것은 개별 설정 문제가 아니라 이관 자체가 그 레코드를 안 만든다는 뜻이다. 그 업체의 설정을 아무리 들여다봐도 원인은 나오지 않았을 것이다.
원인 — 기존 상품이 도는 이유
그런데 이관된 업체들의 기존 상품은 잘 나가고 있었다. 왜 도는지 보니 product_id와 account_id를 개별로 잇는 별도 연결 테이블이 있었다.
이관 시점에 상품마다 그 개별 연결이 만들어져서 기존 상품은 그것으로 동작한다. 신규로 만드는 상품에는 그 연결이 없으므로 차단된다. 문의가 신규 상품에서만 나오는 이유가 여기에 있었다.
공용 레코드와 폴백 부재
seller_id가 NULL인 공용 계정 레코드도 있어서 그것을 대신 쓰면 되지 않을까 싶었다. 코드를 보니 where('seller_id', $sellerId)->first()로 업체 전용 레코드만 찾고 null이면 그냥 실패한다.
공용 레코드가 있는데도 그 경로로 대체하는 폴백이 없는 것이었다. 있는 것과 쓰는 것은 다르므로 존재만 확인하고 넘어가면 안 된다.
조치 — 넣는 것과 연결하는 것
원인을 알고 나니 계획이 한 업체 설정 수정에서 백여 개 업체 일괄 보정으로 바뀌었다. 부류 전체가 같은 상태이므로 한 건씩 할 일이 아니었다.
두 가지 방법이 있었는데 코드에 공용 레코드 폴백을 넣는 것과 업체마다 전용 계정을 넣고 참조를 옮기는 것이다. 뒤쪽을 골랐다. 이유는 폴백을 넣으면 이관 전 업체와 이관 후 업체가 서로 다른 경로로 동작해 다음 장애 때 둘을 따로 봐야 해서다. 대신 백여 개 업체에 DML을 돌리는 작업을 감수했다.
계정 레코드를 넣는 것만으로 풀리는지도 따져 봤는데 아니었다. 상위 레코드의 account_id가 기존 공용 계정을 가리킨 채 남아 있어서 전용 계정을 새로 만들어도 아무도 그것을 가리키지 않는다.
그래서 전용 계정을 넣는 작업과 상위 레코드의 참조를 그쪽으로 옮기는 작업 둘이 필요했고 검증 조건도 둘로 적었다. COUNT(*)가 업체 수 × 채널 수인지와 공용을 가리키는 account_id가 0건인지다. 넣은 것만 확인하면 만들었으니 됐다로 끝나는데 만든 것과 연결된 것은 다르다.
정리
- 개별 문의를 받아도 이 대상만인지를 전체 집계로 확인한다
- 전원이 같으면 개별 설정 문제가 아니라 구조 문제다
- 이관이 부속 레코드 생성을 누락할 수 있다
- 기존 것은 개별 연결로 동작하고 신규만 막히는 패턴이 있다
NULL공용 레코드가 있어도 코드가 그 경로로 대체 안 하면 소용없다- 넣는 것만으로는 안 풀리고
account_id참조를 갱신하는 작업이 같이 필요하다 - 검증에 만들었는지와 연결됐는지를 둘 다 넣는다
- 만든 것과 연결된 것은 다르다