우리는 30일 만에 슈퍼 앱을 만들었습니다. 아무도 예상치 못한 혼돈의 과정.
요약
단 30일 만에 9개의 서비스 수직 계열을 포함하는 슈퍼 앱을 구축한 개발 과정과 도전 과제를 다룹니다. 음식 배달에서 시작해 약국, 슈퍼마켓, 세탁 등 다양한 카테고리를 확장하며 겪은 코드베이스 변화와 설계의 어려움을 기록했습니다.
핵심 포인트
- 단일 앱이 아닌 9개의 독립적인 서비스가 결합된 구조 설계의 복잡성
- 서비스별로 상이한 결제 흐름과 재고 관리 시스템 구축 필요성
- 확장성을 고려한 홈 화면 UI/UX 및 그리드 시스템 재설계
- 구독 엔진 등 복잡한 비즈니스 로직을 위한 백엔드 구현 경험
한 팀. 30일. 9개의 서비스 수직 계열 (Service Verticals). 50개 이상의 화면. 그리고 새벽 5시까지 우리를 잠 못 들게 했던 한 가지 질문: "이게 정말 가능할까?"
1일 차: "그냥 음식 앱 아닌가요...?"
상상해 보세요.
6월 1일입니다. 우리는 음식 배달 앱을 바라보고 있습니다. 잘 작동합니다. 고객들은 근처 식당에서 졸로프 라이스 (jollof rice)를 주문할 수 있습니다. 삶은 평화롭습니다.
그때 누군가 모든 것을 바꿔놓을 말을 내뱉습니다:
"사용자가 약국에서도 주문할 수 있다면 어떨까요? 슈퍼마켓은요? 로컬 마켓은요? 택배를 보낼 수도 있다면? 빨래를 맡길 수도 있다면? 500명의 손님을 위한 이벤트를 계획할 수도 있다면 어떨까요?"
우리는 웃었습니다.
그리고 우리는 코드베이스 (codebase)를 열었습니다.
그 후 30일 동안, 우리는 잠을 자지 못했습니다.
1주 차: 멀티 서비스 괴물의 각성
슈퍼 앱 (super-app)을 구축하는 것에 대해 아무도 말해주지 않는 사실이 있습니다. 그것은 하나의 앱이 아닙니다. 같은 재킷을 입고 있는 9개의 앱입니다.
월요일 — 우리는 약국 (pharmacy)부터 시작했습니다. 간단하죠? 약국 둘러보기. 약 검색하기. 장바구니에 담기. 결제하기.
하지만 "간단함"은 서비스별 결제 흐름 (checkout flows), 수량 기반 주문, 그리고 공급업체 재고에서 실시간으로 가져오는 완전히 새로운 카테고리 탐색 시스템으로 변했습니다.
화요일 — 슈퍼마켓 (Supermarket)이 코드베이스에 침투했습니다. 식료품 제품. 카테고리 탭. 실제로 원하는 것을 찾아주는 검색 기능. 또 다른 서비스. 또 다른 결제 흐름. 또 다른 2,000줄의 코드.
수요일 — 로컬 마켓 (Local Market). 나이지리아의 야외 시장을 상상해 보세요 — 하지만 당신의 휴대폰 안에 있는 것입니다. 판매자. 품목. 실시간 가용성. 동일한 패턴이지만, 독자적인 정체성이 필요할 만큼 충분히 달랐습니다.
목요일 — 세탁 (Laundry). 픽업 주소. 빠른 서비스 옵션. 보험 지원. 누군가 당신의 옷을 빨아주지 않는다면 슈퍼 앱이라고 할 수 있을까요?
금요일 — 우리는 한 걸음 물러나 홈 화면을 살펴보았습니다. 홈 화면은 카드와 배너가 뒤섞인 난장판이 되어 있었습니다. 그래서 우리는 그것을 다시 만들었습니다. 깔끔한 3열 그리드 (3-column grid). 서비스별 강조 색상 — 약국은 청록색 (teal), 세탁은 파란색 (blue), 로컬 마켓은 초록색 (green), 슈퍼마켓은 노란색 (yellow). 각 섹션은 백엔드 (backend)에서 각자의 추천 판매자를 불러옵니다.
금요일 밤이 되었을 때, 앱은 하나의 서비스에서 다섯 개의 서비스로 늘어나 있었습니다. 홈 화면은 스프린트 리뷰 (sprint review)가 아니라 디자인 포트폴리오에 들어있어야 할 것처럼 보였습니다.
코드베이스 (codebase)는 첫 주에만 **40개 파일에 걸쳐 8,020개의 삽입 (insertions)**이 이루어지며 성장했습니다.
하지만 우리는 끝난 것이 아니었습니다. 근처에도 가지 못했습니다.
2주 차: 사람들이 "잠깐, 이 앱이 '이것'까지 된다고?"라고 말하게 만든 기능들
식사 구독 엔진 (Meal Subscription Engine)
Ile-Ife에 사는 바쁜 직장인을 상상해 보세요. 매일 아침, 그들은 스마트폰을 바라보며 _"오늘 뭐 먹지?"_라고 고민합니다.
우리는 스크롤 가능한 뷰 (scrollable view), 배송 시간 및 주소의 즉시 편집 (in-place editing), 일시 중지 및 취소 기능, 자동 갱신 토글 (auto-renewal toggles), 그리고 플랜을 구성함에 따라 업데이트되는 실시간 비용 미리보기 (real-time cost preview)를 갖춘 캘린더 기반 구독 시스템을 구축했습니다.
캘린더 구현에만 3일이 걸렸습니다. 백엔드 (backend) 통합에는 또 다른 2일이 소요되었습니다. UX 논쟁요? 그건 아직도 진행 중입니다.
기업용 식단 플랜 (직원 점심)
그때 영업 팀에서 폭탄 발언을 던졌습니다:
"기업들이 앱을 통해 직원들의 점심을 관리할 수 있다면 어떨까요?"
직원 수. 1인당 식사 예산. 근무일 전체에 걸친 배송 일정. 배송 시간대.
우리는 완전한 기업용 식사 프로그램을 구축했습니다. 조로프 라이스 (jollof rice)로 시작한 앱이 이제 기업들의 점심시간을 운영하고 있는 셈이니까요.
실제로 무언가를 찾아내는 글로벌 검색 (Global Search)
무엇을 입력하든 똑같은 세 가지 결과만 보여주는 그런 검색창을 아시나요? 네, 우리는 그런 것을 원하지 않았습니다.
우리는 스코어링 알고리즘 (scoring algorithm)을 갖춘 통합 글로벌 검색을 구축했습니다. "paracetamol"을 입력하면 약국 판매자, 특정 의약품을 찾아내고, 올바른 화면으로 딥링크 (deep-link)까지 연결해 줍니다. "pizza"를 입력하면 레스토랑, 특정 메뉴 항목, 심지어 과거 주문 내역까지 나타납니다.
50개 이상의 화면. 모두 검색 가능합니다. 이 모든 것이 탭 바 (tab bar)에 있는 하나의 플로팅 버튼 (floating button)에서 이루어집니다.
3주 차: 게이미피케이션 (Gamification), 예측, 그리고 우리의 뇌를 마비시킨 스핀 휠 (Spin Wheel)
스핀 휠 (The Spin Wheel)
모두가 멋진 스핀 휠 (Spin Wheel)을 좋아합니다. 우리의 스핀 휠은 다중 회전 물리 엔진 (multi-rotation physics)이 적용된 애니메이션 그래픽, 자격 확인 (eligibility checks), 일일 제한 (daily limits), 보상에 대한 실시간 만료 카운트다운 (live expiry countdowns), 그리고 사용자가 수령 완료, 대기 중, 만료된 보상을 추적할 수 있는 전용 인벤토리 화면 (inventory screen)을 갖추고 있습니다.
애니메이션 구현만으로도 커스텀 보간 수학 (custom interpolation math)이 필요했습니다. 하지만 그 휠이 돌아가고 사용자가 승리했을 때? 그동안 망가진 모든 키보드 단축키의 가치가 충분했습니다.
FIFA 2026 월드컵 예측 (FIFA 2026 World Cup Predictions)
이 기능은 순수한 혼돈 그 자체였습니다 — 아주 좋은 의미로 말이죠.
우리는 고객이 2026년 월드컵 경기 승자를 선택할 수 있는 인앱 예측 시스템 (in-app prediction system)을 구축했습니다. 경기 일정 확인. 예측 제출. 예측 내역 추적. 리더보드 (leaderboard) 등반.
주 단위 및 월 단위로 필터링 가능한 리더보드가 있습니다. 트로피 아이콘. 골드 배지. 모든 것이 갖춰져 있습니다.
이것은 배달 앱을 하나의 소셜 경험 (social experience)으로 탈바꿈시켰습니다. 사람들은 이제 단순히 음식을 주문하는 것에 그치지 않습니다. 브라질이 독일을 이길 것인지에 대해 논쟁을 벌이기도 합니다.
4주 차: 결제, 택배, 그리고 실제로 중요한 것들
여기 화려하지 않은 진실이 있습니다: 결제가 실패한다면 아무리 화려한 기능이라도 아무런 의미가 없습니다.
원활한 인앱 결제 (Seamless In-App Payments)
이번 달 이전에는 결제가 외부 브라우저에서 열렸습니다. 사용자는 리다이렉트 (redirected)되어 맥락 (context)을 잃어버렸고, 때로는 다시 돌아오지 못하기도 했습니다.
우리는 결제를 인앱 경험 (in-app experience)으로 옮겼습니다. 매끄럽게. 맥락 안에서. 브라우저 전환 없이.
하지만 그것은 시작에 불과했습니다:
- 실패한 주문에 대한 결제 재시도 (Payment retry for failed orders) — 네트워크는 신뢰할 수 없으며 사용자가 처음부터 다시 시작할 필요가 없어야 하기 때문입니다.
- 중복 제출 방지 (Duplicate submission protection) — 누군가
Google Places를 사용하여 주소 자동 완성 (Autocomplete) 기능을 구축했습니다. 일정 예약을 위한 시간 선택기 (Time pickers), 수동 주소 입력을 위한 역지오코딩 (Reverse geocoding) 기능도 포함되었습니다. 픽업부터 배송까지 모든 단계를 보여주는 타임라인 트래커 (Timeline tracker)도 구현했습니다.
단순히 패키지를 보내는 것이 아닙니다. 패키지가 전국을 가로질러 이동하는 것을 지켜보는 것입니다.
실시간 배송 추적 (Live Delivery Tracking)
지도 이야기가 나와서 말인데—저희는 Google Maps 통합에 깊게 파고들었습니다:
- 화면을 가로질러 움직이는 실시간 라이더 마커 (Real-time rider markers)
- 거리와 도착 예정 시간 (ETA)이 포함된 경로 안내
- 자동 지도 프레이밍 (Automatic map framing)
- 전화 버튼이 포함된 라이더 프로필 표시
배송 지도는 사용자가 가장 오래 응시하는 화면입니다. 저희는 이 화면이 아름답고, 신뢰할 수 있으며, 유익하도록 만들었습니다.
아무도 말하지 않는 보이지 않는 아키텍처 (The Invisible Architecture Nobody Talks About)
게스트-인증 사용자 장바구니 병합 (Guest-to-Authenticated Cart Merging)
사용자가 로그인하지 않은 상태로 앱을 엽니다. 약국들을 둘러봅니다. 장바구니에 파라세타몰 (Paracetamol)을 담습니다. 그러고 나서 로그인합니다.
파라세타몰은 여전히 그곳에 있습니다. 매끄럽게 병합되었습니다. 데이터 손실도 없고, 장바구니 항목이 중복되지도 않습니다.
백그라운드에서는 게스트 토큰 (Guest token) 시스템이 익명 브라우징에서 전체 계정으로 모든 항목이 안전하게 전환되도록 보장합니다.
네트워크 회복 탄력성 (Network Resilience)
모든 API 호출은 지수 백오프 (Exponential backoff)를 적용한 자동 재시도 기능을 갖추고 있습니다. 네트워크가 깜빡거려도 앱은 충돌하지 않습니다. 기다리고, 재시도하고, 복구합니다.
나이지리아에서는 네트워크가 보장되지 않기 때문입니다. 저희는 그 현실에 맞춰 구축했습니다.
수치 (The Numbers)
규모에 대해 이야기해 봅시다:
| 지표 (Metric) | 수치 (Count) |
|---|---|
| 서비스 수직 계열 (Service Verticals) | 9 |
| ... |
다음 단계는? (What's Next?)
저희는 속도를 늦추지 않을 것입니다.
온보딩 (Onboarding) 화면의 "Coming Soon" 슬라이드는 장식이 아닙니다—그것은 약속입니다. 더 많은 서비스. 더 많은 기능. 다른 앱을 다운로드하는 대신 이 앱을 열어야 할 더 많은 이유들.
우리의 목표는 결코 음식 배달 앱을 만드는 것이 아니었기 때문입니다.
우리의 목표는 일상 서비스를 위해 당신이 마지막으로 필요로 할 단 하나의 앱을 만드는 것이었습니다.
그리고 30일 만에, 저희는 그 목표에 매우, 매우 가까워졌습니다.
Foodmartex는 Android에서 이용 가능합니다. iOS는 곧 출시될 예정입니다.
React Native, Redux Toolkit, 그리고 비정상적일 정도로 엄청난 결단력으로 구축되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기