fix(reco): fria sökord + mjuk-filter så råvaru-sökning (kyckling) ger rätt recept (MIKRO 60)
CI / Typecheck, test & build (push) Failing after 42s
CI / Typecheck, test & build (push) Failing after 42s
This commit is contained in:
@@ -393,7 +393,22 @@ export async function recommendationRoutes(app: FastifyInstance) {
|
|||||||
const weights = personalizationEnabled
|
const weights = personalizationEnabled
|
||||||
? viewWeights(q.view)
|
? viewWeights(q.view)
|
||||||
: depersonalize(viewWeights(q.view));
|
: depersonalize(viewWeights(q.view));
|
||||||
let recommendations = rankAll(scoredCandidates, ctx, weights, q.limit);
|
|
||||||
|
// Om användaren sökte specifikt (t.ex. "kyckling") – visa matchande recept först.
|
||||||
|
let pool = scoredCandidates;
|
||||||
|
if (craving && (craving.keywords.length > 0 || craving.cuisine)) {
|
||||||
|
const matches = scoredCandidates.filter((c) => {
|
||||||
|
const title = c.titleSv.toLowerCase();
|
||||||
|
const tagSet = new Set<string>(c.tags as unknown as string[]);
|
||||||
|
return (
|
||||||
|
(!!craving.cuisine && c.cuisine === craving.cuisine) ||
|
||||||
|
craving.keywords.some((k) => title.includes(k) || tagSet.has(k))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
if (matches.length > 0) pool = matches; // annars behåll alla (aldrig tomt)
|
||||||
|
}
|
||||||
|
|
||||||
|
let recommendations = rankAll(pool, ctx, weights, q.limit);
|
||||||
|
|
||||||
// --- 9. AAMOS-omrankning bakom feature flag (aldrig obligatorisk) ---
|
// --- 9. AAMOS-omrankning bakom feature flag (aldrig obligatorisk) ---
|
||||||
if (await app.flags.isEnabled("ai_rerank", req.userId)) {
|
if (await app.flags.isEnabled("ai_rerank", req.userId)) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export interface ParsedCraving {
|
|||||||
tags: string[];
|
tags: string[];
|
||||||
cuisine?: Cuisine | undefined;
|
cuisine?: Cuisine | undefined;
|
||||||
maxKcal?: number | undefined;
|
maxKcal?: number | undefined;
|
||||||
|
keywords: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,5 +67,34 @@ export function parseCraving(text: string): ParsedCraving {
|
|||||||
const kcalMatch = lower.match(/under\s+(\d{2,4})\s*(?:kcal|kalorier)/);
|
const kcalMatch = lower.match(/under\s+(\d{2,4})\s*(?:kcal|kalorier)/);
|
||||||
if (kcalMatch?.[1]) maxKcal = Number(kcalMatch[1]);
|
if (kcalMatch?.[1]) maxKcal = Number(kcalMatch[1]);
|
||||||
|
|
||||||
return { tags, cuisine, maxKcal };
|
const STOPWORDS = new Set([
|
||||||
|
"jag",
|
||||||
|
"är",
|
||||||
|
"sugen",
|
||||||
|
"på",
|
||||||
|
"vill",
|
||||||
|
"ha",
|
||||||
|
"något",
|
||||||
|
"lite",
|
||||||
|
"och",
|
||||||
|
"med",
|
||||||
|
"gärna",
|
||||||
|
"känner",
|
||||||
|
"för",
|
||||||
|
"mig",
|
||||||
|
"idag",
|
||||||
|
"ikväll",
|
||||||
|
"kväll",
|
||||||
|
"mat",
|
||||||
|
"äta",
|
||||||
|
"laga",
|
||||||
|
"göra",
|
||||||
|
"en",
|
||||||
|
"ett",
|
||||||
|
]);
|
||||||
|
const keywords = lower
|
||||||
|
.split(/[^a-zåäö0-9]+/)
|
||||||
|
.filter((w) => w.length >= 3 && !STOPWORDS.has(w));
|
||||||
|
|
||||||
|
return { tags, cuisine, maxKcal, keywords };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user