import { PrismaClient } from "@prisma/client"; import Logger from "../utils/logger"; const logger = new Logger(); class RecipeModel { private prisma: PrismaClient; constructor() { this.prisma = new PrismaClient(); } async getAllRecipes(): Promise { try { logger.info("index page view"); return await this.prisma.recipes.findMany(); } catch (err) { console.error("Error fetching all recipes:", err); throw new Error(err instanceof Error ? err.message : "Unknown error"); } } async findById(id: number): Promise { try { const recipe = await this.prisma.recipes.findUnique({ where: { id }, include: { recipeSteps: true, recipeIngredients: true }, }); if (!recipe) { logger.warn(`Recipe with id ${id} cannot be found`); return null; } const data = { details: { id: recipe.id, name: recipe.name, author: recipe.author, cuisine: recipe.cuisine, stars: recipe.stars, prep_minutes: recipe.prep_minutes, cook_minutes: recipe.cook_minutes, }, ingredients: recipe.recipeIngredients.map((ing) => ing.raw), steps: recipe.recipeSteps.map((step) => ({ step_number: step.step_number, instruction: step.instruction, })), }; logger.info("recipe page view", { recipe_id: data.details.id, recipe_name: data.details.name, }); return data; } catch (err) { console.log("Error finding recipe:", err); logger.error("Error finding recipe", { message: err instanceof Error ? err.message : "Unknown error", }); throw new Error(err instanceof Error ? err.message : "Unknown error"); } } async addRecipe(recipeData: { name: string; author: string; cuisine: string; stars: number; ingredients: string[]; steps: { [key: string]: string }; prep_minutes: number; cook_minutes: number; }): Promise { const { name, author, cuisine, stars, ingredients, steps, prep_minutes, cook_minutes, } = recipeData; try { const createdRecipe = await this.prisma.recipes.create({ data: { name, author, cuisine, prep_minutes, cook_minutes, stars, recipeIngredients: { create: ingredients.map((ing) => ({ raw: ing })), }, recipeSteps: { create: Object.keys(steps).map((stepNumber) => ({ step_number: parseInt(stepNumber), instruction: steps[stepNumber], })), }, }, }); logger.info("New recipe created", { id: createdRecipe.id, name: createdRecipe.name, }); return createdRecipe; } catch (err) { console.log("Error creating recipe:", err); logger.error("Error creating recipe", { message: err instanceof Error ? err.message : "Unknown error", }); throw new Error("Failed to add recipe"); } } async setStars(id: number, stars: number): Promise<{ message: string }> { try { await this.prisma.recipes.update({ where: { id }, data: { stars }, }); return { message: "Stars updated" }; } catch (err) { console.error("Error updating stars:", err); logger.error("Error setting stars", { message: err instanceof Error ? err.message : "Unknown error", }); throw new Error(err instanceof Error ? err.message : "Unknown error"); } } async deleteRecipe(id: number): Promise<{ message: string }> { try { await this.prisma.recipe_ingredients.deleteMany({ where: { recipe_id: id }, }); await this.prisma.recipe_steps.deleteMany({ where: { recipe_id: id }, }); const deletedRecipe = await this.prisma.recipes.delete({ where: { id }, }); logger.info("Recipe deleted", { id: deletedRecipe.id, name: deletedRecipe.name, }); return { message: "Recipe deleted successfully" }; } catch (err) { console.error("Error deleting recipe:", err); logger.error("Error deleting recipe", { message: err instanceof Error ? err.message : "Unknown error", }); throw new Error(err instanceof Error ? err.message : "Unknown error"); } } } export default RecipeModel;