앱스토어 분석 대시보드를 처음부터 만들기
App Store Connect API 연동, JWT 인증 처리, TSV 판매 리포트 파싱, 일일 cron 셋업. Apsity 코어 대시보드를 어떻게 만들었고 어디서 막혔는지 정리합니다.
왜 직접 대시보드를 만들었나
App Store Connect는 잘 동작하지만, 확장이 안 됩니다. 12개 앱을 운영하면 12번 로그인하고, 12개 대시보드를 클릭해 다니고, 통화별 매출을 머릿속에서 합산해야 합니다. 게다가 2026년 1월에는 ASC에 IAP 매출이 며칠간 $0으로 표시되는 버그도 있었습니다.
서드파티 도구도 있긴 합니다 — Sensor Tower는 연 $30K부터, AppFollow는 5개 앱 한도에 월 $39. 12개 앱을 굴리는 인디 개발자에게 경제성이 안 맞습니다.
App Store Connect API 연결
첫 번째 허들은 인증입니다. ASC는 ES256 개인키로 서명한 JWT 토큰을 사용합니다. App Store Connect에서 API 키를 만들고 .p8 파일을 다운로드한 뒤, Key ID + Issuer ID + 개인키로 단명(short-lived) 토큰을 생성합니다.
개인키는 DB에 저장하기 전 AES-256-GCM으로 암호화합니다. API 호출 시점에 서버 측에서만 복호화 — 브라우저로는 절대 흐르지 않습니다.
판매 리포트 파싱
애플의 Sales Report API는 JSON이 아니라 gzip 압축된 TSV 파일을 반환합니다. 각 행은 하루의 (제품 유형 + 국가 + 디바이스) 조합 하나를 나타냅니다. Vendor 단위 리포트에는 계정의 모든 앱이 들어있어서, Apple ID로 필터링해서 앱별 데이터를 분리해야 합니다.
제품 유형 식별자가 각 행이 무엇을 의미하는지 결정합니다: 1/1F/1T는 신규 다운로드, 3/3F/3T는 재다운로드, 7/7F/7T는 업데이트, IA는 IAP, 그리고 구독은 Subscription Summary 엔드포인트로 따로 받아옵니다.
일일 동기화 아키텍처
Vercel Cron Job이 매일 KST 새벽 3시(UTC 18:00)에 실행됩니다. 각 앱마다 동기화 작업을 after() 패턴으로 디스패치 — cron 엔드포인트는 즉시 200 응답을 내려주고, 앱 처리는 백그라운드에서 진행. Vercel 함수 타임아웃을 피하기 위함입니다.
애플 판매 데이터는 1~2일 지연됩니다. 월요일 데이터는 보통 화요일 저녁(KST)에 들어옵니다. 이를 다루기 위해 항상 최근 3일치를 다시 받아 upsert — 애플이 데이터를 수정하면 자동으로 반영됩니다.
다운로드 카운팅: ASC와 정확히 일치시키기
여기서 한 번 막혔습니다. ASC의 "Sales > Units" 차트는 신규 다운로드만 보여줍니다 — 제품 유형 1, 1F, 1T. 재다운로드(3) 또는 업데이트(7)를 포함하면 숫자가 안 맞습니다.
DOWNLOAD_TYPES = ['1', '1F', '1T']로 정의하고, 모든 쿼리에서 일관되게 필터링합니다 — 대시보드, 매출 페이지, 주간 리포트, 알림 모두.
배운 것
이걸 만들고 매일 아침 약 15분을 절약했습니다 — 예전에는 ASC 탭을 일일이 클릭하는 시간. 하지만 더 중요한 건, 12개 앱을 한 화면에서 보면 개별로는 절대 안 보이는 패턴이 보인다는 점입니다. 그게 바로 AI Growth Agent로 이어졌습니다 (다음 글).