# 🍽️ 였늘 뭐 λ¨ΉZ? (LunchPick) > 맀일 λ°˜λ³΅λ˜λŠ” 점심 메뉴 고민을 ν•΄κ²°ν•˜λŠ” μŠ€λ§ˆνŠΈν•œ 메뉴 μΆ”μ²œ μ•± [![Flutter Version](https://img.shields.io/badge/Flutter-3.8.1+-blue.svg)](https://flutter.dev) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) ## πŸ“± μ†Œκ°œ **였늘 뭐 λ¨ΉZ?**λŠ” 직μž₯μΈλ“€μ˜ 점심 메뉴 선택 고민을 ν•΄κ²°ν•˜κΈ° μœ„ν•œ Flutter 기반 λͺ¨λ°”일 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μž…λ‹ˆλ‹€. 넀이버 μ§€λ„μ—μ„œ 맛집을 κ°„νŽΈν•˜κ²Œ μˆ˜μ§‘ν•˜κ³ , 날씨와 거리λ₯Ό κ³ λ €ν•œ μŠ€λ§ˆνŠΈν•œ μΆ”μ²œμ„ 받을 수 μžˆμŠ΅λ‹ˆλ‹€. ### 🎯 핡심 κ°€μΉ˜ - **μ˜μ‚¬κ²°μ • μ‹œκ°„ 단좕**: 점심 선택 μ‹œκ°„μ„ 10-15λΆ„μ—μ„œ 1λΆ„μœΌλ‘œ - **메뉴 λ‹€μ–‘μ„± 보μž₯**: 쀑볡 λ°©λ¬Έ λ°©μ§€ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ μƒˆλ‘œμš΄ κ²½ν—˜ 제곡 - **νŽΈλ¦¬ν•œ λ§›μ§‘ 관리**: 넀이버 지도 URL둜 κ°„νŽΈν•˜κ²Œ λ§›μ§‘ μΆ”κ°€ ## ✨ μ£Όμš” κΈ°λŠ₯ ### 🎰 랜덀 메뉴 μΆ”μ²œ - 날씨 기반 거리 μžλ™ μ‘°μ • (우천 μ‹œ 500m 이내) - n일 이내 재방문 κΈˆμ§€ μ„€μ • - μΉ΄ν…Œκ³ λ¦¬λ³„ 필터링 - 1-Tap μΆ”μ²œ μ‹œμŠ€ν…œ ### πŸ“ 넀이버 지도 연동 - 넀이버 단좕 URL(naver.me) μžλ™ νŒŒμ‹± - 식당 정보 μžλ™ μΆ”μΆœ - μœ„μΉ˜ 정보 및 μΉ΄ν…Œκ³ λ¦¬ μžλ™ λΆ„λ₯˜ ### πŸ“Š λ°©λ¬Έ 기둝 관리 - μΊ˜λ¦°λ” 뷰둜 λ°©λ¬Έ 이λ ₯ 확인 - λ°©λ¬Έ 톡계 μ‹œκ°ν™” - μžλ™ λ°©λ¬Έ 확인 μ•Œλ¦Ό (점심 ν›„ 1.5~2μ‹œκ°„) ### 🌦️ 날씨 연동 - ν˜„μž¬ 날씨 및 1μ‹œκ°„ ν›„ 날씨 예보 - 우천 μ‹œ κ°€κΉŒμš΄ λ§›μ§‘ μš°μ„  μΆ”μ²œ ### πŸ“± Bluetooth 곡유 - 근처 기기와 λ§›μ§‘ 리슀트 곡유 - νŒ€ νšŒμ‹ μ‹œ λΉ λ₯Έ μ˜μ‚¬κ²°μ • 지원 ### πŸ”” 슀마트 μ•Œλ¦Ό - λ°©λ¬Έ 확인 ν‘Έμ‹œ μ•Œλ¦Ό - μ•Œλ¦Ό μ‹œκ°„ μ»€μŠ€ν„°λ§ˆμ΄μ§• ## πŸ“Έ μŠ€ν¬λ¦°μƒ·
μŠ€ν”Œλž˜μ‹œ
μŠ€ν”Œλž˜μ‹œ
ν™ˆ
ν™ˆ ν™”λ©΄
λ§›μ§‘ 리슀트
λ§›μ§‘ 리슀트
방문 기둝
방문 기둝
## πŸ› οΈ 기술 μŠ€νƒ ### Frontend - **Framework**: Flutter 3.8.1+ - **State Management**: Riverpod 2.4.0 - **Local Database**: Hive 2.2.3 - **Navigation**: Go Router 13.0.0 - **Architecture**: Clean Architecture + MVVM ### API & Services - **넀이버 지도 API**: μž₯μ†Œ 검색 및 상세 정보 - **기상청 Open API**: μ‹€μ‹œκ°„ 날씨 정보 - **Google AdMob**: κ΄‘κ³  μˆ˜μ΅ν™” ### μ£Όμš” 라이브러리 - `dio`: HTTP λ„€νŠΈμ›Œν‚Ή - `flutter_blue_plus`: Bluetooth 톡신 - `geolocator`: μœ„μΉ˜ μ„œλΉ„μŠ€ - `flutter_local_notifications`: 둜컬 μ•Œλ¦Ό - `table_calendar`: μΊ˜λ¦°λ” UI - `adaptive_theme`: 닀크λͺ¨λ“œ 지원 ## πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰 ``` lib/ β”œβ”€β”€ core/ # 곡톡 μœ ν‹Έλ¦¬ν‹°, μƒμˆ˜, μœ„μ ― β”‚ β”œβ”€β”€ constants/ # μ•± μƒμˆ˜, 컬러, νƒ€μ΄ν¬κ·Έλž˜ν”Ό β”‚ β”œβ”€β”€ errors/ # μ˜ˆμ™Έ 처리 β”‚ β”œβ”€β”€ network/ # λ„€νŠΈμ›Œν¬ ν΄λΌμ΄μ–ΈνŠΈ β”‚ β”œβ”€β”€ utils/ # μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜ β”‚ └── widgets/ # 곡톡 μœ„μ ― β”œβ”€β”€ data/ # 데이터 λ ˆμ΄μ–΄ β”‚ β”œβ”€β”€ api/ # API ν΄λΌμ΄μ–ΈνŠΈ β”‚ β”œβ”€β”€ datasources/ # 데이터 μ†ŒμŠ€ (둜컬/원격) β”‚ β”œβ”€β”€ models/ # 데이터 λͺ¨λΈ β”‚ └── repositories/ # λ ˆν¬μ§€ν† λ¦¬ κ΅¬ν˜„ β”œβ”€β”€ domain/ # 도메인 λ ˆμ΄μ–΄ β”‚ β”œβ”€β”€ entities/ # λΉ„μ¦ˆλ‹ˆμŠ€ μ—”ν‹°ν‹° β”‚ β”œβ”€β”€ repositories/ # λ ˆν¬μ§€ν† λ¦¬ μΈν„°νŽ˜μ΄μŠ€ β”‚ └── usecases/ # μœ μ¦ˆμΌ€μ΄μŠ€ └── presentation/ # ν”„λ ˆμ  ν…Œμ΄μ…˜ λ ˆμ΄μ–΄ β”œβ”€β”€ pages/ # ν™”λ©΄ β”œβ”€β”€ providers/ # Riverpod ν”„λ‘œλ°”μ΄λ” └── widgets/ # UI μœ„μ ― ``` ## πŸš€ μ‹œμž‘ν•˜κΈ° ### μš”κ΅¬μ‚¬ν•­ - Flutter SDK 3.8.1 이상 - Dart SDK 3.0 이상 - Android Studio / VS Code - iOS: Xcode 14.0+ (iOS λΉŒλ“œ μ‹œ) ### μ„€μΉ˜ 방법 1. **μ €μž₯μ†Œ 클둠** ```bash git clone https://gitea.chizstudio.com/julian/lunchpick.git cd lunchpick ``` 2. **μ˜μ‘΄μ„± μ„€μΉ˜** ```bash flutter pub get ``` 3. **API ν‚€ μ„€μ •** 넀이버 Client ID/Secret은 ν™˜κ²½ λ³€μˆ˜λ‘œ μ£Όμž…ν•©λ‹ˆλ‹€. 민감 μ •λ³΄λŠ” base64둜 μΈμ½”λ”©ν•œ λ’€ `--dart-define`으둜 μ „λ‹¬ν•˜μ„Έμš”. ```bash # macOS/Linux NAVER_CLIENT_ID=$(printf 'YOUR_NAVER_CLIENT_ID' | base64) NAVER_CLIENT_SECRET=$(printf 'YOUR_NAVER_CLIENT_SECRET' | base64) flutter run \ --dart-define=NAVER_CLIENT_ID=$NAVER_CLIENT_ID \ --dart-define=NAVER_CLIENT_SECRET=$NAVER_CLIENT_SECRET # ν…ŒμŠ€νŠΈ μ‹€ν–‰ μ‹œμ—λ„ λ™μΌν•˜κ²Œ 전달 flutter test \ --dart-define=NAVER_CLIENT_ID=$NAVER_CLIENT_ID \ --dart-define=NAVER_CLIENT_SECRET=$NAVER_CLIENT_SECRET ``` 둜컬 κ°œλ°œμ—μ„œλ§Œ μž„μ‹œλ‘œ 평문을 μ‚¬μš©ν•˜λ €λ©΄ base64 인코딩을 μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 4. **μ½”λ“œ 생성** ```bash flutter pub run build_runner build --delete-conflicting-outputs ``` ### 개발 λͺ¨λ“œ μ‹€ν–‰ ```bash # iOS flutter run -d ios # Android flutter run -d android # Web (μ‹€ν—˜μ ) flutter run -d chrome ``` ### ν”„λ‘œλ•μ…˜ λΉŒλ“œ ```bash # Android APK flutter build apk --release # Android App Bundle flutter build appbundle --release # iOS flutter build ios --release ``` ## πŸ§ͺ ν…ŒμŠ€νŠΈ ### λ‹¨μœ„ ν…ŒμŠ€νŠΈ μ‹€ν–‰ ```bash flutter test ``` ### νŠΉμ • ν…ŒμŠ€νŠΈ 파일 μ‹€ν–‰ ```bash flutter test test/unit/domain/usecases/recommendation_engine_test.dart ``` ### ν…ŒμŠ€νŠΈ 컀버리지 ```bash flutter test --coverage genhtml coverage/lcov.info -o coverage/html ``` ## πŸ“ λ¬Έμ„œ μžμ„Έν•œ λ¬Έμ„œλŠ” [`doc/`](./doc) 디렉토리λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”: - [개발 κ°€μ΄λ“œ](doc/01_requirements/였늘%20뭐%20λ¨ΉZ%3F%20μ™„μ „ν•œ%20개발%20κ°€μ΄λ“œ.md) - [μ•„ν‚€ν…μ²˜ κ°œμš”](doc/03_architecture/architecture_overview.md) - [μ½”λ“œ μ»¨λ²€μ…˜](doc/03_architecture/code_convention.md) - [넀이버 URL 처리 κ°€μ΄λ“œ](doc/04_api/naver_short_url_guide.md) ## 🀝 κΈ°μ—¬ν•˜κΈ° ### 브랜치 μ „λž΅ - `main`: ν”„λ‘œλ•μ…˜ 배포 브랜치 - `develop`: 개발 브랜치 - `feature/*`: κΈ°λŠ₯ 개발 - `bugfix/*`: 버그 μˆ˜μ • - `hotfix/*`: κΈ΄κΈ‰ μˆ˜μ • ### 컀밋 μ»¨λ²€μ…˜ ``` type(scope): κ°„λ‹¨ν•œ μ„€λͺ… 상세 μ„€λͺ… (선택사항) Resolves: #이슈번호 ``` νƒ€μž…: - `feat`: μƒˆλ‘œμš΄ κΈ°λŠ₯ - `fix`: 버그 μˆ˜μ • - `docs`: λ¬Έμ„œ μˆ˜μ • - `style`: μ½”λ“œ ν¬λ§·νŒ… - `refactor`: λ¦¬νŒ©ν† λ§ - `test`: ν…ŒμŠ€νŠΈ μ½”λ“œ - `chore`: λΉŒλ“œ, νŒ¨ν‚€μ§€ κ΄€λ ¨ ### Pull Request κ°€μ΄λ“œλΌμΈ 1. `develop` λΈŒλžœμΉ˜μ—μ„œ feature 브랜치 생성 2. μž‘μ—… μ™„λ£Œ ν›„ PR 생성 3. μ½”λ“œ 리뷰 ν›„ λ¨Έμ§€ 4. 브랜치 μ‚­μ œ ## πŸ“„ λΌμ΄μ„ΌμŠ€ 이 ν”„λ‘œμ νŠΈλŠ” MIT λΌμ΄μ„ΌμŠ€ ν•˜μ— λ°°ν¬λ©λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ [LICENSE](LICENSE) νŒŒμΌμ„ μ°Έμ‘°ν•˜μ„Έμš”. ## πŸ“ž μ—°λ½μ²˜ - **개발자**: NatureBridgeAI - **이메일**: contact@naturebridgeai.com - **이슈 트래컀**: [GitHub Issues](https://gitea.chizstudio.com/julian/lunchpick/issues) ---
Built with ❀️ by NatureBridgeAI