feat: enhance ingredient matching rules with keyword matching and add chocolate detection
Test Suite / test (24.15.0) (push) Has been cancelled

This commit is contained in:
Nils-Johan Gynther
2026-05-08 17:36:06 +02:00
parent bd78b1de81
commit 853e853e5e
2 changed files with 36 additions and 12 deletions
+13 -6
View File
@@ -153,13 +153,20 @@ Regler:
Tillgängliga kategorier (format: [id] Sökväg):
${categoryList}
KWICK-MATCHNING (gör detta först):
- Kött/fläsk: Sök efter ord som "fläsk", "flaskytterfile", "bacon", "kotlett", "karré" → Kött, chark & fågel > Fläsk
- Fågel: Sök efter "kyckling", "kalkon", "drumstick", "filé" → Kött, chark & fågel > Fågel
- Choklad/spreads: Sök efter "nutella", "choklad", "kakao", "spreads" → Sötsaker & snacks > Choklad & spreads
- Bröd: Sök efter "bröd", "toast", "brödrost", "limpa" → Bröd & bakvaror > Bröd
Regler:
1. Välj den mest specifika underkategorin som passar produkten.
2. Om ingen specifik kategori passar, välj en underkategori under "Övrigt" om möjligt.
3. Om ingen underkategori under "Övrigt" passar, välj "Övrigt" (den kategori vars sökväg är exakt "Övrigt").
4. Du MÅSTE alltid returnera ett svar — aldrig null eller tomt.
5. Svara ENDAST med giltig JSON i detta format: { "categoryId": <nummer>, "confidence": "high" | "medium" | "low" }
- "high": uppenbart matchande kategori
1. Använd KEYWORD-MATCHNING först innan annat.
2. Om ingen keyword-match, välj den mest specifika underkategorin som passar.
3. Om ingen specifik kategori passar, välj en underkategori under "Övrigt" om möjligt.
4. Om ingen underkategori under "Övrigt" passar, välj "Övrigt" (den kategori vars sökväg är exakt "Övrigt").
5. Du MÅSTE alltid returnera ett svar — aldrig null eller tomt.
6. Svara ENDAST med giltig JSON i detta format: { "categoryId": <nummer>, "confidence": "high" | "medium" | "low" }
- "high": keyword-match ELLER uppenbart matchande kategori
- "medium": trolig matchning
- "low": osäker, används fallback (Övrigt eller underkategori till Övrigt)`;
@@ -68,12 +68,11 @@ function hasPorkLikeSignal(normalized: string): boolean {
normalized.includes('bacn') ||
normalized.includes('baco') ||
/\bbac[a-z0-9]{1,5}\b/.test(normalized) ||
/\bsidflask\b/.test(normalized) ||
/\bpancetta\b/.test(normalized) ||
/\bflask\b/.test(normalized) ||
/\bflaskfile\b/.test(normalized) ||
/\bkarr[eé]\b/.test(normalized) ||
/\bkotlett\b/.test(normalized)
normalized.includes('sidflask') ||
normalized.includes('pancetta') ||
normalized.includes('flask') ||
normalized.includes('karre') ||
normalized.includes('kotlett')
);
}
@@ -699,6 +698,24 @@ export class ReceiptImportService {
if (hit) return hit;
}
// ── Regel: Choklad & spreads (Nutella, sjokolade, m.m.) ─────────────
const hasChocolateSignal =
normalized.includes('nutella') ||
normalized.includes('chocolate') ||
normalized.includes('choklad') ||
normalized.includes('sjokolade') ||
normalized.includes('kakao') ||
normalized.includes('spreads');
if (hasChocolateSignal) {
const chocolate = findCategory({
name: 'choklad & spreads',
includes: 'sötsaker',
});
const hit = toSuggestion(chocolate, 'high');
if (hit) return hit;
}
// ── Regel: Korvfamiljen ─────────────────────────────────────────────
const hasSausageSignal =
/\bkorv\b/.test(normalized) ||