diff --git a/back/src/controllers/habittrackerController.js b/back/src/controllers/habittrackerController.js index 7ee920aab8315dec92f4ad8dfb09fe97e28a6b71..cbeb7121f309b745ba3846c67618f6c49c5c8af7 100644 --- a/back/src/controllers/habittrackerController.js +++ b/back/src/controllers/habittrackerController.js @@ -2,6 +2,7 @@ const { minutesToSeconds, secondsToMinutes } = require('../utils/timeconvert'); //habittracker구조 const HabitTracker = require('../models/habittracker'); +const Records = require('../models/records'); //goal_weight는 habit tracker schema 안에 존재하도록 const habittrackerController = { @@ -68,6 +69,7 @@ const habittrackerController = { res.status(200).json(habitTrackergoal); } catch (error) { + console.error(error); res.status(500).json({ message: 'Failed to get habitTracker goals', error: error.message, @@ -75,18 +77,19 @@ const habittrackerController = { } }, getEveryRecords: async (req, res) => { - const { period } = req.query.period; + const { period } = req.query; try { //정규식 const regex = new RegExp(`^${period}`); //해당 월에 해당하는 운동 기록들을 가져옴 - const monthlyRecords = Record.find({ + const monthlyRecords = await Records.find({ user_id: req.user.user_id, //미들웨어에 있는 user_id date: { $regex: regex }, - }); + }).exec(); res.status(200).json(monthlyRecords); } catch (error) { + console.error('GetEveryRecords Error:', error); res.status(500).json({ message: 'Failed to get habitTracker monthly records', error: error.message, diff --git a/back/src/initDB.js b/back/src/initDB.js index 8026af3babaee015814b1a456622c33d321770b5..a635e85fccd933afc08a29fd9b3995da6edf7c29 100644 --- a/back/src/initDB.js +++ b/back/src/initDB.js @@ -14,36 +14,36 @@ const timestampOptions = { }; const foodOptions = [ - { name: "계란", calories: 70, carbs: 1, protein: 6, fat: 5 }, - { name: "밥", calories: 300, carbs: 68, protein: 6, fat: 0.5 }, - { name: "닭가슴살", calories: 120, carbs: 0, protein: 23, fat: 2 }, - { name: "사과", calories: 80, carbs: 21, protein: 0.5, fat: 0.3 }, - { name: "고구마", calories: 86, carbs: 20, protein: 1.6, fat: 0.1 }, - { name: "바나나", calories: 89, carbs: 23, protein: 1.1, fat: 0.3 }, - { name: "오렌지", calories: 62, carbs: 15, protein: 1.2, fat: 0.2 }, - { name: "소고기", calories: 250, carbs: 0, protein: 26, fat: 17 }, - { name: "돼지고기", calories: 242, carbs: 0, protein: 27, fat: 14 }, - { name: "고등어", calories: 189, carbs: 0, protein: 20, fat: 12 }, - { name: "연어", calories: 206, carbs: 0, protein: 22, fat: 13 }, - { name: "두부", calories: 76, carbs: 1.9, protein: 8, fat: 4.8 }, - { name: "김치", calories: 33, carbs: 6.1, protein: 1.1, fat: 0.2 }, - { name: "우유", calories: 42, carbs: 5, protein: 3.4, fat: 1 }, - { name: "요거트", calories: 59, carbs: 3.6, protein: 10, fat: 0.4 }, - { name: "치킨", calories: 239, carbs: 0, protein: 27, fat: 14 }, - { name: "고추", calories: 40, carbs: 9, protein: 2, fat: 0.4 }, - { name: "양파", calories: 40, carbs: 9, protein: 1.1, fat: 0.1 }, - { name: "당근", calories: 41, carbs: 10, protein: 0.9, fat: 0.2 }, - { name: "감자", calories: 77, carbs: 17, protein: 2, fat: 0.1 }, - { name: "브로콜리", calories: 34, carbs: 7, protein: 2.8, fat: 0.4 }, - { name: "호박", calories: 26, carbs: 6.5, protein: 1, fat: 0.1 }, - { name: "치즈", calories: 402, carbs: 1.3, protein: 25, fat: 33 }, - { name: "햄", calories: 145, carbs: 1.3, protein: 20, fat: 7 }, - { name: "소시지", calories: 301, carbs: 2, protein: 11, fat: 28 }, - { name: "초콜릿", calories: 546, carbs: 61, protein: 4.9, fat: 31 }, - { name: "아몬드", calories: 576, carbs: 21, protein: 21, fat: 49 }, - { name: "땅콩", calories: 567, carbs: 16, protein: 25, fat: 49 }, - { name: "식빵", calories: 265, carbs: 49, protein: 9, fat: 3.2 }, - { name: "파스타", calories: 131, carbs: 25, protein: 5, fat: 1.1 }, + { food_id:1, name: "계란", calories: 70, carbs: 1, protein: 6, fat: 5 }, + { food_id:2, name: "밥", calories: 300, carbs: 68, protein: 6, fat: 0.5 }, + { food_id:3, name: "닭가슴살", calories: 120, carbs: 0, protein: 23, fat: 2 }, + { food_id:4, name: "사과", calories: 80, carbs: 21, protein: 0.5, fat: 0.3 }, + { food_id:5, name: "고구마", calories: 86, carbs: 20, protein: 1.6, fat: 0.1 }, + { food_id:6, name: "바나나", calories: 89, carbs: 23, protein: 1.1, fat: 0.3 }, + { food_id:7, name: "오렌지", calories: 62, carbs: 15, protein: 1.2, fat: 0.2 }, + { food_id:8, name: "소고기", calories: 250, carbs: 0, protein: 26, fat: 17 }, + { food_id:9, name: "돼지고기", calories: 242, carbs: 0, protein: 27, fat: 14 }, + { food_id:10, name: "고등어", calories: 189, carbs: 0, protein: 20, fat: 12 }, + { food_id:11, name: "연어", calories: 206, carbs: 0, protein: 22, fat: 13 }, + { food_id:12, name: "두부", calories: 76, carbs: 1.9, protein: 8, fat: 4.8 }, + { food_id:13, name: "김치", calories: 33, carbs: 6.1, protein: 1.1, fat: 0.2 }, + { food_id:14, name: "우유", calories: 42, carbs: 5, protein: 3.4, fat: 1 }, + { food_id:15, name: "요거트", calories: 59, carbs: 3.6, protein: 10, fat: 0.4 }, + { food_id:16, name: "치킨", calories: 239, carbs: 0, protein: 27, fat: 14 }, + { food_id:17, name: "고추", calories: 40, carbs: 9, protein: 2, fat: 0.4 }, + { food_id:18, name: "양파", calories: 40, carbs: 9, protein: 1.1, fat: 0.1 }, + { food_id:19, name: "당근", calories: 41, carbs: 10, protein: 0.9, fat: 0.2 }, + { food_id:20, name: "감자", calories: 77, carbs: 17, protein: 2, fat: 0.1 }, + { food_id:21, name: "브로콜리", calories: 34, carbs: 7, protein: 2.8, fat: 0.4 }, + { food_id:22, name: "호박", calories: 26, carbs: 6.5, protein: 1, fat: 0.1 }, + { food_id:23, name: "치즈", calories: 402, carbs: 1.3, protein: 25, fat: 33 }, + { food_id:24, name: "햄", calories: 145, carbs: 1.3, protein: 20, fat: 7 }, + { food_id:25, name: "소시지", calories: 301, carbs: 2, protein: 11, fat: 28 }, + { food_id:26, name: "초콜릿", calories: 546, carbs: 61, protein: 4.9, fat: 31 }, + { food_id:27, name: "아몬드", calories: 576, carbs: 21, protein: 21, fat: 49 }, + { food_id:28, name: "땅콩", calories: 567, carbs: 16, protein: 25, fat: 49 }, + { food_id:29, name: "식빵", calories: 265, carbs: 49, protein: 9, fat: 3.2 }, + { food_id:30, name: "파스타", calories: 131, carbs: 25, protein: 5, fat: 1.1 }, ]; const initDB = async () => { @@ -78,11 +78,12 @@ const initDB = async () => { } // Food100 컬렉션 초기화 - await Food100.deleteMany({}); + await Food100.deleteMany(); console.log('Food100 컬렉션이 초기화되었습니다.'); // Food100 데이터 추가 const foodData = foodOptions.map(item => ({ + food_id: item.food_id, food_name: item.name, energy_kcal: item.calories, carbohydrate: item.carbs, diff --git a/back/src/models/food100.js b/back/src/models/food100.js index c52150453dc4106fc2789bbac6f3cf997e7875d6..42498a66fbd95f3cad1cc9af0aeaadabd6864c8a 100644 --- a/back/src/models/food100.js +++ b/back/src/models/food100.js @@ -43,4 +43,4 @@ const food100Schema = new mongoose.Schema({ const Food100 = mongoose.model('Food100', food100Schema); -module.exports = { Food100 }; \ No newline at end of file +module.exports = Food100; \ No newline at end of file diff --git a/back/src/models/habittracker.js b/back/src/models/habittracker.js index ddeb3fb9eda2acd1637f4ae7690bc88ac59c0a33..164c613edcbc6133ae3e9387e0256465638d3ec7 100644 --- a/back/src/models/habittracker.js +++ b/back/src/models/habittracker.js @@ -35,4 +35,4 @@ const habitTrackerSchema = new mongoose.Schema( const HabitTracker = mongoose.model('HabitTracker', habitTrackerSchema); -module.exports = { HabitTracker }; \ No newline at end of file +module.exports = HabitTracker; \ No newline at end of file diff --git a/back/src/models/records.js b/back/src/models/records.js index 47013ec420e86143181a27c0fadaf39861060c71..af3ef5c5d8b287ed17c1c67b819ea555d24ab972 100644 --- a/back/src/models/records.js +++ b/back/src/models/records.js @@ -27,6 +27,6 @@ const recordSchema = new mongoose.Schema({ }, }); -const Record = mongoose.model('Record', recordSchema); +const Records = mongoose.model('Records', recordSchema); -module.exports = { Record }; +module.exports = Records; diff --git a/front/src/api/UserAPI.js b/front/src/api/UserAPI.js index b82ca607c0c8f10a9519728f70edf478ce06b238..9f22e52650f60fa7c0f6913a2298e8d236b37933 100644 --- a/front/src/api/UserAPI.js +++ b/front/src/api/UserAPI.js @@ -162,4 +162,62 @@ async function userWithdraw(password) { } } -export {userLogin, userSignUp, getUserData, changeUserData, userLogout, userWithdraw}; \ No newline at end of file +async function refreshAccessToken() { + try { + const response = await fetch('/api/auth/refresh', { + method: 'POST', + credentials: 'include', // refreshToken 쿠키 전송을 위해 필요 + headers: { + 'Content-Type': 'application/json' + } + }); + + if (!response.ok) { + throw new Error('토큰 갱신 실패'); + } + + const data = await response.json(); + localStorage.setItem('accessToken', data.accessToken); + return data.accessToken; + } catch (error) { + console.error('토큰 갱신 중 에러:', error); + throw error; + } +} + +async function getProfile() { + try { + let response = await fetch('/api/user/profile', { + method: 'GET', + headers: { + 'Authorization': `Bearer ${localStorage.getItem('accessToken')}`, + 'Content-Type': 'application/json' + } + }); + + // 401 에러 발생 시 토큰 갱신 시도 + if (response.status === 401) { + const newAccessToken = await refreshAccessToken(); + + // 새로운 토큰으로 다시 요청 + response = await fetch('/api/user/profile', { + method: 'GET', + headers: { + 'Authorization': `Bearer ${newAccessToken}`, + 'Content-Type': 'application/json' + } + }); + } + + if (!response.ok) { + throw new Error('프로필 조회 실패'); + } + + return await response.json(); + } catch (error) { + console.error('프로필 조회 중 에러:', error); + throw error; + } +} + +export {userLogin, userSignUp, getUserData, changeUserData, userLogout, userWithdraw, getProfile, refreshAccessToken}; \ No newline at end of file diff --git a/front/src/api/routineAPI.js b/front/src/api/routineAPI.js index 61726101177e72030cd1597cfcabecc78e4e997b..fe433cc9d0455416d174e9fd185da4a7bb30ce2a 100644 --- a/front/src/api/routineAPI.js +++ b/front/src/api/routineAPI.js @@ -15,6 +15,7 @@ async function addExerciseRecord(record) { return await fetchWithOptions('/routine/records', { method: 'POST', headers: { + "Authorization": `Bearer ${localStorage.getItem('accessToken')}`, 'Content-Type': 'application/json', }, body: JSON.stringify(record), @@ -25,6 +26,7 @@ async function getUserRoutines() { return await fetchWithOptions('/routine', { method: 'GET', headers: { + "Authorization": `Bearer ${localStorage.getItem('accessToken')}`, 'Content-Type': 'application/json', }, }); @@ -34,6 +36,7 @@ async function getRoutineVideos(routineName) { return await fetchWithOptions(`/routine/videos?routine_name=${routineName}`, { method: 'GET', headers: { + "Authorization": `Bearer ${localStorage.getItem('accessToken')}`, 'Content-Type': 'application/json', }, }); @@ -43,6 +46,7 @@ async function deleteRoutine(routineName) { return await fetchWithOptions('/routine', { method: 'DELETE', headers: { + "Authorization": `Bearer ${localStorage.getItem('accessToken')}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ routine_name: routineName }),