chefbible/prisma/seed.ts

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();
});