feat: full health & fitness app with workout/meal planning
Some checks failed
CI/CD - Build, Push & Deploy / Build & Push Docker Image (push) Has been cancelled
CI/CD - Build, Push & Deploy / Update GitOps Manifest (push) Has been cancelled

- Login/register with JWT auth
- User profile (age, weight, height, goal, country)
- AI trainer agent: 7-day workout programs by goal
- AI dietitian agent: calorie-based meal plans with Turkish cuisine
- Shopping list generator from meal plans
- Modern Turkish UI (SPA)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 10:02:46 +00:00
parent d0d40c2195
commit c17f143a40
13 changed files with 3318 additions and 18 deletions

754
src/services/dietitian.js Normal file
View File

@@ -0,0 +1,754 @@
"use strict";
// Mifflin-St Jeor BMR
function calculateBMR(weight, height, age, gender) {
if (gender === "male") {
return 10 * weight + 6.25 * height - 5 * age + 5;
}
return 10 * weight + 6.25 * height - 5 * age - 161;
}
const ACTIVITY_MULTIPLIERS = {
sedentary: 1.2,
light: 1.375,
moderate: 1.55,
active: 1.725,
very_active: 1.9,
};
function calculateTDEE(bmr, activityLevel) {
return bmr * (ACTIVITY_MULTIPLIERS[activityLevel] || 1.55);
}
function adjustCalories(tdee, goal) {
switch (goal) {
case "lose_weight": return tdee - 500;
case "gain_weight": return tdee + 500;
case "build_muscle": return tdee + 300;
default: return tdee;
}
}
function calculateMacros(calories, goal) {
let proteinPct, carbsPct, fatPct;
switch (goal) {
case "lose_weight":
proteinPct = 0.35; carbsPct = 0.35; fatPct = 0.30; break;
case "build_muscle":
proteinPct = 0.35; carbsPct = 0.40; fatPct = 0.25; break;
case "gain_weight":
proteinPct = 0.30; carbsPct = 0.45; fatPct = 0.25; break;
default:
proteinPct = 0.30; carbsPct = 0.40; fatPct = 0.30;
}
return {
protein_g: Math.round((calories * proteinPct) / 4),
carbs_g: Math.round((calories * carbsPct) / 4),
fat_g: Math.round((calories * fatPct) / 9),
};
}
// ==================== TURKISH MEALS ====================
const TURKISH_BREAKFASTS = [
{
name: "Menemen & Simit Kahvaltısı",
ingredients: [
{ item: "Yumurta", amount: "2 adet", grams: 120 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Biber (sivri)", amount: "2 adet", grams: 60 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Simit", amount: "1/2 adet", grams: 60 },
{ item: "Beyaz peynir", amount: "40g", grams: 40 },
],
calories: 420, protein: 22, carbs: 35, fat: 22,
},
{
name: "Peynirli Kahvaltı Tabağı",
ingredients: [
{ item: "Beyaz peynir", amount: "60g", grams: 60 },
{ item: "Kaşar peyniri", amount: "30g", grams: 30 },
{ item: "Zeytin (siyah)", amount: "8 adet", grams: 30 },
{ item: "Domates", amount: "1 adet", grams: 120 },
{ item: "Salatalık", amount: "1 adet", grams: 100 },
{ item: "Bal", amount: "1 tatlı kaşığı", grams: 10 },
{ item: "Tam buğday ekmek", amount: "2 dilim", grams: 60 },
{ item: "Tereyağı", amount: "10g", grams: 10 },
],
calories: 450, protein: 20, carbs: 38, fat: 24,
},
{
name: "Sucuklu Yumurta",
ingredients: [
{ item: "Yumurta", amount: "2 adet", grams: 120 },
{ item: "Sucuk", amount: "40g", grams: 40 },
{ item: "Tam buğday ekmek", amount: "1 dilim", grams: 30 },
{ item: "Domates", amount: "1/2 adet", grams: 60 },
{ item: "Yeşil biber", amount: "1 adet", grams: 30 },
],
calories: 400, protein: 24, carbs: 18, fat: 26,
},
{
name: "Kaymak & Bal ile Simit",
ingredients: [
{ item: "Simit", amount: "1 adet", grams: 120 },
{ item: "Kaymak", amount: "30g", grams: 30 },
{ item: "Bal", amount: "1 yemek kaşığı", grams: 20 },
{ item: "Çay", amount: "1 bardak", grams: 200 },
{ item: "Beyaz peynir", amount: "30g", grams: 30 },
],
calories: 460, protein: 14, carbs: 55, fat: 20,
},
{
name: "Sahanda Yumurta & Peynir",
ingredients: [
{ item: "Yumurta", amount: "2 adet", grams: 120 },
{ item: "Tereyağı", amount: "10g", grams: 10 },
{ item: "Beyaz peynir", amount: "40g", grams: 40 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Zeytin", amount: "6 adet", grams: 24 },
{ item: "Tam buğday ekmek", amount: "1 dilim", grams: 30 },
],
calories: 410, protein: 23, carbs: 20, fat: 27,
},
{
name: "Gözleme (Peynirli & Ispanaklı)",
ingredients: [
{ item: "Un (hamur)", amount: "80g", grams: 80 },
{ item: "Ispanak", amount: "60g", grams: 60 },
{ item: "Beyaz peynir", amount: "50g", grams: 50 },
{ item: "Tereyağı", amount: "10g", grams: 10 },
{ item: "Ayran", amount: "1 bardak", grams: 200 },
],
calories: 430, protein: 20, carbs: 42, fat: 20,
},
{
name: ılbır (Yumurtalı Yoğurt)",
ingredients: [
{ item: "Yumurta", amount: "2 adet", grams: 120 },
{ item: "Yoğurt", amount: "150g", grams: 150 },
{ item: "Tereyağı", amount: "10g", grams: 10 },
{ item: "Pul biber", amount: "1 çay kaşığı", grams: 2 },
{ item: "Tam buğday ekmek", amount: "1 dilim", grams: 30 },
],
calories: 380, protein: 24, carbs: 22, fat: 22,
},
];
const TURKISH_LUNCHES = [
{
name: "Mercimek Çorbası & Bulgur Pilavı",
ingredients: [
{ item: "Kırmızı mercimek", amount: "80g", grams: 80 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Havuç", amount: "1/2 adet", grams: 40 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Limon", amount: "1/2 adet", grams: 30 },
{ item: "Bulgur pilavı", amount: "150g (pişmiş)", grams: 150 },
{ item: "Tereyağı", amount: "5g", grams: 5 },
],
calories: 480, protein: 22, carbs: 68, fat: 14,
},
{
name: "Izgara Köfte & Salata",
ingredients: [
{ item: "Dana kıyma (az yağlı)", amount: "150g", grams: 150 },
{ item: "Soğan (rendelenmiş)", amount: "30g", grams: 30 },
{ item: "Maydanoz", amount: "10g", grams: 10 },
{ item: "Çoban salatası", amount: "150g", grams: 150 },
{ item: "Tam buğday ekmek", amount: "1 dilim", grams: 30 },
{ item: "Sumak", amount: "1 çay kaşığı", grams: 2 },
],
calories: 450, protein: 38, carbs: 22, fat: 24,
},
{
name: "Tavuk Şiş & Bulgur",
ingredients: [
{ item: "Tavuk göğsü", amount: "180g", grams: 180 },
{ item: "Biber", amount: "2 adet", grams: 60 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Bulgur pilavı", amount: "150g (pişmiş)", grams: 150 },
{ item: "Zeytinyağı", amount: "1 tatlı kaşığı", grams: 7 },
{ item: "Soğan", amount: "1/4 adet", grams: 20 },
],
calories: 480, protein: 45, carbs: 42, fat: 14,
},
{
name: "Kuru Fasulye & Pilav",
ingredients: [
{ item: "Kuru fasulye (pişmiş)", amount: "200g", grams: 200 },
{ item: "Domates salçası", amount: "1 yemek kaşığı", grams: 15 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Tereyağlı pirinç pilavı", amount: "150g (pişmiş)", grams: 150 },
{ item: "Turşu", amount: "50g", grams: 50 },
],
calories: 520, protein: 24, carbs: 78, fat: 12,
},
{
name: "Patlıcan Musakka",
ingredients: [
{ item: "Patlıcan", amount: "200g", grams: 200 },
{ item: "Dana kıyma", amount: "100g", grams: 100 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Biber", amount: "1 adet", grams: 30 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Pilav", amount: "100g (pişmiş)", grams: 100 },
],
calories: 470, protein: 28, carbs: 35, fat: 24,
},
{
name: "Karnıyarık",
ingredients: [
{ item: "Patlıcan", amount: "250g", grams: 250 },
{ item: "Dana kıyma", amount: "100g", grams: 100 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Sarımsak", amount: "2 diş", grams: 6 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Bulgur pilavı", amount: "100g (pişmiş)", grams: 100 },
],
calories: 490, protein: 28, carbs: 38, fat: 25,
},
{
name: "İmam Bayıldı & Pilav",
ingredients: [
{ item: "Patlıcan", amount: "250g", grams: 250 },
{ item: "Domates", amount: "2 adet", grams: 200 },
{ item: "Soğan", amount: "1 adet", grams: 80 },
{ item: "Sarımsak", amount: "3 diş", grams: 9 },
{ item: "Zeytinyağı", amount: "2 yemek kaşığı", grams: 28 },
{ item: "Pilav", amount: "120g (pişmiş)", grams: 120 },
],
calories: 440, protein: 10, carbs: 48, fat: 24,
},
{
name: "Lahmacun & Ayran",
ingredients: [
{ item: "Lahmacun", amount: "2 adet", grams: 200 },
{ item: "Maydanoz", amount: "15g", grams: 15 },
{ item: "Limon", amount: "1/2 adet", grams: 30 },
{ item: "Domates", amount: "1/2 adet", grams: 60 },
{ item: "Ayran", amount: "1 bardak", grams: 200 },
],
calories: 460, protein: 24, carbs: 52, fat: 16,
},
{
name: "Etli Pide",
ingredients: [
{ item: "Pide hamuru", amount: "150g", grams: 150 },
{ item: "Dana kıyma", amount: "100g", grams: 100 },
{ item: "Domates", amount: "1/2 adet", grams: 60 },
{ item: "Biber", amount: "1 adet", grams: 30 },
{ item: "Soğan", amount: "1/4 adet", grams: 20 },
{ item: "Ayran", amount: "1 bardak", grams: 200 },
],
calories: 530, protein: 30, carbs: 52, fat: 22,
},
{
name: "Ezogelin Çorbası & Tavuk Sote",
ingredients: [
{ item: "Kırmızı mercimek", amount: "50g", grams: 50 },
{ item: "Bulgur", amount: "20g", grams: 20 },
{ item: "Domates salçası", amount: "1 yemek kaşığı", grams: 15 },
{ item: "Tavuk göğsü", amount: "150g", grams: 150 },
{ item: "Biber", amount: "2 adet", grams: 60 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
],
calories: 460, protein: 40, carbs: 36, fat: 16,
},
{
name: "Yayla Çorbası & Mantı",
ingredients: [
{ item: "Yoğurt", amount: "150g", grams: 150 },
{ item: "Pirinç", amount: "30g", grams: 30 },
{ item: "Yumurta", amount: "1 adet", grams: 60 },
{ item: "Nane (kuru)", amount: "1 çay kaşığı", grams: 1 },
{ item: "Mantı (dondurulmuş veya ev yapımı)", amount: "150g", grams: 150 },
{ item: "Tereyağı", amount: "10g", grams: 10 },
],
calories: 500, protein: 26, carbs: 54, fat: 20,
},
{
name: "Taze Fasulye Yemeği & Pilav",
ingredients: [
{ item: "Taze fasulye", amount: "250g", grams: 250 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Pilav", amount: "150g (pişmiş)", grams: 150 },
],
calories: 420, protein: 12, carbs: 58, fat: 16,
},
{
name: "Bamya Yemeği & Bulgur",
ingredients: [
{ item: "Bamya", amount: "200g", grams: 200 },
{ item: "Domates", amount: "1 adet", grams: 100 },
{ item: "Et (kuşbaşı)", amount: "100g", grams: 100 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Limon suyu", amount: "1 yemek kaşığı", grams: 15 },
{ item: "Bulgur pilavı", amount: "120g (pişmiş)", grams: 120 },
],
calories: 440, protein: 30, carbs: 42, fat: 16,
},
{
name: "Adana Kebap & Şalgam",
ingredients: [
{ item: "Adana kebap", amount: "200g", grams: 200 },
{ item: "Lavaş ekmek", amount: "1 adet", grams: 60 },
{ item: "Közlenmiş domates", amount: "1 adet", grams: 100 },
{ item: "Közlenmiş biber", amount: "2 adet", grams: 60 },
{ item: "Soğan", amount: "1/4 adet", grams: 20 },
{ item: "Şalgam suyu", amount: "1 bardak", grams: 200 },
],
calories: 520, protein: 36, carbs: 30, fat: 28,
},
];
const TURKISH_DINNERS = [
{
name: "Zeytinyağlı Yaprak Sarma & Cacık",
ingredients: [
{ item: "Asma yaprağı sarması", amount: "8 adet", grams: 160 },
{ item: "Yoğurt (cacık)", amount: "150g", grams: 150 },
{ item: "Salatalık", amount: "1/2 adet", grams: 50 },
{ item: "Sarımsak", amount: "1 diş", grams: 3 },
{ item: "Nane", amount: "1 çay kaşığı", grams: 1 },
{ item: "Tam buğday ekmek", amount: "1 dilim", grams: 30 },
],
calories: 380, protein: 14, carbs: 48, fat: 14,
},
{
name: "Tavuk Izgara & Kısır",
ingredients: [
{ item: "Tavuk göğsü (ızgara)", amount: "180g", grams: 180 },
{ item: "Kısır (bulgur salatası)", amount: "150g", grams: 150 },
{ item: "Nar ekşisi", amount: "1 tatlı kaşığı", grams: 5 },
{ item: "Maydanoz", amount: "15g", grams: 15 },
{ item: "Domates", amount: "1/2 adet", grams: 60 },
],
calories: 440, protein: 44, carbs: 38, fat: 10,
},
{
name: "Kabak Mücver & Yoğurt",
ingredients: [
{ item: "Kabak (rendelenmiş)", amount: "200g", grams: 200 },
{ item: "Un", amount: "30g", grams: 30 },
{ item: "Yumurta", amount: "1 adet", grams: 60 },
{ item: "Dereotu", amount: "10g", grams: 10 },
{ item: "Beyaz peynir", amount: "30g", grams: 30 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Yoğurt", amount: "100g", grams: 100 },
],
calories: 360, protein: 18, carbs: 28, fat: 20,
},
{
name: "Su Böreği",
ingredients: [
{ item: "Yufka", amount: "3 yaprak", grams: 120 },
{ item: "Beyaz peynir", amount: "100g", grams: 100 },
{ item: "Maydanoz", amount: "15g", grams: 15 },
{ item: "Yumurta", amount: "1 adet", grams: 60 },
{ item: "Süt", amount: "50ml", grams: 50 },
{ item: "Tereyağı", amount: "15g", grams: 15 },
],
calories: 440, protein: 22, carbs: 38, fat: 22,
},
{
name: "Mercimek Köftesi & Salata",
ingredients: [
{ item: "Kırmızı mercimek", amount: "100g", grams: 100 },
{ item: "İnce bulgur", amount: "80g", grams: 80 },
{ item: "Soğan", amount: "1 adet", grams: 80 },
{ item: "Domates salçası", amount: "1 yemek kaşığı", grams: 15 },
{ item: "Marul", amount: "4 yaprak", grams: 40 },
{ item: "Limon", amount: "1/2 adet", grams: 30 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
],
calories: 400, protein: 20, carbs: 58, fat: 10,
},
{
name: "Sigara Böreği & Çorba",
ingredients: [
{ item: "Yufka (sigara böreği)", amount: "4 adet", grams: 120 },
{ item: "Beyaz peynir", amount: "60g", grams: 60 },
{ item: "Maydanoz", amount: "10g", grams: 10 },
{ item: "Zeytinyağı (kızartma)", amount: "15g", grams: 15 },
{ item: "Domates çorbası", amount: "250ml", grams: 250 },
],
calories: 420, protein: 18, carbs: 36, fat: 22,
},
{
name: "Çoban Salatası & Humus & Ekmek",
ingredients: [
{ item: "Domates", amount: "2 adet", grams: 200 },
{ item: "Salatalık", amount: "1 adet", grams: 100 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Biber", amount: "1 adet", grams: 30 },
{ item: "Humus", amount: "100g", grams: 100 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Tam buğday ekmek", amount: "2 dilim", grams: 60 },
],
calories: 400, protein: 16, carbs: 42, fat: 20,
},
{
name: "Havuç Tarator",
ingredients: [
{ item: "Havuç", amount: "300g", grams: 300 },
{ item: "Yoğurt", amount: "200g", grams: 200 },
{ item: "Sarımsak", amount: "2 diş", grams: 6 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Ceviz", amount: "20g", grams: 20 },
{ item: "Tam buğday ekmek", amount: "2 dilim", grams: 60 },
],
calories: 380, protein: 16, carbs: 44, fat: 16,
},
{
name: "İçli Köfte",
ingredients: [
{ item: "İnce bulgur (dış)", amount: "100g", grams: 100 },
{ item: "Dana kıyma (iç)", amount: "80g", grams: 80 },
{ item: "Soğan", amount: "1/2 adet", grams: 40 },
{ item: "Ceviz", amount: "15g", grams: 15 },
{ item: "Maydanoz", amount: "10g", grams: 10 },
{ item: "Yoğurt", amount: "100g", grams: 100 },
],
calories: 470, protein: 28, carbs: 52, fat: 16,
},
{
name: "Balık Izgara & Roka Salatası",
ingredients: [
{ item: "Levrek veya çipura", amount: "200g", grams: 200 },
{ item: "Roka", amount: "50g", grams: 50 },
{ item: "Limon", amount: "1/2 adet", grams: 30 },
{ item: "Zeytinyağı", amount: "1 yemek kaşığı", grams: 14 },
{ item: "Domates", amount: "1/2 adet", grams: 60 },
{ item: "Tam buğday ekmek", amount: "1 dilim", grams: 30 },
],
calories: 380, protein: 42, carbs: 16, fat: 16,
},
];
const TURKISH_SNACKS = [
{ name: "Ayran & Ceviz", ingredients: [{ item: "Ayran", amount: "1 bardak", grams: 200 }, { item: "Ceviz", amount: "30g", grams: 30 }], calories: 240, protein: 10, carbs: 10, fat: 18 },
{ name: "Meyve & Yoğurt", ingredients: [{ item: "Mevsim meyvesi", amount: "1 porsiyon", grams: 150 }, { item: "Yoğurt", amount: "100g", grams: 100 }], calories: 170, protein: 6, carbs: 28, fat: 4 },
{ name: "Kuru Meyve & Fındık", ingredients: [{ item: "Kuru kayısı", amount: "4 adet", grams: 30 }, { item: "Fındık", amount: "20g", grams: 20 }, { item: "Badem", amount: "10g", grams: 10 }], calories: 200, protein: 5, carbs: 22, fat: 12 },
{ name: "Peynirli Kraker", ingredients: [{ item: "Tam buğday kraker", amount: "4 adet", grams: 30 }, { item: "Beyaz peynir", amount: "30g", grams: 30 }], calories: 170, protein: 8, carbs: 18, fat: 8 },
{ name: "Muzlu Süt", ingredients: [{ item: "Muz", amount: "1 adet", grams: 120 }, { item: "Süt (yarım yağlı)", amount: "200ml", grams: 200 }], calories: 210, protein: 8, carbs: 34, fat: 4 },
{ name: "Havuç & Humus", ingredients: [{ item: "Havuç çubukları", amount: "100g", grams: 100 }, { item: "Humus", amount: "50g", grams: 50 }], calories: 160, protein: 6, carbs: 18, fat: 8 },
{ name: "Yumurta (Haşlanmış)", ingredients: [{ item: "Yumurta", amount: "2 adet", grams: 120 }, { item: "Tuz & karabiber", amount: "az", grams: 1 }], calories: 155, protein: 13, carbs: 1, fat: 11 },
{ name: "Elma & Fıstık Ezmesi", ingredients: [{ item: "Elma", amount: "1 adet", grams: 180 }, { item: "Fıstık ezmesi", amount: "1 yemek kaşığı", grams: 16 }], calories: 190, protein: 5, carbs: 28, fat: 8 },
{ name: "Lor Peyniri & Domates", ingredients: [{ item: "Lor peyniri", amount: "80g", grams: 80 }, { item: "Domates", amount: "1/2 adet", grams: 60 }, { item: "Zeytinyağı", amount: "az", grams: 5 }], calories: 140, protein: 12, carbs: 6, fat: 8 },
{ name: "Türk Kahvesi & Hurma", ingredients: [{ item: "Türk kahvesi", amount: "1 fincan", grams: 60 }, { item: "Hurma", amount: "3 adet", grams: 30 }], calories: 100, protein: 1, carbs: 22, fat: 1 },
];
// ==================== USA / DEFAULT MEALS ====================
const USA_BREAKFASTS = [
{
name: "Oatmeal with Berries",
ingredients: [
{ item: "Rolled oats", amount: "80g", grams: 80 },
{ item: "Milk (low-fat)", amount: "200ml", grams: 200 },
{ item: "Mixed berries", amount: "100g", grams: 100 },
{ item: "Honey", amount: "1 tsp", grams: 7 },
{ item: "Almonds (sliced)", amount: "15g", grams: 15 },
],
calories: 400, protein: 16, carbs: 58, fat: 12,
},
{
name: "Scrambled Eggs & Toast",
ingredients: [
{ item: "Eggs", amount: "3", grams: 180 },
{ item: "Whole wheat toast", amount: "2 slices", grams: 60 },
{ item: "Butter", amount: "10g", grams: 10 },
{ item: "Avocado", amount: "1/4", grams: 50 },
{ item: "Cherry tomatoes", amount: "5", grams: 75 },
],
calories: 450, protein: 26, carbs: 30, fat: 26,
},
{
name: "Greek Yogurt Parfait",
ingredients: [
{ item: "Greek yogurt", amount: "200g", grams: 200 },
{ item: "Granola", amount: "40g", grams: 40 },
{ item: "Banana", amount: "1/2", grams: 60 },
{ item: "Honey", amount: "1 tbsp", grams: 20 },
{ item: "Chia seeds", amount: "10g", grams: 10 },
],
calories: 420, protein: 24, carbs: 54, fat: 12,
},
{
name: "Protein Smoothie Bowl",
ingredients: [
{ item: "Banana (frozen)", amount: "1", grams: 120 },
{ item: "Protein powder", amount: "1 scoop (30g)", grams: 30 },
{ item: "Almond milk", amount: "150ml", grams: 150 },
{ item: "Peanut butter", amount: "1 tbsp", grams: 16 },
{ item: "Granola topping", amount: "20g", grams: 20 },
],
calories: 430, protein: 30, carbs: 48, fat: 14,
},
{
name: "Avocado Toast with Egg",
ingredients: [
{ item: "Whole wheat bread", amount: "2 slices", grams: 60 },
{ item: "Avocado", amount: "1/2", grams: 100 },
{ item: "Egg (poached)", amount: "2", grams: 120 },
{ item: "Red pepper flakes", amount: "pinch", grams: 1 },
{ item: "Lemon juice", amount: "1 tsp", grams: 5 },
],
calories: 440, protein: 20, carbs: 32, fat: 26,
},
];
const USA_LUNCHES = [
{
name: "Grilled Chicken Salad",
ingredients: [
{ item: "Chicken breast (grilled)", amount: "180g", grams: 180 },
{ item: "Mixed greens", amount: "100g", grams: 100 },
{ item: "Cherry tomatoes", amount: "80g", grams: 80 },
{ item: "Cucumber", amount: "80g", grams: 80 },
{ item: "Olive oil dressing", amount: "1 tbsp", grams: 14 },
{ item: "Feta cheese", amount: "30g", grams: 30 },
],
calories: 420, protein: 44, carbs: 12, fat: 22,
},
{
name: "Turkey Wrap",
ingredients: [
{ item: "Whole wheat tortilla", amount: "1 large", grams: 60 },
{ item: "Turkey breast slices", amount: "120g", grams: 120 },
{ item: "Lettuce", amount: "30g", grams: 30 },
{ item: "Tomato", amount: "1/2", grams: 60 },
{ item: "Hummus", amount: "30g", grams: 30 },
{ item: "Swiss cheese", amount: "20g", grams: 20 },
],
calories: 400, protein: 36, carbs: 30, fat: 16,
},
{
name: "Salmon & Sweet Potato",
ingredients: [
{ item: "Salmon fillet", amount: "180g", grams: 180 },
{ item: "Sweet potato (baked)", amount: "200g", grams: 200 },
{ item: "Broccoli (steamed)", amount: "100g", grams: 100 },
{ item: "Olive oil", amount: "1 tsp", grams: 5 },
{ item: "Lemon", amount: "1/2", grams: 30 },
],
calories: 500, protein: 40, carbs: 42, fat: 18,
},
{
name: "Chicken & Brown Rice Bowl",
ingredients: [
{ item: "Chicken breast", amount: "180g", grams: 180 },
{ item: "Brown rice (cooked)", amount: "150g", grams: 150 },
{ item: "Mixed vegetables", amount: "100g", grams: 100 },
{ item: "Soy sauce", amount: "1 tbsp", grams: 15 },
{ item: "Sesame oil", amount: "1 tsp", grams: 5 },
],
calories: 480, protein: 42, carbs: 48, fat: 12,
},
{
name: "Tuna Sandwich",
ingredients: [
{ item: "Whole wheat bread", amount: "2 slices", grams: 60 },
{ item: "Canned tuna", amount: "120g", grams: 120 },
{ item: "Greek yogurt (instead of mayo)", amount: "30g", grams: 30 },
{ item: "Celery", amount: "30g", grams: 30 },
{ item: "Lettuce", amount: "20g", grams: 20 },
{ item: "Apple", amount: "1 small", grams: 120 },
],
calories: 420, protein: 38, carbs: 42, fat: 10,
},
];
const USA_DINNERS = [
{
name: "Grilled Steak & Vegetables",
ingredients: [
{ item: "Lean steak", amount: "180g", grams: 180 },
{ item: "Asparagus", amount: "100g", grams: 100 },
{ item: "Baked potato", amount: "150g", grams: 150 },
{ item: "Olive oil", amount: "1 tbsp", grams: 14 },
{ item: "Garlic", amount: "2 cloves", grams: 6 },
],
calories: 480, protein: 42, carbs: 30, fat: 22,
},
{
name: "Baked Chicken Thighs & Quinoa",
ingredients: [
{ item: "Chicken thighs (skinless)", amount: "200g", grams: 200 },
{ item: "Quinoa (cooked)", amount: "150g", grams: 150 },
{ item: "Roasted vegetables", amount: "150g", grams: 150 },
{ item: "Olive oil", amount: "1 tbsp", grams: 14 },
{ item: "Herbs", amount: "mixed", grams: 5 },
],
calories: 520, protein: 44, carbs: 38, fat: 20,
},
{
name: "Shrimp Stir-Fry",
ingredients: [
{ item: "Shrimp", amount: "200g", grams: 200 },
{ item: "Brown rice (cooked)", amount: "150g", grams: 150 },
{ item: "Bell peppers", amount: "100g", grams: 100 },
{ item: "Broccoli", amount: "80g", grams: 80 },
{ item: "Soy sauce", amount: "1 tbsp", grams: 15 },
{ item: "Sesame oil", amount: "1 tsp", grams: 5 },
],
calories: 440, protein: 38, carbs: 46, fat: 10,
},
{
name: "Turkey Meatballs & Pasta",
ingredients: [
{ item: "Ground turkey", amount: "150g", grams: 150 },
{ item: "Whole wheat pasta (cooked)", amount: "150g", grams: 150 },
{ item: "Marinara sauce", amount: "100g", grams: 100 },
{ item: "Parmesan", amount: "15g", grams: 15 },
{ item: "Side salad", amount: "80g", grams: 80 },
],
calories: 500, protein: 38, carbs: 50, fat: 16,
},
{
name: "Baked Cod & Roasted Vegetables",
ingredients: [
{ item: "Cod fillet", amount: "200g", grams: 200 },
{ item: "Zucchini", amount: "100g", grams: 100 },
{ item: "Cherry tomatoes", amount: "80g", grams: 80 },
{ item: "Olive oil", amount: "1 tbsp", grams: 14 },
{ item: "Brown rice (cooked)", amount: "120g", grams: 120 },
],
calories: 420, protein: 40, carbs: 34, fat: 14,
},
];
const USA_SNACKS = [
{ name: "Protein Bar", ingredients: [{ item: "Protein bar", amount: "1", grams: 60 }], calories: 220, protein: 20, carbs: 24, fat: 8 },
{ name: "Apple & Almond Butter", ingredients: [{ item: "Apple", amount: "1 medium", grams: 180 }, { item: "Almond butter", amount: "1 tbsp", grams: 16 }], calories: 190, protein: 4, carbs: 28, fat: 8 },
{ name: "Trail Mix", ingredients: [{ item: "Mixed nuts", amount: "20g", grams: 20 }, { item: "Dried cranberries", amount: "15g", grams: 15 }, { item: "Dark chocolate chips", amount: "10g", grams: 10 }], calories: 200, protein: 5, carbs: 20, fat: 12 },
{ name: "Cottage Cheese & Berries", ingredients: [{ item: "Cottage cheese", amount: "150g", grams: 150 }, { item: "Mixed berries", amount: "80g", grams: 80 }], calories: 170, protein: 18, carbs: 16, fat: 4 },
{ name: "Veggie Sticks & Hummus", ingredients: [{ item: "Carrot sticks", amount: "60g", grams: 60 }, { item: "Celery sticks", amount: "40g", grams: 40 }, { item: "Hummus", amount: "50g", grams: 50 }], calories: 150, protein: 6, carbs: 16, fat: 8 },
{ name: "Hard Boiled Eggs", ingredients: [{ item: "Eggs", amount: "2", grams: 120 }], calories: 155, protein: 13, carbs: 1, fat: 11 },
{ name: "Greek Yogurt & Honey", ingredients: [{ item: "Greek yogurt", amount: "150g", grams: 150 }, { item: "Honey", amount: "1 tsp", grams: 7 }], calories: 160, protein: 15, carbs: 16, fat: 4 },
{ name: "Banana & Peanut Butter", ingredients: [{ item: "Banana", amount: "1", grams: 120 }, { item: "Peanut butter", amount: "1 tbsp", grams: 16 }], calories: 210, protein: 6, carbs: 30, fat: 9 },
];
function getMealsByCountry(country) {
const c = (country || "").toLowerCase().trim();
if (c === "turkey" || c === "türkiye" || c === "turkiye") {
return {
breakfasts: TURKISH_BREAKFASTS,
lunches: TURKISH_LUNCHES,
dinners: TURKISH_DINNERS,
snacks: TURKISH_SNACKS,
};
}
if (c === "usa" || c === "united states" || c === "us" || c === "america") {
return {
breakfasts: USA_BREAKFASTS,
lunches: USA_LUNCHES,
dinners: USA_DINNERS,
snacks: USA_SNACKS,
};
}
// Default: Mediterranean mix (use USA meals as base)
return {
breakfasts: USA_BREAKFASTS,
lunches: USA_LUNCHES,
dinners: USA_DINNERS,
snacks: USA_SNACKS,
};
}
function scaleMeal(meal, targetCalories, mealCalorieShare) {
const target = targetCalories * mealCalorieShare;
const ratio = target / meal.calories;
return {
...meal,
calories: Math.round(meal.calories * ratio),
protein: Math.round(meal.protein * ratio),
carbs: Math.round(meal.carbs * ratio),
fat: Math.round(meal.fat * ratio),
ingredients: meal.ingredients.map((ing) => ({
...ing,
grams: Math.round(ing.grams * ratio),
})),
};
}
function pickDifferent(arr, count, usedIndices) {
const available = arr.map((item, idx) => ({ item, idx })).filter((x) => !usedIndices.has(x.idx));
const shuffled = available.sort(() => 0.5 - Math.random());
const picked = shuffled.slice(0, count);
picked.forEach((p) => usedIndices.add(p.idx));
if (picked.length < count) {
// Reset and pick more if needed
const extra = arr.map((item, idx) => ({ item, idx })).sort(() => 0.5 - Math.random()).slice(0, count - picked.length);
return [...picked.map((p) => p.item), ...extra.map((p) => p.item)];
}
return picked.map((p) => p.item);
}
function generateMealPlan(profile) {
const { weight, height, age, gender, activity_level, goal, country } = profile;
const bmr = calculateBMR(weight, height, age, gender);
const tdee = calculateTDEE(bmr, activity_level);
const targetCalories = Math.round(adjustCalories(tdee, goal));
const macros = calculateMacros(targetCalories, goal);
const meals = getMealsByCountry(country);
// Meal calorie distribution: breakfast 25%, snack1 10%, lunch 30%, snack2 10%, dinner 25%
const shares = { breakfast: 0.25, snack1: 0.10, lunch: 0.30, snack2: 0.10, dinner: 0.25 };
const dayNames = ["Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi", "Pazar"];
const usedBreakfasts = new Set();
const usedLunches = new Set();
const usedDinners = new Set();
const usedSnacks1 = new Set();
const usedSnacks2 = new Set();
const days = dayNames.map((dayName) => {
const breakfast = scaleMeal(pickDifferent(meals.breakfasts, 1, usedBreakfasts)[0], targetCalories, shares.breakfast);
const snack1 = scaleMeal(pickDifferent(meals.snacks, 1, usedSnacks1)[0], targetCalories, shares.snack1);
const lunch = scaleMeal(pickDifferent(meals.lunches, 1, usedLunches)[0], targetCalories, shares.lunch);
const snack2 = scaleMeal(pickDifferent(meals.snacks, 1, usedSnacks2)[0], targetCalories, shares.snack2);
const dinner = scaleMeal(pickDifferent(meals.dinners, 1, usedDinners)[0], targetCalories, shares.dinner);
const dayCalories = breakfast.calories + snack1.calories + lunch.calories + snack2.calories + dinner.calories;
return {
day: dayName,
total_calories: dayCalories,
meals: [
{ type: "Kahvaltı", ...breakfast },
{ type: "Ara Öğün 1", ...snack1 },
{ type: "Öğle Yemeği", ...lunch },
{ type: "Ara Öğün 2", ...snack2 },
{ type: "Akşam Yemeği", ...dinner },
],
};
});
return {
title: "Kişisel Beslenme Programı",
bmr: Math.round(bmr),
tdee: Math.round(tdee),
target_calories: targetCalories,
macros,
goal,
country: country || "Turkey",
notes: [
`Günlük hedef kalori: ${targetCalories} kcal`,
`Protein: ${macros.protein_g}g | Karbonhidrat: ${macros.carbs_g}g | Yağ: ${macros.fat_g}g`,
"Günde en az 2.5-3 litre su için",
"Öğün saatlerinizi düzenli tutun",
"Yemekleri yavaş yiyin, iyi çiğneyin",
],
days,
};
}
module.exports = { generateMealPlan };