All projects

Case 01 / 04

kimgap

차익 대시보드

Role
개인 프로젝트 · 설계·백엔드·프론트엔드 전체
Stack
Python · FastAPI · WebSocket · Vanilla JS · pytest
Links
kimgap 대시보드 첫 화면: 환율·BTC 김프 KPI와 업비트×빗썸 갭 표

Overview

업비트와 빗썸의 같은 코인 가격 차이, 그리고 Binance · Bybit · Bitget · OKX · Gate.io의 현물·USDT 무기한 선물 대비 김치 프리미엄을 한 화면에 모았습니다. 라이브 데모는 브라우저에서 만든 가상 데이터로 도는 정적 빌드이며, 서버나 거래소 API를 호출하지 않습니다.

Features

  • 국내 갭: 업비트·빗썸 가격 차이(%)와 매수→매도 방향
  • 해외 김프: 업비트 USDT 환율로 환산해 해외 5개 거래소 현물·무기한과 비교, 한국식 색(▲ 빨강 / ▼ 파랑)과 부호를 함께 표시
  • 입출금 상태: 네트워크별 입금·출금 가능 여부를 모아 이슈 종목을 따로 표시
  • 반응형: 모바일에서는 종목 열을 고정한 가로 스크롤 표와 바텀시트 모달

Key decisions

캐시로 호출 증폭 차단

요청마다 거래소 API를 부르던 구조를 공개 시세(5초)·지갑 상태(60초)·출금 가능 정보(6시간) 스케줄러로 분리했습니다. 엔드포인트는 캐시만 반환하므로 요청 수와 거래소 호출 수가 무관해졌고, 큰 응답은 gzip으로 약 2.4MB → 0.3MB로 줄였습니다.

정적 데모와 CSP

인라인 스크립트·스타일은 SHA-256 해시로만 허용합니다(default-src 'none', 'unsafe-inline' 없음). 해시할 수 없는 인라인 코드가 생기면 빌드가 실패하고, Playwright로 30초 관찰했을 때 다른 출처 요청·CSP 위반이 0건이었습니다.

WebSocket pong 감시와 재연결

20초 동안 수신이 없으면 ping을 보내고, 다시 20초 안에 응답이 없으면 반쯤 끊긴 연결로 보고 재연결합니다. 멈춘 가격을 실시간 값처럼 보여주지 않기 위해서입니다.

외부 요청 0건을 위한 폰트 subset

Pretendard에서 실제로 쓰는 약 500자만 남겨 약 3MB를 110KB로 줄였고, OFL 예약 폰트 이름 조항에 맞춰 이름을 바꿨습니다.

Security

  • 조회 전용 키: 지갑 상태·출금 가능 여부 조회 API만 호출하고 주문·출금 코드는 없음
  • 관리자 경로는 토큰이 설정됐을 때만 라우트에 등록 — 없으면 경로 존재 자체가 404
  • 출금 정보는 불리언만 수집·공개, 한도·잔여 금액은 저장하지 않음
  • IP별 토큰 버킷 속도 제한과 WebSocket 동시 연결 상한
  • 보안·캐시 동작 테스트 30개, 외부 네트워크를 막은 상태로 실행

07 — Contact

Let's
talk.

Email

이메일 주소는 스팸 수집을 막기 위해 JavaScript로 표시합니다. GitHub로도 연락할 수 있습니다.

GitHub

github.com/znan2