웹훅이 안되는 이유

Today I Learned 날짜 2024년 5월 17일 금요일 내용 Shopify API 버전 웹훅이 안되는 이유를 알았다. 새로운 앱의 API 버전은 2024-04였다. 기존 우리앱은 버전이 2023-07이었는데, 웹훅 등 Shopify와 통신을 이것저것 주고받을 때 항상 API 버전을 Query Param으로 주어야 한다. 새로운 앱과 통신할때도, 환경변수로 설정된 이전 API 버전을 변수에 담아 주었으니 당연히 401이 떴다. 회고 한 주의 마무리는 오후반차.

2024년 5월 17일 · 1 분 · 배준수

새 앱의 시작 분기 고려하기

Today I Learned 날짜 2024년 5월 16일 목요일 내용 서비스 시작 분기 앱이 2개로 분리되면서 앱을 설치할 때의 분기가 꽤나 복잡해졌다. 해당 쇼피파이 계정으로 알파플러스 서비스에 처음 가입하는 유저 해당 쇼피파이 계정의 다른 스토어로는 알파플러스 서비스를 이용하였으나 지금 스토어로는 처음 가입하는 유저 해당 스토어로 알파플러스 서비스를 가입하였으나 브라우저부스터는 처음인 경우 정도가 있다. 물론 브라우저부스터와 알파플러스가 반대인 경우도 있긴 하지만.. 2번과 3번 과정이 꽤나 헷갈렸다. 우리 서비스 로직으로는, 우선 설치하는 과정에서 샵 데이터를 생성한 후, 온보딩(혹은 계정 통합 과정)을 거치면서 이 샵 데이터가 계정 데이터와 연결된다. 3번은 바로 로그인 화면으로 이동해줘야 하므로 별도의 계정 연결 과정이 없다. 따라서 샵 데이터가 생성될 때 이뤄저야 한다. 따라서 샵을 만들때, 그 샵의 URL로 다른 앱 데이터를 탐색해서 존재하는지 확인했다. 존재한다면, 그 데이터와 연결된 계정에 이 샵도 바로 연결해주었다. ...

2024년 5월 16일 · 2 분 · 배준수

QA 지옥

Today I Learned 날짜 2024년 5월 14일 화요일 내용 QA 제법, 아니 꽤 많이 미완성인채로 일정대로 QA가 진행됐다. 자질구레한 것 여러가지를 뜯어고쳤고, 앞으로도 뜯어 고칠게 참 많다. 앱 삭제 기능 쇼피파이에서 고객이 앱을 삭제하면 웹훅을 이용해 우리 서비스에 호출을 보낸다. 그럼 우리 서버 내에 데이터들을 삭제해주어야 한다. 이 기능이 작동을 안하고 있다. 따로 엔드포인트를 이용하면 기가막히게 삭제가 되는데… 주소가 잘못 되어있는 것 같아 수정하고, 기능이 새 앱에서는 작동되지 않도록 설정되어 있어 그 부분도 손봤는데 여전히 작동하지 않는다. elastic apm을 홗인해보니 웹훅을 처리하는 라우터 자체가 호출된 흔적이 없었다. 기존에 있던 웹훅 조회하는 함수를 조금 손봐서 새 앱에도 쓸 수 있게 해봤는데, 웹훅 조회자체가 안된다. 없을 거라 예상했는데 조회가 안되는건 예상 못했는데.. ...

2024년 5월 14일 · 3 분 · 배준수

Shopify에 앱 설치가 안되었던 이유

Today I Learned 날짜 2024년 5월 13일 월요일 내용 1 스토어 2 앱 설치 하나의 스토어에 우리 앱 2개가 설치되지 않는다. 쇼피파이에게 문의한 결과는 “개발에 관련된 질문은 받지 않으니, 개발자 커뮤니티를 이용하거나 우리 디스코드에 들어와!” 내가 안찾아봤겠냐고… 거기도 이미 답변을 다는 사람에 비해 너무 많은 질문이 올라온지 한참되버렸을 뿐더러, 내가 원하는 질문은 찾을 수도 없었다. 별 수 있나? 열심히 짱구 굴려봐야지.. 답이 없을 것 같았던 문제는, 전지전능하신 선배님의 도움으로 해결되었다. 브라우저 부스터 앱 설치를 테스트 서버로 넘기기 전에, ngrok을 이용해 내 로컬로 설치할 수 있다. 더 쉽게 말하자면, 유저가 “앱 설치할래요!” 라고 요청을 보내면, 쇼피파이와 앱 서버(여기선 우리 테스트 서버)는 검증받은 앱인지, 올바른 URL인지 기타 등등을 검증하고, 데이터를 주고 받는다. 이 과정에서 우리 서버에는 설치한 스토어의 정보가 저장되고, 새로운 손님에겐 우리가 미리 설정한 주소(온보딩 or 로그인 페이지)로 리다이렉트 시켜준다. ngrok을 이용하면 쇼피파이가 테스트 서버 대신 내 로컬과 이야기를 주고받도록 설정하는 셈이다. ...

2024년 5월 13일 · 2 분 · 배준수

두 앱의 공통 진입점 파악

Today I Learned 날짜 2024년 5월 10일 금요일 내용 프로덕트바리언트 가격 리스트디자이너 위젯에서 할인 전후 가격이 바뀌어서 나타나고 있었다. 알고보니 쇼피파이에서 보내는 데이터 상으로 compare_at_price가 할인 전 가격(높은 가격)이고 price가 할인 후 가격(낮은 가격)인데 바꾸어서 데이터로 저장하고 있었다. 애초에 변수 이름을 좀 알아보기 쉽게 짓지 거참.. 온보딩 앱 두개가 하나의 시작점을 지니도록 처리하려니 신경써야 할 부분이 한 두개가 아니다. 예를 들어, 어떤 계정이 3개의 스토어에 우리 서비스를 설치했다고 가정해보자. A 샵은 알파플러스만 사용하고, B 샵은 브라우저 부스터만 사용, C 샵은 둘 다 사용한다. 계정은 두 서비스를 다 사용한다는 변수를 프론트에게 제공하고 있고, 세션에 저장된다. 그럼 각 샵은 어떻게 처리해야할까? 어드민 페이지에서 A샵이나 B샵을 선택하면 그 샵이 설치한 앱(A샵은 알파플러스, B샵은 브라우저 부스터)에만 접근하도록 해주어야 한다. C샵은 둘 다 접근할 수 있어야 한다. 로그인 시점에 이 정보가 프론트에게 주어져야 한다. 이런 부분이 한두 개가 아니다.. 기존 알파플러스 서비스를 망가뜨리지 않고 새로운 앱을 합치다 보니 머리가 너무 복잡하다ㅏㅏㅏㅏㅏㅏ…. ...

2024년 5월 10일 · 1 분 · 배준수

2앱 체제 구현

Today I Learned 날짜 2024년 5월 9일 목요일 내용 샵 디테일 수정 새로운 브라우즈 부스터 앱에서 사용할 샵 테이블을 별도로 생성했었다. 이 앱에 앞으로 다양한 서비스가 추가될 테지만, 우선은 필요한 최소한으로 구현하는게 좋다고 클린 아키텍처에서 배웠다. 알파플러스 앱에선 쇼피파이에서 보내주는 데이터는 샵 테이블에, 우리 서비스에서 사용하기 위해 필요한 정보들을 담는데는 샵 디테일 테이블을 사용한다. 우선 브라우저 부스터 앱은 샵 디태일을 별도로 만들지지 않았다. 배운대로 했다는 뿌듯함을 느꼈다. 브라우저 부스터 앱을 설치해도, 알파플러스와 동일한 온보딩 및 회원가입 과정을 겪어야 해서 샵 데이테일 테이블이 필요하다는 것을 꺠달았다. 바로 샵 디테일을 만들었다. 난 생각의 범위가 참 좁다. ...

2024년 5월 9일 · 2 분 · 배준수

Shopify Session 설치

Today I Learned 날짜 2024년 5월 8일 수요일 내용 Shopify session 새로 추가될 앱을 같은 서버에 만들었다. 앱이 설치되는 방식은 대략 다음과 같다. 쇼피파이에 설정해둔 우리 서버의 엔드포인트로 요청이 들어오면(/shopify) 우리 서버는 shopify_session을 이용해 허용 URL을 만들고 redirect시킨다. 앱을 설치하는 고객은 앱이 요청하는 권한(고객 데이터 접근, 주문 데이터 접근 등등)에 대해 확인하고 허가하는 창으로 안내되고, 허용하면 다시 우리 서버로 요청이 넘어온다. 이후로 온보딩 플로우로 넘어가든, 로그인으로 넘어가든 우리 코드대로 처리된다. ...

2024년 5월 8일 · 2 분 · 배준수

데이터베이스 개선작업 시작

Today I Learned 날짜 2024년 5월 7일 화요일 내용 데이터베이스 개선 지난주에 이어 데이터베이스를 개선하고 있는데, 예상치 못한 부분에서 신경쓸 거리가 많다. 예를 들어, 서비스에 가입할 때 항상 Shop테이블을 기준으로 구현되어 있다. 이 부분의 로직도 다른 예외처리를 두어야 한다. 그리고 리뷰서버에선 Redis를 이용해 샵의 정보를 불러오는데 새로 만든 앱의 샵은 Redis에서 정보를 찾을 수 없다. 우선은 Shop_id로 Shop 서버에서 정보를 가져오는 함수를 만들어 처리하고 있다. 점차 두번째 앱에서 처리해야할 정보나 범위가 많아진다면 Redis에 두번째 앱의 shop들에 대한 정보를 추가해주야 한다. ...

2024년 5월 7일 · 1 분 · 배준수

데이터베이스 테이블 계층 변경하기

Today I Learned 날짜 2024년 5월 3일 금요일 내용 DB구조에 대해 열심히 고민했다. 우리 서비스는 애초에 앱을 여러개 낼 계획이 없었기 떄문에 Shopify에서 받은 스토어 정보를 Shop 테이블에 저장하고 이 테이블을 중심으로 모든 로직이 이루어진다. 가장 최상위 테이블 역할을 한다. 알파리뷰 서비스에 가입한 계정에 관한 테이블인 ShopAdminAccount가 같은 계층에 있어 서로 참조할 수 있는 테이블이긴 하지만, 그외의 모든 데이터는 결국 Shop을 기준으로 정규화가 이루어져 있다. 따라서 서비스 삭제도 이 Shop을 삭제하면 이와 연관된 모든 테이블이 삭제된다(일부 남는 테이블과 리뷰서버 쪽도 처리하긴 해야 하지만…). ...

2024년 5월 3일 · 1 분 · 배준수

이메일 템플릿 렌더링

Today I Learned 날짜 2024년 5월 2일 목요일 내용 실수 처리 몇가지 실수를 뿌려놓은게 있어서 열심히 메꾸었다. 가장 먼저, 코어스크립트와 앱블록을 활성화한 유저들을 탐색하는 기능을 고쳤다. 당연히 Dict 일거라 생각하고 처리한 부분에서, 뜬금없이 문자열이 튀어나와 오류가 나고있었다. if not isinstance(settings_data, dict): 를 추가해서 해결했다. 스프레드시트에 데이터가 올바르게 들어가지 않고 있었다. 각 유저들이 앱을 사용하는 상황을 저장하는 방식을 바꾸었는데 이 로직의 코드는 변경하지 않아 작동하지 않는 문제였다. 지난주 이메일 레거시 코드를 개선하고 테스트 하는 과정에서 수신 주소를 내 개인 메일로 바꾸어놨는데, 이 부분을 복구하지 않고 실서버 까지 올라가버렸다.. VOC가 나한테 와서 상당히 당황스러웠다. 메일 주소 바꾸는건 어렵지 않았지만 문제는 템플릿이 렌더링되지 않는 것이었다. ...

2024년 5월 2일 · 2 분 · 배준수