This commit is contained in:
Jack committed 2026-06-08 12:36:35 +08:00
commit 363c4abdc7
42 files changed
+6105

No files matched your search

+170
View File
@@ -0,0 +1,170 @@
const express = require('express');
const cors = require('cors');
const mysql = require('mysql2/promise');
const app = express();
app.use(cors());
app.use(express.json());
const dbConfig = {
host: process.env.DB_HOST || 'db',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || 'password',
database: process.env.DB_NAME || 'nutrition',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
};
let pool;
// Wait for DB to be ready
const connectDB = async () => {
let retries = 5;
while (retries) {
try {
pool = mysql.createPool(dbConfig);
await pool.query('SELECT 1');
console.log('Connected to MariaDB');
break;
} catch (err) {
console.error('Failed to connect to MariaDB, retrying...', err);
retries -= 1;
await new Promise(res => setTimeout(res, 5000));
}
}
};
connectDB();
// Get Profile
app.get('/api/profile/:userId', async (req, res) => {
try {
const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [req.params.userId]);
if (rows.length > 0) {
res.json(rows[0]);
} else {
res.status(404).json({ error: 'Profile not found' });
}
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Save Profile
app.post('/api/profile', async (req, res) => {
const p = req.body;
const userId = p.id || 'default_user';
try {
await pool.query(`
INSERT INTO users (id, height, weight, age, gender, activityLevel, goal, bmi, tdee, targetCalories, targetProtein, targetFat, targetCarbs, targetWater)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
height=?, weight=?, age=?, gender=?, activityLevel=?, goal=?, bmi=?, tdee=?, targetCalories=?, targetProtein=?, targetFat=?, targetCarbs=?, targetWater=?
`, [
userId, p.height, p.weight, p.age, p.gender, p.activityLevel, p.goal, p.bmi, p.tdee, p.targetCalories, p.targetProtein, p.targetFat, p.targetCarbs, p.targetWater,
p.height, p.weight, p.age, p.gender, p.activityLevel, p.goal, p.bmi, p.tdee, p.targetCalories, p.targetProtein, p.targetFat, p.targetCarbs, p.targetWater
]);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Get Logs (returns a mapped object { "YYYY-MM-DD": DailyLog })
app.get('/api/logs/:userId', async (req, res) => {
try {
const [logRows] = await pool.query('SELECT * FROM daily_logs WHERE user_id = ?', [req.params.userId]);
const [mealRows] = await pool.query('SELECT * FROM meals WHERE user_id = ?', [req.params.userId]);
const logs = {};
logRows.forEach(row => {
// row.date is Date object, format to YYYY-MM-DD
const dateStr = new Date(row.date).toISOString().split('T')[0];
logs[dateStr] = {
date: dateStr,
waterIntake: row.waterIntake,
weight: row.weight,
meals: []
};
});
mealRows.forEach(row => {
const dateStr = new Date(row.date).toISOString().split('T')[0];
if (!logs[dateStr]) {
logs[dateStr] = { date: dateStr, waterIntake: 0, meals: [] };
}
logs[dateStr].meals.push({
id: row.id,
name: row.name,
time: row.time,
calories: row.calories,
protein: row.protein,
fat: row.fat,
carbs: row.carbs
});
});
res.json(logs);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Add Meal
app.post('/api/logs/meal', async (req, res) => {
const { userId, date, meal } = req.body;
try {
await pool.query(`
INSERT INTO meals (id, user_id, date, name, time, calories, protein, fat, carbs)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`, [meal.id, userId, date, meal.name, meal.time, meal.calories, meal.protein, meal.fat, meal.carbs]);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Add Water
app.post('/api/logs/water', async (req, res) => {
const { userId, date, amount } = req.body;
try {
await pool.query(`
INSERT INTO daily_logs (date, user_id, waterIntake)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE waterIntake = waterIntake + ?
`, [date, userId, amount, amount]);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Log Weight
app.post('/api/logs/weight', async (req, res) => {
const { userId, date, weight } = req.body;
try {
await pool.query(`
INSERT INTO daily_logs (date, user_id, weight)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE weight = ?
`, [date, userId, weight, weight]);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Clear Data
app.delete('/api/data/:userId', async (req, res) => {
try {
await pool.query('DELETE FROM users WHERE id = ?', [req.params.userId]);
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`API server running on port ${PORT}`);
});