Ingredienser: fyllde luckan från 101 till 362 för da/de/es/fi/fr/it/nb/nl/pl/pt
(engelska hade redan alla 362). Nu 3982 översättningar, 11 språk kompletta – en
spansk/tysk/fransk användare ser ingrediensnamn på sitt språk, inte svenska.
Författat av språkexperter per språk, verifierat mot 362-listan + kvalitetskoll.
Recept: 407 recept har 0 översättningar (svensk källa visas). Lade till två
körbara skript för AI-pipelinen (kräver din Gemini-nyckel i workern):
- scripts/translate-recipes.ts [språk|all] – köar TRANSLATE_RECIPE för alla
publicerade recept × språk, idempotent (hoppar redan gjorda).
- scripts/publish-translations.ts [språk|all] – publicerar de utkast som klarat
den inbyggda verifieringen (numbersPreserved/stegantal/confidence); övriga
stannar som utkast för granskning.
Verifierat mot testdatabas: ingredient_translations 3982 rader/11 språk kompletta;
enqueue köar 405 jobb; processor skapar draft_ai+ok; publish publicerar; steg-
översättningar följer med och serveras.
Behaller maltidsfoto men informerar: 'Varje foto raknas som en skanning av din
kvot. Streckkod ar alltid gratis.' visas pa Skanna-skarmen under kvot-raden.
Ny i18n-nyckel scan.costNote x 12 sprak. Verifierat: mobil-typecheck gront.
Tar bort expiry_date ur skanningsknapparna pa Skanna-fliken. Sjalva scan-typen
finns kvar i backend/enums (ofarligt), bara knappen forsvinner. Verifierat:
mobil-typecheck gront.
Efter lyckad lasning/produktbidrag fanns bara 'Skanna igen'. Nu finns en tydlig
knapp som bekraftar och gar tillbaka dit man kom ifran (router.back):
'Stammer - klar' nar man just bidragit med foto, annars 'Klar'. 'Skanna igen'
finns kvar som sekundar, och 'Fota baksidan' visas nar info saknas.
Nya i18n-nycklar barcode.done + barcode.looksRight x 12 sprak.
Verifierat: mobil-typecheck gront.
Streckkod / produktbidrag:
- Tydlig bekraftelse 'Sparad i delade katalogen - tack!' visas nu efter att en
fotad produkt lasts av, sa man ser att bidraget gick fram (forut bara
'Skanna igen' utan aterkoppling).
- Naringsetiketter laser nu ocksa enkelomattat och fleromattat fett (t.ex.
olivolja visar tre fettrader). Nya valfria falt monounsaturatedFatG/
polyunsaturatedFatG i NutritionValues + READ_NUTRITION_LABEL + prompt +
produktpanelen. Obligatoriska EU-falt oforandrade.
Kvitto:
- Rader som ar samma vara (samma normaliserade namn + enhet) slas nu ihop till
EN vara med ratt antal - '2 x mjolk' pa kvittot blir en vara a 2 st i stallet
for tva rader a 1 st. Priser summeras, rabatter dras som forut. En kvittorad
raknas som minst 1 exemplar aven om antal saknas.
Verifierat: typecheck hela repot gront, nutrition-engine 19/19, ai-contracts
24/24, worker 23/23, api 104/104, samt repro mot testdatabas (2 mjolk-rader ->
1 vara a 2; olivolja sparar fett/mattat/enkel-/fleromattat).
Veckoplan/kalender:
- Byt ratt: PATCH satter nu titeln (och portioner/status) efter det nya
receptet, inte bara recipeId - annars visade kalendern kvar gamla ratten.
- Planera om veckan: ersatter nu veckans plan (raderar tidigare + entries via
kaskad) sa man aldrig far dubbletter och alltid ser den nya planen. Nytt
plan-id ger ocksa ny variation.
- Variation: liten deterministisk jitter per recept, seedad pa plan-id +
veckostart, sa olika veckor OCH omgenereringar blir olika. Tackning/utgang
dominerar fortfarande. Skalas av varietyLevel.
- Veckoplaneraren visar alltid mandag-sondag (mondayOf), oavsett dagens dag.
Streckkod (fota okand produkt):
- Fotar nu fram- OCH baksida (multi-foto) sa AI:n far bade namn (fram) och
naring/innehall (bak). Prompt uppdaterad for flera bilder.
- Worker uppdaterar en befintlig delad produkt aven utan nytt namn (behaller
namnet, fyller pa naring/innehall/allergener) - och sparar ny produkt aven
fran baksidesfoto (fallback-namn) sa data inte tappas.
- Produktpanelen visar 'Fota baksidan (naring & innehall)' nar info saknas, sa
man kan komplettera en halvfardig produkt. Fel visas som dialog utan att
tappa vyn.
- 5 nya i18n-nycklar x 12 sprak.
Verifierat: typecheck (ai-contracts/worker/api/mobil), worker 23/23,
ai-contracts 24/24, api 104/104, samt repro mot testdatabas (byt ratt satter
titel; planera om ger 1 plan; 3 veckor + omgenerering varierar; delvis produkt
kompletteras och behaller namnet).
Okand streckkod erbjuder nu 'Fota forpackningen' direkt i streckkodsvyn.
Fotot lases av (naring/allergener/innehall) och produkten UPSERTas i den
DELADE products-katalogen kopplat till GTIN (dataSource=user_scanned,
verificationStatus=unverified, createdByUserId=anvandaren) sa nasta person
som skannar samma kod far den direkt. Produkten laggs INTE till i lagret.
Naringsdeklaration-knappen tas bort som egen ingang - flodet vavs in i
streckkodsskanningen. product_package/nutrition_label -> READ_NUTRITION_LABEL
avslutar som 'completed' med result.product (ingen awaiting_confirmation).
- validation: barcode-falt i createScanInput.context
- worker: ny gren i processScanJob som skriver till products + returnerar tidigt
- mobil: inline contributePhoto (fota -> ladda upp -> polla -> visa info)
- scan: ta bort naringsdeklaration-knappen
- i18n: barcode.contributing.* + uppdaterad unknownBody pa 12 sprak
Verifierat: typecheck (validation/worker/api/mobil), worker 23/23, api 104/104,
och repro mot testdatabas (products-upsert, ingen inventory, idempotent aterskann).
Alla 44 ingredienser utan defaultPriceMinorPerKg har fatt rimliga
schablonpriser (kr/kg) sa det ALLTID finns en prisuppskattning; kvitto-
priser forfinar sen. Verifierat: 0 ingredienser utan pris i DB.
- Byt rätt gav 'något gick fel': limit=30 översteg schemats tak (20).
Höjt taket till 50, byt rätt hämtar 40 + sök vilken rätt som helst.
- Veckonavigering: pilarna byter nu VECKA (weekOffset) i stället för att
bara flytta markerad dag -> går att planera nästa vecka. Titel visar
veckans datumintervall; bakåt spärras före denna vecka.
- Lägg till måltid: ny POST /v1/week-plans/:id/entries + knapp 'Lägg till
måltid' (väljer måltidstyp -> receptväljaren i lägg-till-läge) + knapp
'Planera om veckan'. Går nu att fylla en tom dag igen.
Verifierat: swap 200 (40 varierade), add-entry 201, delete 200, api 104/104.
Rena tillbehor utan protein i titeln (potatisgratang, mos, pommes) far
en not: 'servera med en proteinbit (ryggbiff/entrecote, kyckling, fisk
eller tofu/halloumi)'. Kott-/korv-/fiskgratanger raknas som hela ratter.
Verifierat mot riktig data: 5 av 19 gratang-traffar klassas som tillbehor,
inga falska traffar pa proteinratter.
Klick pa en maltid oppnar en egen panel: 'Jag lagade detta' (ratt dag),
'Byt ratt', 'Ta bort'. Ingen 'Avbryt' - tryck utanfor for att stanga.
Kanns mer enterprise an systemets Alert-ruta.
Byt-ratt-skarmen far ett sokfalt. Med sokning filtreras maltidstyp bort
pa servern -> byt till vilken ratt som helst. Utan sokning visas breda
forslag for slotten (view=swap).
communityPublish satts till false aven under trial (ovriga premium-
funktioner ingar fortfarande i provperioden). Endast betalda planer
(household/family/large_household) far skicka in egna recept. Uppdaterat
premium-meddelandet i appen (11 sprak + sv) sa det inte langre antyder
att provperioden lases upp funktionen. Verifierat: subscriptions 10/10,
api 104/104, typecheck gron.
QR-produktinfo (barcode.info.*), egna recept (submit.*) och 'har du
lagat denna' (cookedLog.*) fyllda i en/da/nb/de/nl/fr/es/it/pt/fi/pl
(39 nycklar/sprak). Slutar falla tillbaka pa svenska.
Skann-bekraftelse slar bara ihop dubbletter inom SAMMA plats (mjolk i
kyl != mjolk i frys) + hoppar over tomma poster. Lagerlistan far en
tydlig 'Ta bort' direkt pa varje rad (inte bara via markering).
Ny ruta langst ner pa receptet: registrera att man lagat ratten sa
r:knas ravarorna av fran lagret och maltiden loggas (aven utan kalender).
Saknade ravaror hoppas over utan krasch (befintlig /cook-endpoint).
POST aterananvander EN aktiv lista per veckoplan (staplar inte nya),
GET sorterar nyaste forst, och appen navigerar med listId. Tidigare
hamnade de genererade raderna i en lista skarmen inte visade -> tomt.
Veckoplanen fyller nu ALLA slots (stegvis fallback, inga tomma dagar),
undviker tva soppor/samma kok i rad och styr soppor mot lunch (inte
middag). Default lunch+middag varje dag. Plan-atgarder: 'Jag lagade
detta' bara ratt dag; 'Hoppa over' ersatt med 'Ta bort' (ny DELETE
/v1/week-plans/:id/entries/:entryId). Verifierat mot 393 recept:
14/14 slots fyllda, 0 upprepningar, 0 soppor pa middag.
Ny 'swap'-vy i rekommendationsmotorn med lag tackningsvikt (30->6) sa
betyg/smak/ratt maltidstyp styr i stallet for 'har hemma'. Byt rätt-
skarmen anropar view=swap, kringgar vardags-tidsgransen och hojer limit
till 20. Loser: bara ~5 val vid byte.
Utokar kock-katalogen fran 10 -> 40 recept (3-5 per kock): Gordon Ramsay,
Jamie Oliver, Nigella Lawson, Yotam Ottolenghi, Marcus Samuelsson, Giada
De Laurentiis, Emeril Lagasse, Ina Garten, Raymond Blanc, Rick Stein.
Kanda ratter (shepherd's pie, sticky toffee, shakshuka, doro wat, svenska
kottbullar, jambalaya, coq au vin, ratatouille, creme brulee, fiskcurry,
moules mariniere m.fl.) - EGNA nyskrivna formuleringar, diskret krediterade
via creatorDisplayName. Ligger bland ovriga recept, lyder diet-/allergi-
filter, sokbara pa kockens namn (aven felstavat via fuzzy-soket).
Verifierat: alla ids finns, alla enheter berakningsbara, seed gron (377
recept), typecheck gron, allergener determiniskt harledda (t.ex.
moules -> blotdjur+mjolk), alla publicerade.
Ny knapp 'Skicka in eget recept' i Hem, direkt under 'Dina sparade
recept' (samma kort-stil). Ny skarm submit-recipe: enkel mall (titel +
ingredienser med mangd/gram/kilo + tillagning). Skickas som fritext ->
AAMOS strukturerar -> workern AI-granskar, dubblettkollar, finskriver
och auto-publicerar, markt med anvandarens namn.
Hanterar 402/PREMIUM_REQUIRED snyggt (egna recept ingar i Premium/trial;
gratisnivan ser uppgraderingsvy i stallet for ratt fel). Backend fanns
redan (POST /v1/recipes + STRUCTURE_RECIPE_TEXT).
QR/streckkod ar nu ett rent informationsflode: skanna for att SE vad
produkten innehaller. Panelen visar full naring per 100 g (energi,
fett/mattat, kolhydrat/socker, fiber, protein, salt), allergener,
'kan innehalla spar av', ingredienslista (Innehall) och kalla. Ingen
'lagg till'-knapp langre.
Buggfix: kameran triggar onBarcodeScanned manga ggr/sek och state-
flaggorna uppdaterades asynkront -> parallella uppslag staplade tva
Alert-rutor (okand forst, produkten bakom -> syntes forst efter Avbryt).
Nu synkront ref-las + panel i stallet for Alert.
CATEGORY_TO_SECTION saknade dessa kategorier, sa varorna hamnade under
'Ovrigt'. Nu: bakning+krydda -> Kryddor & bakning, chark -> Chark,
skaldjur -> Fisk & skaldjur, dryck -> Dryck. Fixar aven aldre varor
(t.ex. julskinka/chark) som redan fanns men sorterades fel.
Publiceringsflodet for anvandarinskickade recept gar nu hela vagen
automatiskt: submitted -> AI-granskning -> dubblettkontroll -> published.
Bara AI-underkanda eller exakta dubbletter (jaccard >= 0.9) stoppas.
Tidigare hamnade allt i in_moderation for manuell granskning.
Felstavade kocknamn hittar ratt kock: aliaslista (remsey/ramsey -> Gordon
Ramsay) + trigram word_similarity (ramzay/otolengi). Ger nolltraffar ett
'Menade du <term>?'-forslag (tappbart) mot titlar, kocknamn, ingredienser.
Egna formuleringar av kanda signaturratter (Ramsay, Oliver, Lawson, Ottolenghi,
Samuelsson, De Laurentiis, Lagasse, Garten, Blanc, Stein). Ligger bland alla
andra recept, samma kort/vyer/filter; diskret 'Kalla: <kock>' via
creatorDisplayName, ingen flik/badge. Sokbara pa kocknamn.
Soket matchar nu aven hogtidsnamn (julafton -> julmat), ingredienser (lax ->
alla laxrecept) och kocknamn (ramsay -> Gordon-recept), utover titel/trigram.
Fortfarande inga falska traffar (pannkakor ger bara pannkakor).
Bekraftade kvittovaror far sitt netto-pris (efter rabatt) i lagret. Prisupp-
skattningar anvander nu ett robust marknadssnitt: median av observerade pris/kg
fran lagret, klampat mot schablonen och viktat efter antal observationer -> ett
'realtidsnara' pris dar en extremt dyr/billig butik inte drar ivag snittet.
Gemini laste kvittot korrekt men resultatet ('lines') slangdes bort: hela
bekraftelseflodet (app scan-review + API extractProposals/annotate) forvantar
sig 'items' i foto-format. Darfor blev VARJE kvitto tomt. Mappar nu icke-
rabattrader till items och kor samma kanoniska namnmatchning som for foton.
ScoredRecommendation som rankAll returnerar bar inte ratingAverage/ratingCount,
sa svaret till mobilen saknade dem helt -> stjarnorna syntes aldrig aven efter
satt betyg. Aterkopplar nu betyg per recept fran kandidaterna i svaret.
getReactNativePersistence/AsyncStorage finns inte i webb-bygget (react-native-
web) och gav 'Cannot read properties of undefined (reading bind)' vid start.
Pa webben anvands nu Firebases standard-webblagring (getAuth), pa native
AsyncStorage som forr. Gor att webbversionen kan koras for felsokning.
Varor som lades till via recept/manuellt fick alla sortOrder=0. GET-listan
sorterade pa (sektion, sortOrder) utan stabil brytare, sa nar en rad bockades
av (UPDATE) kastades ordningen om - varorna hoppade. Nu: id som sista
sorteringsnyckel (total, deterministisk ordning) + nya varor far nasta
sortOrder sa de laggs sist.
Receptnamnet ska beskriva rätten, inte förvaringen. Skolstart-/matlåde-
kopplingen ligger kvar i taggar (skolstart, meal_prep) och beskrivningen.
Slug oförändrad så omseedning uppdaterar receptet på plats.
Buggen: när användaren uttryckligen valde en högtid (t.ex. Kräftskiva), en
tagg (Baka) eller sökte, hårdfiltrerade scoreCandidate bort alla recept vars
totalTimeMinutes översteg hushållets maxCookingMinutesWeekday (parts.time=-1,
rankAll släpper <0). De smala högtidspoolerna kollapsade då till 0-1 recept
trots att flera fanns korrekt taggade.
Reproducerat mot riktig seedad databas: med en 20-min vardagsgräns gav
kräftskiva 2, grillsäsong 2, skolstart 0, bak nästan tomt. Med fixen ger de
4, 5, 3 respektive 18 – medan standardvyn "Rekommenderat" fortfarande
respekterar tidsgränsen (3 snabba middagar).
Fix: uttrycklig avsikt (holiday/tag/search) förbigår vardagens tidsgräns –
tiden blir mjuk rankning i stället för hårt filter. En uttrycklig q.maxMinutes
i förfrågan respekteras fortfarande. Regressionstest låser mekanismen.
Ratta slug-bugg: recept-taggen "grillsäsong" matchade aldrig event-sluggen
"grillsasong" (ASCII) sa grillsäsong-knappen visade inget. Nu ratt.
15 nya hogtidsrecept taggade med exakt SE-event-slug: rodbetssallad, rodkal,
senapssill, stekt prinskorv, kokta kraftor med krondill, aioli, ostbricka,
farskpotatis med dill, agghalvor med rakror, rakcocktail, grillspett med
halloumi, grillad kycklingfile, pastasallad i matladan, tillbehor till
surstromming, kryddig kyckling med ris.
Omtaggar befintliga recept till ratt hogtid: vasterbottensostpaj +kraftskiva,
grekisk-sallad +grillsasong, chili/spaghetti +skolstart, chokladtarta
+alla-hjartans-dag, tomatsoppa +halloween, korvgratang +oktoberfest,
halloumiburgare +valborg.
Alla 14 SE-hogtider har nu minst ett korrekt taggat recept. Naring och
enheter ar berakningsbara for alla 74 extrarecept (invarianttest gront,
repo-typecheck gront).
Kvitto-skanning (rapporterad krasch 'svar matchar inte schema … invalid value'):
- AI-skan-enheter (kvitto/kyl/maltid) normaliseras nu fore validering:
'st'->COUNT, 'kg'->KILOGRAM, 'forp'/'pase'->PACKAGE osv. Okand enhet -> null
i stallet for att falla hela svaret. Skarpt kvitto-prompt med exakt enhetslista.
17 nya tester bevisar normaliseringen.
Sok pa 'Vad ska vi ata':
- Endast TITELN (inte beskrivningen) -> 'pannkaka' ger inte langre appelkompott
(som bara namnde pannkakor i beskrivningen).
- Stavningstolerant via trigram-similarity: 'pankakor' hittar pannkakor.
Hogtidsknapparna (kraftskiva/grill/jul ...):
- Filtrerar nu pa recept-holidayTag (slug) i stallet for en titelsok som gav
tomt. Har event inga recept an visas ett arligt tomt-lage.
Full typecheck gron, ai-contracts 24 tester grona.
- Sok fungerar nu: what-to-eat tar ?search= och filtrerar recept pa titel/
beskrivning BLAND ALLA recept (t.ex. 'pannkaka' hittar pannkakor), oavsett
vald flik. Sokrutan skickar nu search i stallet for craving.
- Hogtids-/sasongsknapparna (kraftskiva, grill, skolstart) ligger nu direkt
UNDER sokrutan, inte nere bland recept-forslagen.
- Saffransbullar + lussekatter ur 'Frukost' (mealTypes dessert+breakfast ->
dessert). Bakverk hor inte till frukost i Sverige.
- Bort med 'Alla recept & sok'-lanken pa forstasidan och 'Bladdra bland recept'
pa Hemma - allt nas nu via flikarna/soket pa 'Vad ska vi ata'.
Full typecheck gron.
Alla kategori-flikar anvander nu SAMMA rekommendations-motor (what-to-eat)
som 'Rekommenderat', sa vyn blir identisk overallt:
- sok fungerar i alla flikar, %-hemma och stjarnor visas, samma kort-layout,
och samma paginering med 'Visa fler' (5 at gangen).
- Backend: what-to-eat tar nu valfri ?tag= (Baka-fliken filtrerar pa 'baking'
i stallet for maltidstyp; mealType styr bara poangsattningen).
- Enhetliga chip-rutor: Button far en style-prop, flikarna ligger i 2 kolumner
med lika bred ruta (48%), centrerad text som krymper vid behov.
- 'Toppval' visas bara pa forsta sidan. 'Alla recept & sok' kvar som lank.
Full typecheck 20/20.
- KRITISKT: what-to-eat-anropet hade limit=30 men schemat tillater max 20
-> 400 Bad Request -> tom sida med 'nagot gick fel'. Det var alltsa INTE
uppkopplingen. Andrat till limit=20.
- Kategori-flikarna (Frukost/Lunch/Middag/Mellanmal/Efterratt/Baka) filtrerar
nu recepten PA SAMMA sida i stallet for att navigera till bladdra-vyn.
'Rekommenderat' visar de personliga forslagen som forut.
- ErrorView visar nu riktig HTTP-status (t.ex. [400]) sa fel gar att diagnosa.
- '/recipes' finns kvar via 'Alla recept & sok' for full bladdring + sok.
Mobil typecheck gron.
- Inkopslista /complete: kopte (markerade) varor laggs i lagret OCH tas bort
ur listan; OMARKERADE varor blir kvar (handla i flera butiker). Listan
arkiveras forst nar den ar tom. Tidigare markerades HELA listan completed
sa allt forsvann.
- Ny radera-knapp (x) per vara med bekraftelse - ta bort nagot man angrat
utan att kopa det (DELETE-endpointen fanns redan).
- Bort med '✓ plattformen'-taggen pa recept + bladdra (satt pa nastan alla
editorial-recept och sag efterblivet ut). Namn visas fortfarande bara for
anvandarskapade recept (creatorDisplayName).
Typecheck: api + mobil gron.
Kategorisering (din notis - bakverk hor till Baka, inte mellanmal):
- Sub-typer bread/bun/pie/cake/cookie i RECIPE_TAGS.
- Bullar/kakor/pajer/chokladbollar -> dessert (inte snack) + sub-tagg; brod
-> breakfast. Befintliga lussekatter/saffransbullar taggas 'bun'.
- Browse: sub-chips under Baka (Brod/Bullar/Paj/Tartor & kakor/Smakakor).
Bladdra pa forstasidan (din onskan):
- Kategori-genvagar pa 'Vad ska vi ata' -> oppnar bladdraren forvald
(/recipes?cat=). recipes.tsx laser ?cat=.
Relevantare 'Vad ska vi ata' (snurrar samma triviala):
- view=pantry -> view=default (tackning vager tungt men inte allenaradande,
ger variation), limit 15 -> 30 (storre pool sa 'Visa fler' upprepar senare).
Felsokning inkopslista:
- Tydligare felmeddelande (HTTP-status vs natverksfel) sa root cause syns.
Full typecheck 20/20, invariant-test gront.
- Ny 'baking'-tagg (RECIPE_TAGS, text[] - ingen migration). Browse-vyn far
en 'Baka'-chip som filtrerar pa taggen; befintliga lussekatter +
saffransbullar taggas ocksa.
- extra-recipes.ts: 16 nya recept som fyller de glesa kategorierna -
4 bak (kanelbullar, kardemummabullar, appelsmulpaj, frukostfrallor),
3 frukost, 3 mellanmal (tomma kategorin -> fylld), 3 efterratt, 3 lunch.
- Endast verifierade canonical-ingredienser + berakningsbara enheter, sa
seed harleder narings-/allergendata utan att krascha (run.ts 675/691).
- Nytt rent invariant-test (ingen DB) kor riktiga computeRecipeNutrition pa
alla 16: id:n finns, naring berakningsbar, inga slug-krockar. 5 tester grona.
- Seed ar additiv (onConflictDoUpdate) - 'pnpm db:seed' lagger till + taggar
om utan dataforlust. Full typecheck 20/20.
- Ny skarm /recipes: kategori-chips (Alla/Frukost/Lunch/Middag/Mellanmal/
Efterratt) + sok. Backend: befintliga GET /v1/recipes (mealType, search).
- Kategorierna ar de RIKTIGA MEAL_TYPES (1:1 mot datan) - inga pahittade
filter. Etiketter ateranvander myday.mealType.* (redan 12 sprak).
- Tomma kategorier visar arligt tomt-lage (katalogen ar idag middagstung:
~240 middag, 8 frukost, 3 efterratt, 0 mellanmal) i stallet for att gommas.
- Ingang fran hemskarmen bredvid Sparade recept. Query-strang byggs som
resten av appen (template + encodeURIComponent).
- Ingen ny tabb (baren har redan 5). Mobil typecheck gron.