9197d93a92
- Nytt endpoint GET /v1/inventory/natural-search. - Robust matchning med unaccent + pg_trgm similarity mot display_name, brand och kanoniska ingrediensnamn (sv/en). - Svar byggs deterministiskt från faktisk data: lagringsplats + sublocation om registrerad, trust-state-hedge från befintlig trust-motor. - Server-sidan i18n-katalog för 12 språk. - Tester för svensk träff och noll-träff på flera språk. - Design-dokument docs/30-sökrobusthet-matvaror.md.
2.9 KiB
2.9 KiB
Sökrobusthet för matvaror i hushållslagret
Målbild: användaren kan ställa en fritextfråga om vad som finns hemma och få ett svar som känns mänskligt, visar exakt lagring (FoodTwin) och ärligt berättar hur säker appen är – utan att hitta på något.
Befintliga motorer
Sökmotor: /v1/inventory
- Enkel
ILIKEmotinventory_items.display_nameochbrand. - Inga synonymer, ingen fonetisk matchning, ingen felstavningstolerans.
- Filtrering på
storage_location_id,expiry_status, paginering.
Förbättrad sökmotor: /v1/inventory/natural-search
- Kombinerar
unaccent(...) ILIKE unaccent(...)med PostgreSQLpg_trgm-similarity. - Söker även mot kanoniska ingrediensnamn (
name_sv,name_en). - Sorterar på
GREATEST(similarity(...)). - Returnerar både strukturerade träffar och ett naturligt-språkligt svar.
Trust-motor (@app/inventory-engine)
computeTrust(...)gertrustState(trusted/decaying/stale/unverified) ochtrustScore0–100.- Baserat på
confidence,verifiedByUser, ålder och förruttnelseprofil. - Används redan i
/v1/inventoryoch vid skanning/konsumtion.
FoodTwin-data
storage_locations: namn, typ, sublocations.inventory_items:storage_location_id,sublocation, kvantitet, enhet,trust_state.canonical_ingredients: kanoniskt namn, synonymer, hållbarhetsriktlinjer.
Svarsformat
GET /v1/inventory/natural-search?q=mjölk&languageTag=sv-SE
{
"query": "mjölk",
"response": "Jag hittade **Mjölk** i Kylen (mellanmålshyllan). Jag är ganska säker på att den finns kvar.",
"items": [
{
"id": "...",
"displayName": "Mjölk",
"quantity": 1,
"unit": "LITER",
"locationName": "Kylen",
"locationType": "fridge",
"sublocation": "mellanmålshyllan",
"trustState": "trusted",
"trustScore": 95
}
]
}
i18n
Server-sidan använder en minimal katalog i apps/api/src/lib/inventorySearchResponse.ts.
Stödja språk (12): sv, en, da, de, es, fi, fr, it, nb, nl, pl, pt.
Vid okänt språk faller vi tillbaka till engelska och sedan svenska.
Hårda regler
- Inga påhittade fakta. Om sublocation saknas visas inte "på hylla X".
- Trust-hedge måste matcha
trustState.staleger en osäker formulering;trustedger en trygg. - Noll träffar ska erkänna det och erbjuda att lägga till.
- Flera träffar ska lista dem med lagring och peka på listan för trust-score.
Nästa steg / öppna frågor
- Ska vi också söka i
canonical_ingredients.aliases(array)? Kräver enunnest/CROSS JOIN LATERALeller en trigram-index på en materialiserad vy. - Ska vi lägga till fonetisk matchning (
fuzzystrmatch) för vanliga felstavningar? - Ska svaret också inkludera hållbarhetsstatus för träffarna?
- Behövs en separat vector/embedding-sökning för semantiska matchningar (t.ex. "mjölkprodukter")?