diff --git a/apps/api/src/routes/recommendations.ts b/apps/api/src/routes/recommendations.ts index dd7165d..d7b77ed 100644 --- a/apps/api/src/routes/recommendations.ts +++ b/apps/api/src/routes/recommendations.ts @@ -383,6 +383,7 @@ export async function recommendationRoutes(app: FastifyInstance) { ratingCount: recipe.ratingCount, peakSeasons: recipe.peakSeasons, holidayTags: recipe.holidayTags, + mealTypes: recipe.mealTypes, spiceLevel: recipe.spiceLevel, coverage, daysSinceLastCooked: lastDate diff --git a/packages/recommendation-engine/src/scoring.ts b/packages/recommendation-engine/src/scoring.ts index 13a3e99..377d402 100644 --- a/packages/recommendation-engine/src/scoring.ts +++ b/packages/recommendation-engine/src/scoring.ts @@ -108,6 +108,12 @@ export function scoreCandidate( parts.cookingAssumptionFit = 0; } + // 16. Måltids-lämplighet: nedvikta lätta övergångsrätter (frukost/dessert) vid huvudmåltid. + const mainMeal = ctx.mealType === "dinner" || ctx.mealType === "lunch"; + const crossover = + (candidate.mealTypes ?? []).includes("breakfast") || (candidate.mealTypes ?? []).includes("dessert"); + parts.mealFit = mainMeal && crossover ? 0.15 : 1; + const score = weightedSum(parts, weights); return { diff --git a/packages/recommendation-engine/src/types.ts b/packages/recommendation-engine/src/types.ts index 766b290..2fa629e 100644 --- a/packages/recommendation-engine/src/types.ts +++ b/packages/recommendation-engine/src/types.ts @@ -37,6 +37,7 @@ export interface RecommendationCandidate { ratingCount: number; peakSeasons: Season[]; holidayTags: string[]; + mealTypes?: MealType[]; spiceLevel: number; coverage: CoverageResult; /** Dagar sedan hushållet senast lagade receptet (null = aldrig). */ @@ -104,6 +105,7 @@ export interface ScoringWeights { variety: number; weather: number; craving: number; + mealFit: number; /** Nya S1-vikter; 0 om personalisering är av. */ memoryFit: number; tasteFit: number; @@ -123,6 +125,7 @@ export const DEFAULT_WEIGHTS: ScoringWeights = { variety: 6, weather: 3, craving: 15, + mealFit: 12, memoryFit: 6, tasteFit: 6, cookingAssumptionFit: 4, @@ -155,6 +158,7 @@ export const TASTE_VIEW_WEIGHTS: ScoringWeights = { variety: 3, weather: 1, craving: 25, + mealFit: 12, memoryFit: 12, tasteFit: 12, cookingAssumptionFit: 6, @@ -174,6 +178,7 @@ export const HEALTH_VIEW_WEIGHTS: ScoringWeights = { variety: 4, weather: 2, craving: 5, + mealFit: 12, memoryFit: 3, tasteFit: 3, cookingAssumptionFit: 4, @@ -193,6 +198,7 @@ export const PANTRY_VIEW_WEIGHTS: ScoringWeights = { variety: 2, weather: 1, craving: 5, + mealFit: 12, memoryFit: 4, tasteFit: 4, cookingAssumptionFit: 8,