오늘의 칼로리+탄단지(탄수화물/단백질/지방) 목표를 입력하면, 제육볶음·김치찌개 같은 일반 한식 레시피의 정체성은 그대로 유지하면서 재료 양을 목표에 맞게 AI가 자동 조정해 3일치 식단을 추천하는 서비스입니다. 재료 구매 링크, 즐겨찾기, 커뮤니티 공유 기능을 포함합니다.
/frontend React 기반 프론트엔드 (화면 1~4)
/backend API 서버 + AI 재료량 재계산 엔진
/test 통합 테스트 + docker-compose (전체 스택 로컬 실행)
main: 심사 평가 기준 브랜치. 항상 배포 가능한 안정 버전만 유지 (직접 커밋 금지)develop: 통합 개발 브랜치. 각 기능이 검증된 뒤 병합되는 곳test: 테스트 서버용 브랜치. 팀원이 기능을 추가한 뒤 여기서 먼저 실행/검증하고develop으로 병합
브랜치명
test와 폴더명/test는 서로 다른 개념입니다. 브랜치는 git 작업 흐름이고, 폴더는 통합 테스트 코드와 docker-compose가 있는 위치입니다.
작업 흐름: feature/* (개인 작업) → test (통합 검증) → develop (통합) → main (배포 가능 버전만)
git clone <repo-url>
cd 탄단지레시피
cp backend/.env.example backend/.env # ANTHROPIC_API_KEY를 본인 키로 채워넣기
cp frontend/.env.example frontend/.env.env 파일은 절대 커밋하지 마세요 (.gitignore에 이미 제외되어 있습니다).
cd backend
npm install
npm run dev # http://localhost:4000cd frontend
npm install
npm run dev # http://localhost:5173cd test
./run.sh # backend 띄우고 통합 테스트 실행
# 또는
docker compose up --build # frontend+backend 전체 스택 실행자세한 안내는 각 폴더의 README.md를 참고하세요: frontend/README.md, backend/README.md, test/README.md.
이 서비스에서 AI(Claude API)는 딱 한 곳, **"재료량 재계산 엔진"**으로만 사용됩니다.
사용자와 채팅하는 챗봇이 아니라, 구조화된 입력을 받아 구조화된 JSON만 반환하는
백엔드 내부 로직입니다 (backend/src/services/aiEngine.js).
- 입력: 음식 이름 + 표준 재료 구성 + 목표 탄단지(g)
- AI의 판단: 재료 하나를 조정하면 다른 영양소도 함께 변하는 연쇄효과를 고려해 여러 재료를 동시에 조절하고, 요리로서의 정체성을 지키는 선에서 조정하며, 조정 이유를 함께 생성
- 출력:
{ food, adjusted_ingredients, reason }형태의 JSON (nutrition 합계는 AI가 계산하지 않음) - 사용자 경험: 사용자는 폼을 입력하고 결과 화면(카드/표 UI)만 받아봅니다. AI 호출은 화면에 전혀 노출되지 않습니다.
신뢰성을 위한 안전장치:
- 조정된 영양성분은 AI 응답을 그대로 믿지 않고,
services/nutrition.js가 시드 데이터의 g당 영양성분표로 서버가 직접 재계산합니다. - 목표 허용 오차는 탄수화물/단백질/지방 각각 목표치의 ±10% 이내로 정의하며, AI 프롬프트·
백엔드 검증·
/test의 테스트 케이스가 모두 이 기준을 공유합니다. - JSON 파싱/스키마 실패 시 최대 2회 재시도하고, 끝까지 실패하면 원본 재료량으로 fallback하여 API가 절대 500으로 죽지 않도록 합니다.
- 9끼(3일×3끼)를 한 번의 배치 호출로 처리하고, 같은 음식+같은 목표 조합은 캐싱해 재사용합니다.
- API 키/민감정보는 절대 커밋되지 않습니다.
.env는 최상위.gitignore와backend/.gitignore,frontend/.gitignore에서 모두 제외됩니다. - 필요한 환경변수는
backend/.env.example,frontend/.env.example에 변수명만 정리되어 있습니다. 각자.env로 복사한 뒤 본인 키를 채워넣으세요.