# 🍽️ 오늘 뭐 먹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 공유
- 근처 기기와 맛집 리스트 공유
- 팀 회식 시 빠른 의사결정 지원

### 🔔 스마트 알림
- 방문 확인 푸시 알림
- 알림 시간 커스터마이징

## 📸 스크린샷

<div align="center">
<table>
  <tr>
    <td align="center">
      <img src="docs/screenshots/splash.png" width="200px" alt="스플래시"/>
      <br />
      <sub><b>스플래시</b></sub>
    </td>
    <td align="center">
      <img src="docs/screenshots/home.png" width="200px" alt="홈"/>
      <br />
      <sub><b>홈 화면</b></sub>
    </td>
    <td align="center">
      <img src="docs/screenshots/list.png" width="200px" alt="맛집 리스트"/>
      <br />
      <sub><b>맛집 리스트</b></sub>
    </td>
    <td align="center">
      <img src="docs/screenshots/calendar.png" width="200px" alt="방문 기록"/>
      <br />
      <sub><b>방문 기록</b></sub>
    </td>
  </tr>
</table>
</div>

## 🛠️ 기술 스택

### 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)

---

<div align="center">
  <sub>Built with ❤️ by NatureBridgeAI</sub>
</div>
