Skip to content
Role
기획 · 디자인 · 개발 · 운영 (1인)
Team
1인
Period
2026.05 – 2026.09
Tools
Claude Code, Apps in Toss SDK, TDS, Supabase, Vercel

지하철 칸별 혼잡도 미니앱

칸칸

요약

“지옥철에서도 앉아갈 수 있게.” 출발역과 도착역만 넣으면, 시간대별로 어느 칸이 덜 붐비는지와 빠른환승 칸을 한 화면에 보여주는 토스 미니앱입니다.

77건
바로잡은 빠른환승 데이터 오류

두 출처 교차검증

456건
앱에 번들한 빠른환승 데이터
0원
지속 운영 비용

배치 캐싱 · 무료 한도 안에서 운영

개인 프로젝트 – 기획 · UX · 디자인 · 개발 · 데이터 · 심사 대응 · 운영 (Claude Code와 1인)

1 / 4
칸칸 기능 소개 영상(45초) – 검색과 결과 화면은 라이브 앱을 그대로 녹화했고, 칸별 혼잡도 화면은 데이터 배치가 멈춰 있어 이전 버전 캡처로 채웠습니다(영상에 표시).

개요

매일 지하철을 타며 느낀 불편에서 시작했습니다. 기존 지도 앱은 경로 안내에 집중하지만, 이미 경로를 아는 사람에게 더 중요한 것은 어느 칸에 타야 앉아 갈 수 있는가였습니다. 칸칸은 토스 안에서 돌아가는 미니앱(앱인토스)으로 출시했습니다.

문제

  • 자리는 매번 감으로 찾는다 – 매일 지하철을 타는 사람들은 어디에 서야 앉을 수 있는지 감에 의존합니다.
  • 지도 앱은 칸을 보지 않는다 – 네이버·카카오 지도는 최단·최적 경로만 보여주고, 칸별 혼잡도는 확인할 수 없습니다.
  • 타깃 – 출퇴근·등하교 때 자리를 원하지만 정보가 없어 오늘도 서서 가는 지하철 이용자.

핵심 결정

  1. 01열차가 오기 전에 답을 준다 – 입력 한 번, 결과 한 번

    탑승 직전 몇 초 안에 판단해야 하는 사용자에게 탭, 설정, 온보딩은 모두 늦습니다.

    출발역과 도착역만 넣으면 바로 결과가 나오는 단일 화면 흐름. 역 검색은 초성으로도 됩니다.

  2. 02숫자보다 색으로 읽게 한다

    서서 기다리는 사람은 글자를 읽을 시간이 없습니다. 화면을 의심할 틈도 없습니다.

    혼잡도를 초록 · 노랑 · 빨강으로 코딩하고, 퍼센트는 보조로 둡니다. 추천 칸에는 표시를 붙였습니다.

  3. 03환승까지 한 화면에서 끝낸다

    앉아 가는 칸과 환승하기 좋은 칸이 다르면, 사용자는 결국 다른 앱을 다시 엽니다.

    구간마다 칸 혼잡도를 보여주고, 환승 구간에는 빠른환승 칸 번호를 함께 적었습니다.

  4. 04공공데이터를 그대로 믿지 않는다

    빠른환승 칸 정보를 기존 길찾기 앱과 역별로 맞춰 보자 누락과 오기가 나왔습니다. 잘못된 칸 번호는 곧 잘못된 행동이 됩니다.

    국토교통부 데이터와 서울교통공사 API를 교차검증해 77건을 고치고, 456건을 정적 데이터로 앱에 번들했습니다.

제약 속 설계

플랫폼, 인프라, API의 제약을 기획 초기에 파악하고 각 제약을 디자인과 개발 결정에 반영했습니다.

  • 앱인토스 배포 정책 – 진입 즉시 팝업 금지, 외부 앱 유도 금지, 뒤로가기 차단 금지 등을 모두 지켰습니다. 뒤로가기 버튼은 없애고 네이티브 제스처에 맡겼습니다.
  • WebView 환경 – 앱인토스 SDK와 웹 프레임워크 가이드를 따라, 네이티브 코드 없이 WebView 안에서 완결했습니다.
  • API 무료 한도 – 혼잡도는 크게 자주 바뀌지 않아 배치로 모아 Supabase에 캐싱하고, 실시간 호출을 최소화해 하루 1,000건 한도 안에서 운영합니다.

디자인

토스 디자인 시스템(TDS) 컴포넌트를 그대로 써서, 토스 앱 안에서 이질감 없이 보이게 했습니다.

  • SearchBar – 역 검색 입력.
  • Badge – 혼잡도 표시(색상 코딩).
  • CTAButton – "칸 추천받기", 해야 할 행동 하나.
  • NavigationBar – 브랜드 로고와 가운데 정렬 타이틀.

데이터

데이터 출처와 처리 방식
  • 칸별 혼잡도 · 하차 비율 – 퍼즐 API(지오비전 SK), 30분 단위, 1~8호선. 배치로 수집해 Supabase에 캐싱하고 시간대별로 조회합니다.
  • 빠른환승 칸 번호 – 국토교통부 CSV와 서울교통공사 API. 두 출처를 교차검증해 오류 77건을 고치고 456건을 정적 데이터로 번들했습니다.
  • 유지보수 – 혼잡도는 배치 스크립트로 Supabase를 갱신하고, 역 정보가 바뀌면 빠른환승 데이터를 다시 검증해 교체합니다. API 한도는 Vercel 로그로 확인합니다.

결과

통과 · 출시
앱인토스 심사
1인
기획부터 운영까지
0원
지속 운영 비용

사람이 개입하는 지점

  • 자동 – 공공데이터를 두 출처로 교차검증해 캐시로 굽습니다.
  • 사람 – 교차검증에서 어긋난 77건은 사람이 확인해 고쳤고, 라이브 API가 불안정한 구간은 검증된 456건을 정적 데이터로 번들해 틀린 값을 실시간으로 보여 주지 않도록 했습니다.

다음 단계

  • 호선 확대 – 1~8호선에서 9호선과 수도권 광역철도(GTX)로.
  • 알림 – 정해 둔 시간대에 출발하기 전, 앉을 확률이 높은 칸을 푸시로 안내.

회고

  • 같은 데이터도 맥락이 바뀌면 다른 서비스가 된다. 혼잡도 데이터는 이미 있었습니다. 탑승 직전이라는 맥락에 맞추자 전혀 다른 가치가 됐습니다.
  • 비용을 없앤 것도 디자인 결정이었다. 혼자 만든 서비스를 오래 열어 두려면 운영비가 0이어야 했습니다.
  • 데이터, 정보 구조, 인터페이스는 하나로 이어져 있다. 한 사람이 전 과정을 맡으니 어느 한 단계의 선택이 다른 단계를 바로 바꾸는 것이 보였습니다.