mirror of
https://github.com/taogaetz/chefbible.git
synced 2025-12-06 11:47:24 -05:00
176 lines
4.9 KiB
TypeScript
176 lines
4.9 KiB
TypeScript
import { PrismaClient } from '@prisma-app/client';
|
|
import { faker } from '@faker-js/faker';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
console.log('🧹 Clearing existing records...');
|
|
await prisma.menuRecipe.deleteMany();
|
|
await prisma.recipeIngredient.deleteMany();
|
|
await prisma.menu.deleteMany();
|
|
await prisma.recipe.deleteMany();
|
|
await prisma.ingredient.deleteMany();
|
|
await prisma.allergen.deleteMany();
|
|
|
|
console.log('🌱 Seeding database with food-themed data...');
|
|
|
|
// Allergens
|
|
const allergenNames = ['Gluten', 'Dairy', 'Tree Nuts', 'Eggs', 'Fish', 'Soy'];
|
|
const allergens = await Promise.all(
|
|
allergenNames.map(name =>
|
|
prisma.allergen.create({
|
|
data: { name, description: faker.food.description() },
|
|
})
|
|
)
|
|
);
|
|
|
|
// Ingredients (mix of spices, vegetables, meats, fruits)
|
|
const ingredientNames = new Set<string>();
|
|
const ingredients: any[] = [];
|
|
|
|
while (ingredientNames.size < 20) {
|
|
const typePick = faker.helpers.arrayElement([
|
|
() => faker.food.ingredient(),
|
|
() => faker.food.spice(),
|
|
() => faker.food.vegetable(),
|
|
() => faker.food.meat(),
|
|
() => faker.food.fruit(),
|
|
]);
|
|
|
|
const name = typePick();
|
|
if (!ingredientNames.has(name)) {
|
|
ingredientNames.add(name);
|
|
const randomAllergens = faker.helpers.arrayElements(allergens, faker.number.int({ min: 0, max: 2 }));
|
|
const ingredient = await prisma.ingredient.create({
|
|
data: {
|
|
name,
|
|
allergens: { connect: randomAllergens.map(a => ({ id: a.id })) },
|
|
},
|
|
});
|
|
ingredients.push(ingredient);
|
|
}
|
|
}
|
|
|
|
// Recipes with realistic kitchen data
|
|
const recipeData = [
|
|
{
|
|
name: 'Caesar Salad',
|
|
description: 'Classic Caesar salad with homemade dressing and croutons',
|
|
time: 'Quick',
|
|
station: 'Garde Manger'
|
|
},
|
|
{
|
|
name: 'Grilled Salmon',
|
|
description: 'Fresh salmon fillet grilled to perfection with herbs',
|
|
time: 'Medium',
|
|
station: 'Grill'
|
|
},
|
|
{
|
|
name: 'Beef Stir Fry',
|
|
description: 'Tender beef with vegetables in a savory sauce',
|
|
time: 'Quick',
|
|
station: 'Pans'
|
|
},
|
|
{
|
|
name: 'Braised Short Ribs',
|
|
description: 'Slow-cooked short ribs in red wine reduction',
|
|
time: 'Long',
|
|
station: 'Pans'
|
|
},
|
|
{
|
|
name: 'Charcuterie Board',
|
|
description: 'Artisanal meats and cheeses with accompaniments',
|
|
time: 'Quick',
|
|
station: 'Garde Manger'
|
|
},
|
|
{
|
|
name: 'Grilled Chicken Breast',
|
|
description: 'Herb-marinated chicken breast with seasonal vegetables',
|
|
time: 'Medium',
|
|
station: 'Grill'
|
|
},
|
|
{
|
|
name: 'Pasta Carbonara',
|
|
description: 'Classic Italian pasta with eggs, cheese, and pancetta',
|
|
time: 'Medium',
|
|
station: 'Pans'
|
|
},
|
|
{
|
|
name: 'Beef Tenderloin',
|
|
description: 'Premium cut grilled to your preference',
|
|
time: 'Medium',
|
|
station: 'Grill'
|
|
},
|
|
{
|
|
name: 'Garden Salad',
|
|
description: 'Fresh mixed greens with house vinaigrette',
|
|
time: 'Quick',
|
|
station: 'Garde Manger'
|
|
},
|
|
{
|
|
name: 'Duck Confit',
|
|
description: 'Traditional French duck confit with crispy skin',
|
|
time: 'Long',
|
|
station: 'Pans'
|
|
}
|
|
];
|
|
|
|
const recipes = await Promise.all(
|
|
recipeData.map(async (recipeInfo) => {
|
|
const recipeIngredients = faker.helpers.arrayElements(ingredients, faker.number.int({ min: 3, max: 6 }));
|
|
return prisma.recipe.create({
|
|
data: {
|
|
name: recipeInfo.name,
|
|
description: recipeInfo.description,
|
|
time: recipeInfo.time,
|
|
station: recipeInfo.station,
|
|
instructions: faker.lorem.paragraph(),
|
|
photoUrl: null,
|
|
ingredients: {
|
|
create: recipeIngredients.map(ing => ({
|
|
ingredientId: ing.id,
|
|
quantity: faker.number.int({ min: 10, max: 500 }),
|
|
unit: faker.helpers.arrayElement(['g', 'ml', 'pcs']),
|
|
})),
|
|
},
|
|
},
|
|
});
|
|
})
|
|
);
|
|
|
|
// Menus
|
|
const menus = await Promise.all(
|
|
['Spring', 'Summer', 'Autumn', 'Winter'].map(season => {
|
|
const seasonRecipes = faker.helpers.arrayElements(recipes, 3);
|
|
return prisma.menu.create({
|
|
data: {
|
|
name: `${season} Menu: ${faker.food.ethnicCategory()}`,
|
|
season,
|
|
recipes: {
|
|
create: seasonRecipes.map((rec, index) => ({
|
|
recipeId: rec.id,
|
|
position: index + 1,
|
|
})),
|
|
},
|
|
},
|
|
});
|
|
})
|
|
);
|
|
|
|
console.log('✅ Seeding complete!');
|
|
console.log('--- Summary ---');
|
|
console.log(`Allergens created: ${allergens.length}`);
|
|
console.log(`Ingredients created: ${ingredients.length}`);
|
|
console.log(`Recipes created: ${recipes.length}`);
|
|
console.log(`Menus created: ${menus.length}`);
|
|
}
|
|
|
|
main()
|
|
.catch(e => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|