Lunch LuckyVicky
점심 메뉴 선택과 후식 비용 분담을 자동화하는 팀 협업 앱. 만장일치 거부권과 게임화된 룰렛으로 공정한 점심 결정을 만듭니다.
Overview
프로젝트 개요
매일 반복되는 "오늘 뭐 먹지?" 고민을 해결합니다. 팀이 큐레이션한 식당 풀에서 무작위 1개를 추천하고, 1명이라도 거부하면 즉시 재추천하는 만장일치 원칙을 적용합니다.
거부자에게는 후식 룰렛 당첨 확률이 올라가는 페널티가 부과되어 무분별한 반대를 방지합니다. Flutter로 iOS/Android/Web 크로스플랫폼을 지원합니다.
Architecture
프로젝트 구조
lib/
├── main.dart # 엔트리 포인트
├── core/
│ ├── router.dart # GoRouter 설정
│ ├── theme.dart # 앱 테마
│ └── network_check.dart # 오프라인 감지
└── features/
├── auth/ # Google 로그인
│ ├── domain/app_user.dart
│ ├── data/auth_repository.dart
│ └── presentation/login_screen.dart
├── group/ # 그룹 & 식당 관리
│ ├── domain/ (group, restaurant, menu_item)
│ ├── data/group_repository.dart # 388줄
│ └── presentation/
│ └── group_home_screen.dart # 3,354줄
├── session/ # 추천 & 수락/거부
│ ├── data/session_repository.dart # 359줄
│ └── presentation/
│ └── suggestion_screen.dart # 454줄
└── roulette/ # 후식 룰렛
├── data/roulette_repository.dart
└── presentation/
└── roulette_screen.dart # 597줄
functions/
└── src/index.ts # Kakao API 검색Feature-Based Architecture
auth, group, session, roulette 4개 피처로 분리. 각 피처는 domain/data/presentation 3계층 구조로 관심사를 명확히 분리합니다.
Firebase 실시간 동기화
Firestore 스트림으로 그룹 멤버, 식당, 세션 상태를 실시간 동기화. Riverpod Provider가 상태 변화를 자동으로 UI에 반영합니다.
Key Features
주요 기능
만장일치 추천 엔진
식당 풀에서 무작위 1개를 추천하고, 최근 5일 방문 식당은 자동 제외합니다. 1명이라도 거부하면 즉시 재추천하는 민주적 결정 방식입니다.
페널티 룰렛 시스템
거부 횟수에 비례해 후식 당첨 확률이 증가하는 가중 모드를 지원합니다. 시각적 룰렛 애니메이션과 confetti 축하 효과로 재미를 더합니다.
식당 큐레이션 & 지도
Google Places로 식당을 검색·등록하고, 카테고리·메뉴·가중치를 관리합니다. Google Maps로 위치를 확인하고 즐겨찾기로 관리할 수 있습니다.
크로스플랫폼 & 실시간
Flutter로 iOS, Android, Web을 단일 코드베이스로 지원합니다. Firestore 실시간 스트림으로 팀원 간 상태가 즉시 동기화됩니다.
Flow
사용 흐름
초대 코드로 팀 그룹에 참가하거나 새 그룹 생성
점심 참석 여부 토글, 매일 자정 자동 초기화
무작위 식당 제시, 1명이라도 거부 시 즉시 재추천
확정된 식당의 메뉴에서 각자 선택
거부 패널티 가중치 반영, 당첨자가 후식 비용 부담
Data Pipeline
식당 데이터 자동 수집
앱에 등록된 식당의 메뉴·가격·주소·좌표 정보를 네이버 지도에서 자동으로 크롤링하는 별도 파이프라인입니다. Playwright로 브라우저를 자동화하고, 결과를 Firebase에 동기화합니다.
restaurant-crawler/
├── src/
│ ├── index.ts # 크롤링 오케스트레이터
│ ├── naverMapCrawler.ts # 네이버 지도 스크래핑
│ ├── firebase.ts # Firestore CRUD
│ └── utils.ts # Haversine 거리 계산
└── .github/workflows/ # 자동 스케줄 (GitHub Actions)3단계 스크래핑 전략
네트워크 API 인터셉트 → API 직접 호출 → DOM 폴백 순으로 시도합니다. Haversine 공식으로 반경 500m 내 결과만 필터링합니다.
자동 동기화
크롤링 결과(메뉴, 가격, 좌표)를 Firebase에 자동 업데이트합니다. 앱에서 별도 작업 없이 항상 최신 메뉴 정보를 확인할 수 있습니다.
Comments
불러오는 중...