feat: make pantry items and meal plan entries user-scoped; update related services and controllers

This commit is contained in:
Nils-Johan Gynther
2026-04-22 18:38:04 +02:00
parent 44b4e7ad73
commit 4482129fca
6 changed files with 123 additions and 35 deletions
+30 -11
View File
@@ -22,9 +22,10 @@ export class MealPlanService {
constructor(private readonly prisma: PrismaService) {}
/** Hämta matplan för ett datumintervall (default: nuvarande vecka) */
async findByRange(from: string, to: string) {
async findByRange(userId: number, from: string, to: string) {
return this.prisma.mealPlanEntry.findMany({
where: {
userId,
date: { gte: new Date(from), lte: new Date(to) },
},
include: { recipe: { select: recipeSelect } },
@@ -33,28 +34,43 @@ export class MealPlanService {
}
/** Sätt recept för ett datum (upsert — ett recept per dag) */
async upsert(dto: CreateMealPlanEntryDto) {
async upsert(userId: number, dto: CreateMealPlanEntryDto) {
const date = new Date(dto.date);
return this.prisma.mealPlanEntry.upsert({
where: { date },
create: { date, recipeId: dto.recipeId, servings: dto.servings ?? null },
where: {
userId_date: {
userId,
date,
},
},
create: {
userId,
date,
recipeId: dto.recipeId,
servings: dto.servings ?? null,
},
update: { recipeId: dto.recipeId, servings: dto.servings ?? null },
include: { recipe: { select: recipeSelect } },
});
}
/** Ta bort matplanspost för ett datum */
async removeByDate(date: string) {
async removeByDate(userId: number, date: string) {
const entry = await this.prisma.mealPlanEntry.findUnique({
where: { date: new Date(date) },
where: {
userId_date: {
userId,
date: new Date(date),
},
},
});
if (!entry) throw new NotFoundException('Ingen matplanspost för detta datum');
return this.prisma.mealPlanEntry.delete({ where: { id: entry.id } });
}
/** Samlad ingredienslista för ett datumintervall */
async shoppingList(from: string, to: string) {
const entries = await this.findByRange(from, to);
async shoppingList(userId: number, from: string, to: string) {
const entries = await this.findByRange(userId, from, to);
// Summera ingredienser per produkt+enhet (skalat per portionsantal)
const map = new Map<string, { productId: number; name: string; quantity: number; unit: string }>();
@@ -83,11 +99,14 @@ export class MealPlanService {
}
/** Jämför veckans ingrediensbehov mot inventariet */
async inventoryCompare(from: string, to: string) {
const entries = await this.findByRange(from, to);
async inventoryCompare(userId: number, from: string, to: string) {
const entries = await this.findByRange(userId, from, to);
// Hämta pantry-produkter — dessa anses alltid tillgängliga
const pantryItems = await this.prisma.pantryItem.findMany({ select: { productId: true } });
const pantryItems = await this.prisma.pantryItem.findMany({
where: { userId },
select: { productId: true },
});
const pantryProductIds = new Set(pantryItems.map((p) => p.productId));
// Aggregera ingredienser per produkt+enhet (skalat per portionsantal)