"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = require("express"); const client_1 = require("@prisma/client"); const joi_1 = __importDefault(require("joi")); const router = (0, express_1.Router)(); const prisma = new client_1.PrismaClient(); const recipeSchema = joi_1.default.object({ recipeNumber: joi_1.default.string().optional().allow(''), title: joi_1.default.string().required().min(1).max(255), description: joi_1.default.string().optional().allow(''), category: joi_1.default.string().optional().allow(''), preparation: joi_1.default.string().optional().allow(''), servings: joi_1.default.number().integer().min(1).default(1), ingredients: joi_1.default.string().optional().allow(''), instructions: joi_1.default.string().optional().allow(''), comment: joi_1.default.string().optional().allow(''), }); const updateRecipeSchema = recipeSchema; router.get('/', async (req, res, next) => { try { const { search = '', category = '', page = '1', limit = '10', sortBy = 'title', sortOrder = 'asc' } = req.query; const pageNum = parseInt(page); const limitNum = parseInt(limit); const skip = (pageNum - 1) * limitNum; const where = {}; if (search) { where.OR = [ { title: { contains: search } }, { description: { contains: search } }, { ingredients: { contains: search } }, ]; } if (category) { where.category = { contains: category }; } const [recipes, total] = await Promise.all([ prisma.recipe.findMany({ where, include: { images: true, ingredientsList: true, }, orderBy: { [sortBy]: sortOrder }, skip, take: limitNum, }), prisma.recipe.count({ where }) ]); return res.json({ success: true, data: recipes, pagination: { page: pageNum, limit: limitNum, total, pages: Math.ceil(total / limitNum), }, }); } catch (error) { next(error); } }); router.get('/:id', async (req, res, next) => { try { const { id } = req.params; if (!id) { return res.status(400).json({ success: false, message: 'Recipe ID is required', }); } const recipeId = parseInt(id); if (isNaN(recipeId)) { return res.status(400).json({ success: false, message: 'Invalid recipe ID format', }); } const recipe = await prisma.recipe.findUnique({ where: { id: recipeId }, include: { images: true, ingredientsList: true, } }); if (!recipe) { return res.status(404).json({ success: false, message: 'Recipe not found', }); } if ((!recipe.ingredients || recipe.ingredients.trim() === '' || recipe.ingredients.length < 10) && recipe.recipeNumber) { try { const paddedNumber = recipe.recipeNumber.padStart(3, '0'); const recipeNumberWithR = `R${paddedNumber}`; const separateIngredients = await prisma.ingredient.findFirst({ where: { recipeNumber: recipeNumberWithR } }); if (separateIngredients && separateIngredients.ingredients) { recipe.ingredients = separateIngredients.ingredients; } } catch (ingredientError) { console.log(`Could not load separate ingredients for recipe ${recipe.recipeNumber}:`, ingredientError); } } const now = new Date(); prisma.recipe.update({ where: { id: recipeId }, data: { lastUsed: now }, select: { id: true } }).catch(err => console.warn('lastUsed update failed for recipe', recipeId, err.message)); recipe.lastUsed = now; return res.json({ success: true, data: recipe, }); } catch (error) { next(error); } }); router.post('/', async (req, res, next) => { try { const { error, value } = recipeSchema.validate(req.body); if (error) { return res.status(400).json({ success: false, message: 'Validation error', details: error.details, }); } if (!value.recipeNumber || value.recipeNumber.trim() === '') { const lastRecipe = await prisma.recipe.findFirst({ orderBy: { id: 'desc' }, select: { recipeNumber: true } }); let nextNumber = 1; if (lastRecipe?.recipeNumber) { const match = lastRecipe.recipeNumber.match(/\d+/); if (match) { nextNumber = parseInt(match[0]) + 1; } } value.recipeNumber = `R${nextNumber.toString().padStart(3, '0')}`; } const recipe = await prisma.recipe.create({ data: value, include: { images: true, ingredientsList: true, } }); return res.status(201).json({ success: true, data: recipe, message: 'Recipe created successfully', }); } catch (error) { next(error); } }); router.put('/:id', async (req, res, next) => { try { const { id } = req.params; if (!id) { return res.status(400).json({ success: false, message: 'Recipe ID is required', }); } const { error, value } = updateRecipeSchema.validate(req.body); if (error) { return res.status(400).json({ success: false, message: 'Validation error', details: error.details, }); } const recipe = await prisma.recipe.update({ where: { id: parseInt(id) }, data: value, include: { images: true, ingredientsList: true, } }); return res.json({ success: true, data: recipe, message: 'Recipe updated successfully', }); } catch (error) { next(error); } }); router.delete('/:id', async (req, res, next) => { try { const { id } = req.params; if (!id) { return res.status(400).json({ success: false, message: 'Recipe ID is required', }); } await prisma.recipe.delete({ where: { id: parseInt(id) } }); return res.json({ success: true, message: 'Recipe deleted successfully', }); } catch (error) { next(error); } }); exports.default = router; //# sourceMappingURL=recipes.js.map