LeanMate는 감량, 유지, 린매스업 목표에 맞춰 하루 섭취 칼로리와 탄단지를 계산하고, 식단 기록과 그룹 운동 출석을 함께 관리하는 웹앱입니다.
- 성별, 나이, 키, 현재 체중 기반 기초대사량 계산
- 감량, 유지, 린매스업 목적별 하루 권장 칼로리 계산
- 4주, 8주, 12주 기간 선택에 따른 칼로리 조정
- 탄수화물, 단백질, 지방 목표 g 계산
- 음식별 kcal와 탄단지 기록
- 로컬 음식 DB, 직접 입력 음식 저장, 즐겨찾기 기반 빠른 식단 추가
- 목표 대비 남은 kcal와 탄단지 진행률 표시
- 날짜별 그룹 운동 출석 기록
- 최근 7일 운동 출석 기록과 이번 달 운동 출석 기록 시각화
- 선택 날짜별 독립 출석 체크
- 주간 출석 횟수와 연속 출석일 기반 랭킹
- 친구 출석 상태와 내 연속 출석일을 비교한 동기부여 문구
/api/food-search서버리스 함수 기반 음식 영양정보 검색- 기본 음식 DB 검색 결과 또는 직접 입력값 확인/수정 후 식단 추가
- OOP 상속 구조를 별도 Architecture 메뉴에서 시각화
남자: 66.47 + (13.75 * 체중) + (5 * 키) - (6.76 * 나이)
여자: 655.1 + (9.56 * 체중) + (1.85 * 키) - (4.68 * 나이)
FitnessModule
├─ GoalPlan
│ ├─ CuttingPlan
│ ├─ MaintainPlan
│ └─ LeanBulkPlan
├─ FoodSearchModule
├─ MealRecord
└─ AttendanceRecord
FitnessModule: 공통run()인터페이스를 정의하는 부모 클래스GoalPlan: 기초대사량과 유지 칼로리를 계산하는 목표 계산 클래스들의 부모 클래스CuttingPlan,MaintainPlan,LeanBulkPlan: 목적별 칼로리와 탄단지 계산을 오버라이딩FoodSearchModule: 로컬 음식 DB를Map으로 조회하고 검색 후보Array를 반환MealRecord: 식단 배열을 합산해 오늘 섭취량과 남은 칼로리를 계산AttendanceRecord: 날짜별 운동 출석 기록을 바탕으로 주간 랭킹과 연속 출석일 계산
Architecture 화면에서는 각 클래스 노드를 클릭하면 해당 클래스 객체의 run() 메서드가 호출된 결과가 출력됩니다. 모든 기능 클래스는 같은 run() 메서드를 가지고 있지만, 각 클래스가 이를 오버라이딩하여 기초대사량 계산, 감량/유지/린매스업 목표 계산, 음식 검색, 식단 합산, 운동 출석 랭킹 계산처럼 서로 다른 결과를 출력합니다.
const selectedModule = modules[className];
const result = selectedModule.run(context);Map: 음식 이름을 key로 영양성분 조회Array: 식단 목록, 검색 후보 목록, 그룹원 목록, 출석 날짜 목록 관리Stack: 마지막 식단 추가 기록 되돌리기Sort: 주간 운동 출석 랭킹 계산Set: 즐겨찾기 음식 중복 방지와 연속 출석일 계산 시 날짜 포함 여부 확인
index.html 파일을 브라우저에서 열면 바로 실행됩니다.
로컬 서버로 확인하려면 아래 명령을 사용할 수 있습니다.
python -m http.server 4173이후 http://127.0.0.1:4173/index.html에 접속합니다.
실제 친구들과 같은 그룹 출석 데이터를 공유하려면 Supabase와 Vercel 환경 변수를 설정합니다.
- Supabase 프로젝트 생성
- Supabase SQL Editor에서
supabase-schema.sql실행 - Vercel 프로젝트 환경 변수에 아래 값 추가
SUPABASE_URL=...
SUPABASE_SERVICE_ROLE_KEY=...
OPENAI_API_KEY=...
OPENAI_MODEL=gpt-4.1-mini
- GitHub에 push 후 Vercel 재배포
서버리스 API는 아래 경로를 사용합니다.
GET /api/members
POST /api/members
GET /api/attendance?date=YYYY-MM-DD
POST /api/attendance
POST /api/food-search
Vercel 환경 변수와 Supabase가 설정되어 있으면 그룹 출석은 Supabase에 저장됩니다. 로컬에서 file://로 실행하거나 백엔드 설정이 없으면 브라우저 localStorage를 fallback 저장소로 사용합니다.
OpenAI API 키는 프론트엔드에 노출하지 않고 /api/food-search 서버리스 함수에서만 사용합니다. 현재 식단 추가 흐름은 로컬 음식 DB와 직접 입력을 우선 사용하며, 기본 DB 음식은 섭취량만 조절하고 직접 입력 음식은 사용자가 kcal와 탄단지를 입력한 뒤 저장합니다.
main 브랜치는 안정 버전으로 유지하고, 기능 수정은 별도의 브랜치에서 진행한 뒤 Pull Request를 통해 병합하는 방식으로 관리하였다.
이번 프로젝트에서는 목표 계산, 배포 설정, 음식 검색, UI 개선, OOP Architecture 수정 작업을 각각 기능 단위로 분리하여 진행하였다. 이를 통해 기능별 변경 사항을 구분하고, 문제가 생겼을 때 수정 범위를 쉽게 파악할 수 있도록 하였다.
feature/goal-calculation: 목표 분류와 탄단지 계산 공식 수정feature/deployment-config: Vercel 배포 설정 수정feature/local-food-db-and-favorites: 로컬 음식 DB와 즐겨찾기 기능feature/final-ui-polish: 최종 UI/UX 정리 및 OOP Architecture UML 시각화 개선feature/oop-architecture: OOP 상속 구조 시각화 개선