타이완메이트 개발기: 대만 여행 올인원 앱을 만들기까지
Flutter + Riverpod + AI 번역 + PDCA 방법론으로 73개 Dart 파일, 9번의 PDCA 사이클을 거쳐 대만 여행 올인원 앱을 완성한 이야기.
🇹🇼 왜 대만 여행 앱을 만들었나
대만 여행을 앞두고 이것저것 준비하다 보니, 앱을 4~5개씩 깔게 됐다. 환율 계산 앱, 번역 앱, 교통 앱, 일정 앱... 각각은 괜찮은데, 여행 중에 앱을 왔다 갔다 하는 게 생각보다 불편했다.
"한국인이 대만에서 겪는 구체적인 상황을 해결하는 앱 하나를 만들자."
이게 출발점이었다.
🏗 기술 스택 선택: 왜 Flutter인가
네이티브 iOS(Swift)로 바로맵을 만들어본 경험이 있었지만, 이번엔 Flutter를 선택했다.
- Android + iOS 동시 출시가 목표였다
- 바로맵은 MapKit/CoreLocation 등 iOS 네이티브 API 의존도가 높았지만, 여행 앱은 그렇지 않았다
- Riverpod의 StateNotifier 패턴이 여행 앱처럼 상태가 많은 앱에 딱 맞았다
상태 관리는 Riverpod으로 통일. MVVM 패턴을 따라 *_provider.dart에 비즈니스 로직을, *_screen.dart에 UI를 분리했다.
📐 PDCA 방법론: 9번의 사이클
타이완메이트는 단순히 코드만 쓴 게 아니라, Plan → Design → Do → Check → Act 사이클을 체계적으로 돌렸다.
| 사이클 | 내용 | Match Rate |
|---|---|---|
| 1차 | 초기 기능 구현 (5탭, 기본 기능) | 96% |
| 2차 | QA 이슈 12건 수정 | 100% |
| 3차 | i18n 완성 + 미구현 기능 추가 | 100% |
| 4차 | 8개 신규 기능 (지출분석, 지도, 날씨 등) | 99% |
| 5차 | 구조적 리팩토링 (대형 파일 분리) | 100% |
| 6차 | 코드 품질 개선 (78→91점) | 91% |
| 7차 | API 서버 구축 + 앱 통합 | 100% |
| 8차 | 버그 수정 + 멀티트립 + 데이터 보강 | 100% |
| 9차 | 탭 구조 최적화 + UX 개선 | 100% |
총 9번의 사이클을 거치면서 설계서와 구현 코드가 100% 일치하는 수준까지 끌어올렸다. "설계서에 있는데 구현 안 된 것"이 0건이 되어야 다음 단계로 넘어갔다.
🎨 디자인 시스템: 일관성의 힘
초기엔 inline 스타일이 곳곳에 있었다. PDCA 7차 사이클에서 이걸 전부 정리했다.
Before:
- 37개 inline TextStyle → 제각각
- 16개 inline InputDecoration → 중복
- 3개 중복 DateRangePicker → 3곳에서 각각 구현
After:
AppTextStyles— 모든 텍스트 스타일 통일AppInputDecorations— 5가지 팩토리 메서드AppDecorations— 카드, 버튼 등 공유 데코레이션AppDimens— 패딩, 라디우스 등 수치 상수AppColors— 다크/라이트 모드 자동 전환
결과적으로 inline 스타일 0개를 달성했다. 새 화면을 만들 때 디자인 고민 없이 시스템에서 꺼내 쓰면 된다.
🤖 AI 기능: 번역 · 숙소 추천 · 일정 추천
번역 기능은 단순히 Google Translate API를 쓸 수도 있었지만, 여행 맥락에 맞는 번역이 필요했다. 야시장 메뉴 "滷肉飯"을 "braised pork rice"가 아니라 **"루로우판 (간장 조림 돼지고기 덮밥)"**처럼 번역해야 의미가 있었다.
그래서 Next.js + Vercel로 자체 API 서버를 구축하고, AI 모델을 활용한 3가지 핵심 기능을 구현했다.
📸 AI 번역
- 텍스트 번역: 중국어 → 한국어/영어 (여행 맥락)
- 이미지 번역: 메뉴판/간판 사진 → OCR + 번역
🏨 AI 숙소 추천
스팟 탭에서 도시별 지역을 선택하면 AI가 숙소를 추천해준다. 시먼딩, 중산, 신이/101 같은 관광 중심 지역별로 럭셔리부터 호스텔까지 등급·가격·위치·팁을 포함한 추천 결과를 보여준다. 탭 한 번이면 구글 지도로 바로 연결된다.
🗓 AI 일정 추천
내 여행 탭에서 여행 날짜와 도시를 설정하면, AI가 날짜별 일정을 짜준다. 맛집, 관광지, 교통, 숙소까지 카테고리별로 시간·장소·예상 비용을 포함한 플랜을 생성한다. 마음에 안 드는 날은 개별 리롤, 전체 재생성도 가능하고, 마음에 들면 바로 내 일정에 적용하거나 참고용으로 저장할 수 있다.
🏮 데이터: 야시장 30곳, 메뉴 177개
대만 야시장 데이터를 직접 수집하고 정리했다.
- 6개 도시: 타이베이, 가오슝, 타이중, 화롄, 자이, 난투
- 30개 야시장: 스린, 라오허제, 닝샤, 류허, 펑자 등
- 177개 메뉴: 가격, 한국어/영어 설명, 추천 태그
- 교통 데이터: MRT 5노선 구간·요금, 버스 노선, 택시 기본요금, YouBike 요금, 고속철도 노선
7차에 걸쳐 데이터 오류를 수정했다. 반난선 종점역명, 문후선 구간, 택시 기본요금(85TWD), YouBike 요금(10TWD), 1819번 버스 요금(140TWD), 고속철도 타이난 환승 정보 등.
🧳 사소하지만 중요한 기능들
대만 여행에서 실제로 당황하는 순간들을 해결하는 작은 기능들:
✋ 숫자 손동작 가이드
대만에서 610을 손으로 표현하는 방식이 한국과 완전히 다르다. 야시장에서 "6개 주세요" 하려다 엉뚱한 수량을 받을 수 있다. 110까지 대만식 손동작을 일러스트와 함께 정리했다.
🧮 야시장 합산 계산기
야시장에서 이것저것 사먹다 보면 "지금까지 얼마 썼지?" 싶을 때가 있다. +50, +100, +200 원터치 버튼으로 먹은 것들을 쭉 추가하면 총 TWD + KRW + USD를 한눈에 보여준다.
🧳 짐싸기 체크리스트
28개 항목을 6개 카테고리(서류, 돈, 전자기기, 의류, 세면도구, 기타)로 정리. "필수" 태그가 붙은 항목은 눈에 띄게 표시. 체크 상태는 로컬 저장되니까 출발 전까지 하나씩 체크하면 된다.
🛫 귀국 준비 가이드
면세 한도(2,000TWD 이상 영수증 필요), 반입 금지 품목(육류, 과일), 면세점 추천, 공항 체크리스트까지. "이거 가져가도 되나?" 하는 고민을 줄여준다.
🔐 보안: 민감 정보는 암호화
여권번호, 숙소 주소 같은 개인정보는 SharedPreferences가 아니라 **FlutterSecureStorage**에 암호화 저장한다. iOS Keychain / Android Keystore를 활용해서 기기에서만 복호화할 수 있다.
📊 프로젝트 규모
| 항목 | 수치 |
|---|---|
| Dart 파일 수 | 73개 |
| i18n 문자열 | 270+ |
| PDCA 사이클 | 9회 |
| AI 기능 | 3개 (번역, 숙소 추천, 일정 추천) |
| 디자인 시스템 컴포넌트 | 5개 모듈 |
| 야시장 데이터 | 30곳 / 177메뉴 |
| 교통 데이터 | MRT 5노선 + HSR + 버스 + 택시 + YouBike |
| 개발 기간 | 약 2주 |
🎯 회고
잘한 점
- PDCA를 진짜로 돌렸다. 설계서를 쓰고, 구현하고, 갭 분석을 돌리고, 부족한 부분을 수정하는 사이클을 9번 반복. 결과적으로 "설계서에 있는데 안 된 거"가 0건이 된 건 처음이다.
- 디자인 시스템을 초중반에 정립했다. 덕분에 후반 기능 추가 속도가 눈에 띄게 빨라졌다.
- 데이터를 직접 수집·검증했다. API에 의존하지 않고 로컬 데이터로 오프라인에서도 동작하게 만든 건 여행 앱에서 핵심이었다.
아쉬운 점
- 초기에 inline 스타일을 많이 쓰고 나중에 정리한 건 비효율적이었다. 처음부터 시스템을 세우고 시작했으면 리팩토링 2사이클을 아꼈을 것.
- 테스트 코드가 없다. 수동 QA로 커버했지만, 유지보수를 생각하면 위젯 테스트라도 있었으면 좋겠다.
다음 계획
- Android 빌드 최적화 + Google Play 출시
- 실시간 날씨 API 연동
- 오프라인 지도 가이드
- 사용자 리뷰 기반 데이터 보강
💬 마무리
1인 개발로 2주 만에 73개 파일, 270+ i18n 문자열, 9번의 PDCA 사이클을 완주했다.
**AI 어시스턴트(Claude)와 함께하는 개발은 "혼자"가 아니라 "팀"**이라는 걸 다시 한번 느꼈다. 설계서 작성부터 갭 분석, 코드 리뷰까지 — 사람 한 명이 할 수 있는 범위를 확실히 넓혀준다.
대만 여행을 준비하는 분들에게 타이완메이트가 든든한 동반자가 되길 바란다. 🇹🇼