feat: add product validation in recipe update and creation; throw BadRequestException for inactive products
Test Suite / test (24.15.0) (push) Has been cancelled

This commit is contained in:
Nils-Johan Gynther
2026-05-04 21:30:51 +02:00
parent 648e1856a1
commit b7c857732c
+22 -1
View File
@@ -1,4 +1,4 @@
import { ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { BadRequestException, ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
@@ -21,6 +21,21 @@ export class RecipesService {
throw new NotFoundException(`Recipe with id ${id} not found`);
}
private async assertProductsActive(productIds: number[]): Promise<void> {
if (productIds.length === 0) return;
const activeProducts = await this.prisma.product.findMany({
where: { id: { in: productIds }, isActive: true },
select: { id: true },
});
if (activeProducts.length !== productIds.length) {
const foundIds = new Set(activeProducts.map((p) => p.id));
const missing = productIds.filter((id) => !foundIds.has(id));
throw new BadRequestException(
`En eller flera ingrediensprodukter är inaktiva eller finns inte: ${missing.join(', ')}`,
);
}
}
private async findRecipeByIdOrThrow(id: number) {
const recipe = await this.prisma.recipe.findUnique({ where: { id } });
if (!recipe) {
@@ -232,6 +247,9 @@ export class RecipesService {
const existingRecipe = await this.findRecipeByIdOrThrow(id);
this.assertRecipeEditableByUser(existingRecipe, userId, id);
// Validera att alla produkter är aktiva
await this.assertProductsActive(updateRecipeDto.ingredients.map((i) => i.productId));
// Ta bort gamla ingredienser
await this.prisma.recipeIngredient.deleteMany({
where: { recipeId: id },
@@ -379,6 +397,9 @@ export class RecipesService {
}
async create(createRecipeDto: CreateRecipeDto, userId: number) {
// Validera att alla produkter är aktiva
await this.assertProductsActive(createRecipeDto.ingredients.map((i) => i.productId));
this.logger.log(
`[create] Incoming imageUrl from client: ${createRecipeDto.imageUrl ?? 'null'}`,
);