개발 요구 사항
1. 개발 범위
| 구분 | 범위 |
|---|---|
| 웹 | 재고 · 영수증 · 레시피 · 어시스턴트 · 쇼핑 · 날씨 · 게임 · 로그인/회원가입 |
| 모바일 | 인트로 영상, 랜딩, 공개 식재료 카탈로그, 위치 기반 날씨 |
| API | /api/fridge/* (inventory · category · food · receipt · receipt-line · recipe-feedback · recipe-ingredients · game-scores · assistant · user), /weather, /api/receipts/images, /auth/{provider} |
| 제외 | 영수증 원본의 DB 저장, 유통기한 푸시 알림, 소비 패턴 분석 (설계만) |
2. 재고 관리
- 재고 항목은 이름, 수량, 단위, 유통기한, 구매일, 보관 위치(기본 냉장), 최소 수량, 상태(기본 정상)를 가진다.
- 유통기한이 없으면 구매일 + 보관 기간(
shelfLifeDays)으로 추정하고expiryIsEstimated로 표시한다. - 수량이 최소 수량 아래로 내려가면 부족으로 보고 쇼핑 연결에 넘긴다.
3. 영수증 → 재고
흐름: S3 업로드 → /api/fridge/receipt/scan-key(Gemini Vision) → 사용자 확인·수정 → POST /api/fridge/inventory
- OCR 엔진과 이미지 리더는 포트로 분리해 모델을 바꿔도 도메인 코드는 그대로 둔다.
- 모델명은 하드코딩하지 않고
GEMINI_MODEL환경변수로 받는다. - 인식 결과는 사용자가 확인한 것만 저장한다.
4. AI 추천 · 어시스턴트
- 레시피: Gemini 호출이 실패하거나 키가 없으면 준비된 레시피로 대체하고 실패 사실을 안내한다.
- 어시스턴트: EXAONE(vLLM)으로 프록시하며, 웹은 채팅 요청만 통합 API로 보낸다.
5. 인증 · 보안
- 소셜 로그인은 사전가입한 사용자만 통과한다. provider까지 일치해야 하고, 미가입자는 회원가입 화면으로 보낸다.
- 가입 의도는 Redis의 OAuth state에 담고, 연동 계정은
user_oauth_accounts에 저장한다. - 외부 API 키(OpenWeather, Gemini)는 서버에만 둔다.