없는 응답의 반환

Today I Learned 날짜 2024년 6월 20일 목요일 내용 실서버 에러처리 실서버에서 이것저것 에러 알람이 또 뜨고있다. 첫번째는 웹훅으로 상품이 수정되었을 때 발생하는 것이고, 두번쨰는 이메일로 온 리뷰작성 요청을 통해 리뷰를 작성할 때 발생한다. 아예 기능이 안된다기보다는 종종 불규칙적으로 발생하는 문제였다. 리뷰 작성하는 부분은 워낙 어렵고 복잡하고 볼 게 많아 머리가 터질 것 같았다. 문득, 두 문제의 공통점을 알게 되었는데 shop을 못찾았음에도 불구하고 코드에서 감지하지 못해 진행하다가 발생한 문제라는 점이다. if not shop: 이라는 예외처리가 있는데도 건너 뛰어진다. elastic apm으로 구체적인 값을 살펴보면 분명 shop의 모든 값은 None으로 되어있다. ...

2024년 6월 20일 · 2 분 · 배준수

슈퍼 어드민 수정

Today I Learned 날짜 2024년 6월 19일 수요일 내용 슈퍼어드민 우리가 고객사를 관리하는 사이트가 슈퍼어드민이다. 모든 고객의 알파리뷰 어드민에 접근할 수 있고 대략적인 정보도 볼 수 있다. 다만 여기엔 브라우즈 부스터 앱과 관련된 정보가 없어서 추가해야 했다. 만든지 상당히 오래됌 + 서비스 구조와는 사뭇 다름 문제가 겹쳐 머리 아팠다. 앱이 하나 추가되면서, 쇼핑몰을 나타내는 샵 테이블은 2개로 나누어졌다. 두 개를 조회해야 한다는 효율성 문제보다는, 두 테이블이 연관된 것이 다르다는게 자꾸 문제로 나타났다. 예를 들어, 알파 플러스 앱에선 온보딩 데이터가 닮긴 shop_initial_info 테이블이 있는 반면, 브라우즈 부스터에는 (필요도) 없다. 해당 쇼핑몰이 우리 서비스를 사용한 지속기간은 여기 있는 installed_at 이라는 필드를 참조해야 하는데 이 부분이 꽤 거슬렸다. 두 테이블이 필요한 값을 다른 테이블의 다른 필드에서 가져와야 했고 기존에 있던 함수들의 타입 힌팅이 계속 어긋났다. 무작정 함수를 나누기엔, 어디서 어떻게 또다른 오류가 발생할지 몰라 그럴 수 없었다. ...

2024년 6월 19일 · 2 분 · 배준수

페이스북 토큰의 자동 갱신

Today I Learned 날짜 2024년 6월 18일 화요일 내용 오늘도 미비된 자잘자잘한 마무리들을 열심히 처리했다. 웹훅 쇼피파이에 앱을 출시하기 위해선, 쇼피파이에서 요구하는 웹훅을 처리해야 한다. 대표적으로 앱을 삭제하는 웹훅이 있는데, 어쩄든 여러 종류의 웹훅이 오면 알맞게 처리하는 기능은 만들어놨다. 사실 이번 앱은 테마와 관련된 데이터만 처리하기 때문에 고객정보나 주문정보를 위한 웹훅은 필요없어 쉬웠다. 그런데 앱을 삭제해도 데이터가 사라지지 않았다. 열심히 테스트를 해봐도 요청 자체가 날라오지 않아 어디서 뭐가 잘못됐는지 알 수가 없었다. 기존에 있는 다른 앱들의 코드를 살펴보니 애초에 웹훅을 내가 만들어 줬어야 했다.. 난 쇼피파이에서 알아서 해주는 줄 알았지.. 샵을 설치할 떄 필요한 웹훅을 설치해주는 함수를 추가했더니 잘된다. ...

2024년 6월 18일 · 2 분 · 배준수

인스타그램 댓글 가져오기 마무리

Today I Learned 날짜 2024년 6월 17일 월요일 내용 스프린트 마무리 인스타그램에서 댓글을 가져오는 기능을 마무리했다. 물론 QA가 남긴했으나.. 이것저것 마무리가 필요한 부분을 PRD를 다시 보면서 고쳤다. 게시된 댓글 저장 : 계정 연동을 해지하더라도 게시된 댓글은 냅둬야 했다. 따라서 기존처럼 샵의 하위 테이블을 모두 삭제하는 대신, 미게시된 댓글만 삭제하도록 했다. 단, 다시 가져올때 그 스토어의 그 댓글이 기존 테이블에 존재하는지 중복검사를 추가했다. 앱 메타필드 업데이트 각 데이터들이 변동될 때마다 앱 메타필드에도 업로드 되도록 기능을 추가했다. 메타필드는 일부 수정은 안되고 항상 덮어쓰기 형식으로 처리된다. 따라서 매번 위젯에서 사용하는 자바스크립트와 스타일 파일은 별도의 key로 두었다. 데이터가 자주 변경되는 것은 댓글이나 위젯 옵션들이 포함된 템플릿 부분이라 이 부분만 별도의 key로 설정했다. ...

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

JSON과 STRING의 성능검사

Today I Learned 날짜 2024년 6월 14일 금요일 내용 앱 메타필드(2) 어제 무사히(?) 앱 메타필드를 저장하는 방법을 알아냈다고 생각했으나, 오늘 왠지 또 잘 안됐다. 원인은 정확히 앱 메타필드가 어디에 어떤값으로 있는지 몰라서 발생한 일이었다. 우리야 “앱 메타필드”라고 부르지만, 정확하겐 appInstallation 이라는 객체 내에 있는 Metafield 안에 저장하는 것이다. 기존에 사용하던 샵 메타필드는 Shop 객체 안에있고.. 따라서 우리 앱의 appInstallation ID를 알아내기 위해, 고객이 우리 앱을 설치하자마자 currentappInstallation을 조회하여 저장하고, 이 객체 안 메타필드를 관리하면 된다. 이 ID값은 key나 namespace가 아닌 ownerID 라는 항목의 값으로 처리된다. ...

2024년 6월 14일 · 2 분 · 배준수

Shopify 앱 메타필드

Today I Learned 날짜 2024년 6월 13일 목요일 내용 앱 메타필드 이번 스프린트는 인스타그램에서 댓글을 가져와 위젯으로 표시해주어야 한다. 기존처럼 쇼피파이에 있는 앱프록시를 이용해 서버쪽에서 처리하기보단, 앱 메타필드에 렌더링된 HTML 전체를 올려놓는 방식을 취해보기로 했다. 그동안은 샵 메타필드를 이용했었기 떄문에 그 샵이 설치한 다른 앱과 공유하는 메타필드였다. 앱 메타필드는 우리가 독점적으로 사용할 수 있으며, 앱을 삭제하면 자동으로 삭제된다는 장점이 있다. 다른 앱들은 유료화 기능에 이용한다고 하는데, 우린 이번 스프린트에 활용해보기로 했다. 단점이라면, 위젯의 HTML이 모두 올라가있기 떄문에 위젯과 관련된 데이터가 변경되는 즉시 메타필드에도 적용되야 한다. 이참에 앱 메타필드를 다루는 클래스를 만들어놓기만 하면 어렵진 않을것 같다. ...

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

개인정보 익명화

Today I Learned 날짜 2024년 6월 12일 수요일 내용 개인정보 익명화하기 인스타그램 댓글을 위젯으로 만들때, 혹시나 댓글 내용에 개인정보가 있다면 익명화하는 기능을 추가하고자 한다. 집 주소, 계좌번호, 전화번호, 이름이 나타나면 별표처리를 해야했다. 개인정보를 내가 형태(글자 수 등)로 추적하는 것은 불가능했기 때문에 라이브러리를 찾았다. 영어로는 PII(Personally Identifying Information)라고 하는데, 개인을 식별할 수 있는 정보를 통칭한다. Presidio 무려 마이크로소프트에서 제공하는 오픈소스다. 언어 관련해선 Analyzer와 Anonymizer 2가지가 있는데, 전자는 nltk 처럼 글을 쪼개 분석해주는 기능이고 후자는 특정 키워드를 대체해준다. 예를 들어, ...

2024년 6월 12일 · 2 분 · 배준수

검색 기능 만들기

Today I Learned 날짜 2024년 6월 11일 화요일 내용 검색 쿼리 유저가 여러 댓글 중 무언가를 검색하거나, 데이터를 정렬하는 기능을 만들어야 했다. 기존 프로덕트 리뷰에 있는 건 너어어어무 복잡하고, 온갖 기능이 추가되어 유지보수가 힘들었다. 아예 다른 곳에서 쓰이는 것일 뿐더러 기능이나 검색 단위, 정렬 단위도 더 작은 범위라 최대한 깔끔하게 만들려고 했다. 정렬 방식이 조금 난해했는데, 정렬 기준이 2개인 경우가 있었기 떄문이다. 이번 인스타그램 댓글 가져오는 앱의 테이블 구조는 샵 → 페이스북 페이지 → 게시글 → 댓글 순서로 이루어졌으며 각각 일대다관계다. 댓글의 작성일자로 정렬할 때는 별 어려움이 없으나, 게시글 작성일자로 정렬할 떄는 꽤 어려웠다. 최근에 작성된 게시글 내의 댓글들을 먼저 가져오되, 같은 게시글 내에선 최근에 작성된 댓글이 먼저와야 했다. ...

2024년 6월 11일 · 1 분 · 배준수

마크 주커버그와 5가지 액세스 토큰의 비밀

Today I Learned 날짜 2024년 6월 10일 월요일 내용 페이스북과 인스타그램은 하나인듯 하나가 아님. 진짜다. 내가 페이스북을 끊은지 오래되었고, 인스타그램을 계정만 만들어놔서 혼나는건지 모르겠으나 얘네는 자기들 맘대로 공유하고, 분리하고 난리부르스를 친다. 상당히 맘에 들지 않으나 내가 뭘 할수 있겠는가. 그저 열심히 Docs를 읽고 만들었다. 이번 기능은 “인스타그램 비즈니스 계정”에서 게시글에 달린 댓글을 가져와야 한다. 그래서 난 인스타그램 계정에 접근하는 법을 열심히 알아봤고 기능을 구현했다. 그리고 인스타그램 비즈니스 계정과 그냥 계정은 다르다는 사실을 깨달아버렸다. 그래도 언젠가 쓰지 않을까? 하는 마음으로 한구석에 조용히 쑤셔넣어놨다. ...

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

에러 알람과 예외처리의 난관

Today I Learned 날짜 2024년 6월 8일 금요일 내용 에러 알람 휴일에 쉬는데, 실서버에서 에러가 난다고 온갖 알람이 오두방정을 떤다. 다행히(?) 서버 트래픽의 문제라던가, 기능상의 문제는 아니였고 크론이 실행되는 도중 발생하는 문제였다. 자동적으로 업데이트 되야할 데이터가 원할하게 돌아가지 못했다는 뜻이다. 쉬는데 참 마음이 찝찝해서 금요일이 되자마자 실서버에서 처리해주었다. 원인은 크게 두가지였다. Orphan Data 직역하면 고아 객체긴 한데.. 관계된 데이터가 없다는 뜻이다. 예를 들어, 우리 서비스에선 Shop 데이터가 존재하면 이 하위 개념으로 shop_detail 데이터가 존재하게 된다. 영속성 전이(CASCADE)를 설정해놓으면 shop이 삭제될때 연관된 shop_detail도 따라없어져야 한다. 그럼에도 불구하고 아주 낮은 확률로 혼자 남아있는 shop_detail이 발견된다면 연관된 shop이 없는 이 shop_detail 데이터를 고아 객체라고 부르는데, 이것 떄문에 발생하는 오류들이 꽤 있었다. 버그나 로직의 구멍이 있다기 보단, 초기 개발때 로직이 불완전한 상황에서 만들어진 데이터들로 인해 생긴듯 하여 커맨드를 작성해서 지워줬다. ...

2024년 6월 7일 · 2 분 · 배준수