require('reflect-metadata'); const { Sequelize } = require('sequelize-typescript'); const path = require('path'); const fs = require('fs'); let FoodItem; let MealFood; let PlannedFood; let Meal; let User; let WaterLog; let WeightLog; let MealPlan; let UserGoal; let DailySummary; let APICache; const foodItemPath = path.join(__dirname, '../dist/models/food-item.model.js'); const mealFoodPath = path.join(__dirname, '../dist/models/meal-food.model.js'); const plannedFoodPath = path.join(__dirname, '../dist/models/planned-food.model.js'); const mealPath = path.join(__dirname, '../dist/models/meal.model.js'); const userPath = path.join(__dirname, '../dist/models/user.model.js'); const waterLogPath = path.join(__dirname, '../dist/models/water-log.model.js'); const weightLogPath = path.join(__dirname, '../dist/models/weight-log.model.js'); const mealPlanPath = path.join(__dirname, '../dist/models/meal-plan.model.js'); const userGoalPath = path.join(__dirname, '../dist/models/user-goal.model.js'); const dailySummaryPath = path.join(__dirname, '../dist/models/daily-summary.model.js'); const apiCachePath = path.join(__dirname, '../dist/models/api-cache.model.js'); if (fs.existsSync(foodItemPath)) { const mod = require(foodItemPath); FoodItem = mod.FoodItem; } else { console.error('Missing model: ' + foodItemPath); process.exit(1); } if (fs.existsSync(mealFoodPath)) { const mod = require(mealFoodPath); MealFood = mod.MealFood; } if (fs.existsSync(plannedFoodPath)) { const mod = require(plannedFoodPath); PlannedFood = mod.PlannedFood; } if (fs.existsSync(mealPath)) { const mod = require(mealPath); Meal = mod.Meal; } if (fs.existsSync(userPath)) { const mod = require(userPath); User = mod.User; } if (fs.existsSync(waterLogPath)) { const mod = require(waterLogPath); WaterLog = mod.WaterLog; } if (fs.existsSync(weightLogPath)) { const mod = require(weightLogPath); WeightLog = mod.WeightLog; } if (fs.existsSync(mealPlanPath)) { const mod = require(mealPlanPath); MealPlan = mod.MealPlan; } if (fs.existsSync(userGoalPath)) { const mod = require(userGoalPath); UserGoal = mod.UserGoal; } if (fs.existsSync(dailySummaryPath)) { const mod = require(dailySummaryPath); DailySummary = mod.DailySummary; } if (fs.existsSync(apiCachePath)) { const mod = require(apiCachePath); APICache = mod.APICache; } // Database connection const dbPath = process.env.DATABASE_URL ? process.env.DATABASE_URL.replace('sqlite://', '') : path.join(__dirname, '../data/calorie_tracker.db'); // Ensure data directory exists if using sqlite file if (!process.env.DATABASE_URL) { const dataDir = path.dirname(dbPath); if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir, { recursive: true }); } } const sequelize = new Sequelize({ dialect: 'sqlite', storage: dbPath, logging: false }); const models = [FoodItem].concat([MealFood, PlannedFood, Meal, User, WaterLog, WeightLog, MealPlan, UserGoal, DailySummary, APICache].filter(Boolean)); sequelize.addModels(models); const filipinoFoods = [ // Rice (Kanin) { name: 'White Rice', name_tagalog: 'Kanin', category: 'kanin', calories: 206, protein_g: 4.3, carbs_g: 45, fat_g: 0.4, serving_description: '1 cup cooked', serving_size_g: 158 }, { name: 'Fried Rice', name_tagalog: 'Sinangag', category: 'kanin', calories: 280, protein_g: 5, carbs_g: 42, fat_g: 10, serving_description: '1 cup', serving_size_g: 170 }, // Main Dishes (Ulam) { name: 'Chicken Adobo', name_tagalog: 'Adobong Manok', category: 'ulam', calories: 350, protein_g: 35, carbs_g: 5, fat_g: 20, serving_description: '1 serving (2 pieces)', serving_size_g: 200 }, { name: 'Pork Sinigang', name_tagalog: 'Sinigang na Baboy', category: 'sabaw', calories: 280, protein_g: 25, carbs_g: 10, fat_g: 15, serving_description: '1 bowl', serving_size_g: 350 }, { name: 'Chicken Tinola', name_tagalog: 'Tinolang Manok', category: 'sabaw', calories: 200, protein_g: 28, carbs_g: 8, fat_g: 6, serving_description: '1 bowl', serving_size_g: 350 }, { name: 'Bicol Express', name_tagalog: 'Bicol Express', category: 'ulam', calories: 400, protein_g: 20, carbs_g: 10, fat_g: 32, serving_description: '1 serving', serving_size_g: 200 }, { name: 'Pork Sisig', name_tagalog: 'Sisig', category: 'ulam', calories: 450, protein_g: 25, carbs_g: 8, fat_g: 35, serving_description: '1 serving', serving_size_g: 180 }, { name: 'Menudo', name_tagalog: 'Menudo', category: 'ulam', calories: 320, protein_g: 22, carbs_g: 12, fat_g: 20, serving_description: '1 serving', serving_size_g: 200 }, { name: 'Kare-Kare', name_tagalog: 'Kare-Kare', category: 'ulam', calories: 380, protein_g: 24, carbs_g: 18, fat_g: 25, serving_description: '1 serving', serving_size_g: 250 }, { name: 'Lechon Kawali', name_tagalog: 'Lechon Kawali', category: 'ulam', calories: 500, protein_g: 30, carbs_g: 2, fat_g: 42, serving_description: '1 serving', serving_size_g: 150 }, { name: 'Pork Nilaga', name_tagalog: 'Nilagang Baboy', category: 'sabaw', calories: 280, protein_g: 28, carbs_g: 12, fat_g: 14, serving_description: '1 bowl', serving_size_g: 350 }, { name: 'Beef Bulalo', name_tagalog: 'Bulalo', category: 'sabaw', calories: 350, protein_g: 32, carbs_g: 8, fat_g: 22, serving_description: '1 bowl', serving_size_g: 400 }, // Vegetables (Gulay) { name: 'Pinakbet', name_tagalog: 'Pinakbet', category: 'gulay', calories: 150, protein_g: 5, carbs_g: 20, fat_g: 6, serving_description: '1 cup', serving_size_g: 200 }, { name: 'Laing', name_tagalog: 'Laing', category: 'gulay', calories: 180, protein_g: 6, carbs_g: 15, fat_g: 12, serving_description: '1 cup', serving_size_g: 180 }, { name: 'Ginisang Monggo', name_tagalog: 'Ginisang Monggo', category: 'gulay', calories: 200, protein_g: 12, carbs_g: 30, fat_g: 4, serving_description: '1 cup', serving_size_g: 220 }, // Breakfast (Almusal) { name: 'Beef Tapa with Rice and Egg', name_tagalog: 'Tapsilog', category: 'almusal', calories: 650, protein_g: 45, carbs_g: 60, fat_g: 25, serving_description: '1 plate', serving_size_g: 400 }, { name: 'Longganisa with Rice and Egg', name_tagalog: 'Longsilog', category: 'almusal', calories: 700, protein_g: 38, carbs_g: 65, fat_g: 32, serving_description: '1 plate', serving_size_g: 420 }, { name: 'Tocino with Rice and Egg', name_tagalog: 'Tocilog', category: 'almusal', calories: 680, protein_g: 42, carbs_g: 62, fat_g: 28, serving_description: '1 plate', serving_size_g: 400 }, { name: 'Fried Egg', name_tagalog: 'Pritong Itlog', category: 'almusal', calories: 90, protein_g: 6, carbs_g: 1, fat_g: 7, serving_description: '1 egg', serving_size_g: 50 }, // Snacks (Meryenda) { name: 'Pandesal', name_tagalog: 'Pandesal', category: 'meryenda', calories: 120, protein_g: 3, carbs_g: 22, fat_g: 2, serving_description: '1 piece', serving_size_g: 40 }, { name: 'Turon', name_tagalog: 'Turon', category: 'meryenda', calories: 180, protein_g: 2, carbs_g: 35, fat_g: 5, serving_description: '1 piece', serving_size_g: 80 }, { name: 'Bibingka', name_tagalog: 'Bibingka', category: 'meryenda', calories: 220, protein_g: 5, carbs_g: 38, fat_g: 6, serving_description: '1 piece', serving_size_g: 100 }, { name: 'Puto', name_tagalog: 'Puto', category: 'meryenda', calories: 90, protein_g: 2, carbs_g: 18, fat_g: 1, serving_description: '1 piece', serving_size_g: 40 }, { name: 'Lumpia', name_tagalog: 'Lumpia', category: 'meryenda', calories: 100, protein_g: 4, carbs_g: 10, fat_g: 5, serving_description: '1 piece', serving_size_g: 50 }, { name: 'Banana Cue', name_tagalog: 'Banana Cue', category: 'meryenda', calories: 150, protein_g: 1, carbs_g: 32, fat_g: 4, serving_description: '1 piece', serving_size_g: 100 }, // Proteins { name: 'Grilled Tilapia', name_tagalog: 'Inihaw na Tilapia', category: 'ulam', calories: 180, protein_g: 32, carbs_g: 0, fat_g: 5, serving_description: '1 whole fish', serving_size_g: 150 }, { name: 'Grilled Chicken', name_tagalog: 'Inihaw na Manok', category: 'ulam', calories: 280, protein_g: 40, carbs_g: 0, fat_g: 13, serving_description: '1 breast', serving_size_g: 150 }, { name: 'Fried Bangus', name_tagalog: 'Pritong Bangus', category: 'ulam', calories: 220, protein_g: 28, carbs_g: 0, fat_g: 12, serving_description: '1 piece', serving_size_g: 120 }, // Vegetables (Gulay) { name: 'Pinakbet', name_tagalog: 'Pinakbet', category: 'gulay', calories: 150, protein_g: 6, carbs_g: 15, fat_g: 8, serving_description: '1 cup', serving_size_g: 200 }, { name: 'Ginisang Monggo', name_tagalog: 'Ginisang Monggo', category: 'gulay', calories: 220, protein_g: 15, carbs_g: 30, fat_g: 6, serving_description: '1 cup', serving_size_g: 240 }, { name: 'Chopsuey', name_tagalog: 'Chopsuey', category: 'gulay', calories: 180, protein_g: 12, carbs_g: 10, fat_g: 10, serving_description: '1 cup', serving_size_g: 200 }, { name: 'Laing', name_tagalog: 'Laing', category: 'gulay', calories: 250, protein_g: 5, carbs_g: 12, fat_g: 22, serving_description: '1 serving', serving_size_g: 150 }, // Breakfast { name: 'Tapsilog', name_tagalog: 'Tapsilog', category: 'almusal', calories: 550, protein_g: 35, carbs_g: 45, fat_g: 25, serving_description: '1 order (rice, egg, beef)', serving_size_g: 350 }, { name: 'Longsilog', name_tagalog: 'Longsilog', category: 'almusal', calories: 600, protein_g: 20, carbs_g: 45, fat_g: 35, serving_description: '1 order (rice, egg, sausage)', serving_size_g: 350 }, { name: 'Pandesal', name_tagalog: 'Pandesal', category: 'almusal', calories: 35, protein_g: 1.5, carbs_g: 6, fat_g: 0.5, serving_description: '1 piece', serving_size_g: 30 }, // Desserts/Snacks { name: 'Halo-Halo', name_tagalog: 'Halo-Halo', category: 'meryenda', calories: 450, protein_g: 12, carbs_g: 85, fat_g: 8, serving_description: '1 glass', serving_size_g: 400 }, { name: 'Leche Flan', name_tagalog: 'Leche Flan', category: 'meryenda', calories: 220, protein_g: 5, carbs_g: 25, fat_g: 10, serving_description: '1 slice', serving_size_g: 80 }, { name: 'Turon', name_tagalog: 'Turon', category: 'meryenda', calories: 200, protein_g: 2, carbs_g: 35, fat_g: 7, serving_description: '1 piece', serving_size_g: 100 } ]; async function seed() { try { await sequelize.authenticate(); console.log('Database connection has been established successfully.'); // Sync database (create tables if not exists) await sequelize.sync(); let addedCount = 0; for (const foodData of filipinoFoods) { // Check if already exists const existing = await FoodItem.findOne({ where: { name: foodData.name, is_filipino: true } }); if (!existing) { await FoodItem.create({ ...foodData, source: 'filipino', is_filipino: true }); addedCount++; } } console.log(`Successfully added ${addedCount} Filipino foods to the database!`); } catch (error) { console.error('Error seeding Filipino foods:', error); } finally { await sequelize.close(); } } seed();