Commit Graph

238 Commits

Author SHA1 Message Date
Claude 55b03b5039 feat(kvot): debitera AI-skanning PER BILD + fixa dubbeldebitering
Johans beslut: en skanning debiteras per bild (6 foton = 6 skanningar), streckkod
gratis. consumeAiScan tar nu units=imageCount och kollar att hela ryms.
Refunden ger tillbaka lika manga (antal bilder) vid misslyckat jobb. Appen kapar
antalet foton till kvarvarande kvot och gar till paywall om 0 (servern ar dock
den slutgiltiga grinden).

Hittade + fixade en PRE-EXISTING bugg pa vagen: kvoten drogs bade vid skapande
(consumeAiScan) OCH vid slutford analys (recordAiUsage aiScans:1) -> varje LYCKAD
skanning kostade 2 enheter, dolt av att appen bara uppdaterade raknaren vid start.
Nu dras kvoten exakt en gang, vid skapandet. Enbildsanvandare far alltsa nu sina
fulla 5 gratis-skanningar (var tidigare ~2,5).
2026-08-18 21:13:58 +00:00
Claude 3bb1d309bc feat(skann): flera bilder i EN skanning for kyl/frys/skafferi/ingredienser
Mobilen hardkodade imageCount:1. Nu kan man ta flera vinklar av samma plats i
en och samma skanning (kamera: ta en till mellan varje; galleri: flerval, tak 6
= schemats max). Worker skickade redan alla bilder till modellen tillsammans och
prompten sager "lista varje vara en gang", sa modellen dedupar over bilderna;
scan-review-markeringen fangar residual. En skanning = en kvotenhet oavsett
antal bilder. Enkel-typer (tallrik/kvitto/datum) tar fortf. en bild.
2026-08-18 20:25:49 +00:00
Claude ee5eb32e09 chore(modell): rikta ALLT mot gemini-3.1-flash-lite + fixa kostnadsberakning
Koden/docs pastod overallt gemini-3.5-flash-lite fast .env kor 3.1. Nu enhetligt
3.1 i .env.example, config.ts-default, gemini.ts-default, tester, eval och docs
(09 + 10). Dessutom en RIKTIG bugg: estimateCostUsd rakna pa 3.5-priser
($0,30/$2,50) medan vi kor 3.1 -> overskattade spend och troffade budgetlarmet
for tidigt. Nu 3.1-priser ($0,25/$1,50). docs/10 helt omraknad pa 3.1 (per
uppgift, per anvandare, skala, 100k-trial-scenariot). Referenslinje kvar som
visar 3.5-priset for att motivera valet.
2026-08-18 20:16:37 +00:00
Claude 7c06516e1e fix(skann): finetune dubblett – ta aldrig bort automatiskt, jamfor ej inom samma foto
Johans test visade tva falska positiva: 3:e smetana pa annan hylla forsvann,
och 2 olika gradde i EN bild -> bara en rakna, andra bortrensad. Orsak: (1)
auto-avmarkering tog bort riktiga varor, (2) varor jamfordes mot varandra inom
samma foto. Fix: markera men ta ALDRIG bort automatiskt (rejected=false, du
valjer); jamfor bara inom samma skanning nar det finns FLERA foton (overlapp),
aldrig tva behallare i ett och samma foto. Verifierat mot alla tre fallen.
2026-08-18 19:19:04 +00:00
Claude 2aaa7f9b3f feat(skann): markera troliga dubbletter i granskningen innan bekraftelse
Enligt Johans onskan: appen forstar sjalv nar en vara troligen redan finns
(samma katalog-id ELLER liknande namn, aven om AI:n laser den olika fran en
annan vinkel) och markerar den i skann-granskningen. Hog sakerhet (>=0.7) =
avmarkerad som standard men syns tydligt och gar att angra; lagre = markerad
men kvar sa du valjer. Jamfor bade mot aktivt lager och tidigare varor i samma
skanning. Ingen auto-hopslagning utan bekraftelse (spec 9). GET /v1/scans/:id
annoterar varje forslag med possibleDuplicate {name, reason, score}.
2026-08-18 18:57:18 +00:00
Claude b24b987d29 fix(skann): begripliga mangder – vikt/volym annars antal, aldrig "0,6 paket"
Prompten bad modellen uppskatta *andel av en forpackning* (0.0-1.0), vilket gav
nonsens som "keso 0,8 paket", "smetana 0,6 paket", "matrester 0,5 paket". Ny
ordning enligt Johans onskan: 1) las vikt/volym om den syns (500 g, 4 dl) 2)
annars rakna hela forpackningar som heltal + "st" 3) oppnad vara: uppskatta
kvarvarande i dl/g 4) vet ej -> 1 st. Aldrig decimaler av paket. La ocksa till
regel: samma vara i flera foton listas EN gang. promptVersion -> gemini-fridge-v4.
2026-08-18 18:44:36 +00:00
Claude c72c7ec25a fix(skann): dubblett-koll aven inom samma foto (intra-batch)
Tva traffar pa samma vara i ETT foto (t.ex. "helmjolk 4dl" + "helmjolk 8dl")
dubbellagrades, eftersom activeItems hamtades en gang fore loopen och nyss
inlagda varor inte lades tillbaka. Nu pushas varje inlagd vara till
activeItems sa resten av batchen slar ihop mot den. Cross-scan-dedup fanns
redan; det har tacker fallet inom samma bild.
2026-08-18 17:48:01 +00:00
Claude 1df3943d29 fix(recept): uppdatera "Vad ska vi ata?" automatiskt nar lagret andras
Nar man raderade varor i Matlager uppdaterades inte receptforslagen (coverage
stod kvar pa t.ex. 50% tills man tvang-reloadade appen). Orsak: radering
invaliderade inte ["what-to-eat"]-cachen. Cooking + scan-review gjorde redan
detta; nu foljer kitchen (radering), barcode, meal-boxes och shopping samma
monster sa forslagen alltid speglar aktuellt lager.
2026-08-18 16:28:31 +00:00
Claude 3942890d6f fix(matlager): stada upp – flytta lager till egen vy, gruppera per plats, fixa limit-bugg
- BUGG: kitchen hamtade ?limit=500 men schemat tillat max 200 -> 400-fel nar man
  gick in i matlager / tryckte "+N till". Hojer inventoryQuerySchema.limit till 500.
- Hem: tar bort den roriga inline-listan (matlager lag kvar under Hemma). Ersatts
  med ett "Matlager"-kort med genvagsknappar per plats (Kyl/Frys/Skafferi) + "Allt".
- Matlager-skarmen: grupperad per plats med rubrik + antal, sorterad pa namn,
  plats-filter via chips ELLER djuplank (?loc=), sok, markera flera, massradering.
- Byter skarmtitel "Ditt kok" -> "Matlager".
- Fixar aven en latent hooks-ordningsbugg i home (useFocusEffect efter early return).
2026-08-18 16:02:57 +00:00
Claude 610910ccf0 feat(inventory): matlager-hantering – sök, plats-filter, markera flera, massradering
- API: POST /v1/inventory/bulk-delete (mjuk radering, ägar-kontroll, correction-tx)
- Mobil: "Ditt kök" görs om till hanteringsvy – sök, filter Kyl/Frys/Skafferi,
  sortering på plats+namn, markera flera (som mejlklient), Ta bort valda / Töm listan
- Hem: "+N till" blir klickbar och tar dig till Ditt kök
2026-08-18 15:22:59 +00:00
Claude 684743ae95 fix(inventory): robustare dedup vid skann + borttag pa startsidan
Dedup vid /v1/scans/:id/confirm matchade bara pa exakt (skiftlageskansligt)
namn eller identiskt katalog-id, sa omfotografering av samma hylla skapade
dubbletter. Ny normalizeItemName (gemener, accenter, storlek bort; behaller
fetthalt-siffror) + matchning pa katalog-id ELLER normaliserat namn mot
aktivt hushallslager.

Mobil: 'Ta bort' fanns bara i Ditt kok. Lade borttag pa startsidans
lager-rader (befintlig DELETE /v1/inventory/items/:id).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WZdew6cWn1MeHqoYWFfxzo
2026-08-18 14:44:03 +00:00
Claude 4ca567bba3 fix(ai): balansera datum-prompt – tolka datum med dagens datum som kontext
Forra andringen blev for strikt: modellen nollade ALLA datum eftersom svenska
stamplar (DDMMYY/YYMMDD) alltid ar "tvetydiga". Nu far modellen dagens datum
och tolkar 2-siffriga artal som narmaste rimliga ar runt idag (04-09-26 ->
2026-09-04, inte 2024). Kod-sparren isPlausibleFoodDate star kvar som skydd mot
grova fel. promptVersion -> gemini-fridge-v3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WZdew6cWn1MeHqoYWFfxzo
2026-08-18 11:42:30 +00:00
Claude 5cf9f8ab0d fix(ai): las aldrig gissade utgangsdatum – skarpt prompt + rimlighetssparr
Gemini gissade fel artal pa kryptiska tryckstamplar (t.ex. "2024" pa en farsk
gradde) vilket kan trigga falska "utgangen"-varningar. Tva lager:
- Prompt: modellen far aldrig gissa artal, returnerar null vid tvetydiga/
  kryptiska koder (buildFridgePrompt + buildExpiryPrompt).
- Kod: ny isPlausibleFoodDate() nollar orimligt gamla/framtida datum i
  toDetectedItems. Hellre inget datum an ett felaktigt (spec §13).
promptVersion -> gemini-fridge-v2. Tester 7/7 grona.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WZdew6cWn1MeHqoYWFfxzo
2026-08-18 11:29:11 +00:00
Claude e66d9aee72 fix(inventory): sluta gissa utgangsdatum + las 2-siffriga bast-fore-stamplar
CI / Typecheck, test & build (push) Failing after 46s
BUG: forseglad vara utan tryckt datum fick fabricerat utgang (purchasedAt + shelfLifeGuidance, som ar hallbarhet EFTER oppning) -> falska 'gar ut snart'-varningar OCH gav sken av att datum inte lastes. Nu: ingen data -> unknown (hedrar appens egen princip 'aldrig gissa'). parseDate laser aven YY-MM-DD/YYMMDD/YYYYMMDD (svenska stamplar) som forr slangdes. Regressionstester tillagda. 36/36 gront.
2026-08-17 19:22:54 +00:00
Claude 3ed12b274d docs(09): modell 2.5 Flash -> 3.5 Flash Lite (matcha koden)
Arkitekturdoc sa fortfarande Gemini 2.5 Flash; koden kor gemini-3.5-flash-lite. ASCII-boxen forkortad till 3.5 Flash for att halla radbredden. scale-batch.sh RORDES EJ (medvetet val?).
2026-08-17 18:44:43 +00:00
Claude 0ff3396d6e fix(cost): korrekt Gemini 3.5 Flash Lite priser i kod + docs
gemini.ts estimateCostUsd: 2.5-Flash-priser (0.075/0.30) -> 3.5-Flash-Lite standard (0.30/2.50). Pessimistiska per-bild-estimat 0.0015->0.004, OCR 0.001->0.002. docs/10: Claude-modelltabell + kostnad-per-uppgift omskrivna till Gemini. 36/36 gront.
2026-08-17 18:41:45 +00:00
Claude ecc3c6395e docs(kostnad): korrekt modell Gemini 3.5 Flash Lite ($0,30/$2,50), rakna om ~3,3x lagre
Kontrollerat mot koden: GEMINI_MODEL=gemini-3.5-flash-lite. Rattelseblock overst, per-skanning $0,01->$0,003, per-user + skala + 100k-scenario omraknat. Flaggar att estimateCostUsd i koden anvander gamla 2.5-Flash-priser (underskattar ~4-8x).
2026-08-17 18:22:52 +00:00
Claude 8bf2647a9e docs(kostnad): rakna om for free=5 + kvoter 100/200/400, lagg till 100k trial-scenario
Gratis-raden 10->5 skanningar ($0,05). Family varsta fall 600->200 skann ($2,16). Skala-antagande gratis 6->5. Nytt scenario: 100k trial dag 1 = ~263k kr AI + Firebase 50k gratis/sen $0,0055 MAU.
2026-08-17 17:46:39 +00:00
Claude 75591bb294 fix(subscriptions): free-niva 5 AI-skanningar (beslut Johan)
Free 10->5 i kod, test, paywall-copy (12 sprak) och docs. Full trappa: free 5 / trial 14d 25 skann / premium 100/200/400.
2026-08-17 17:34:55 +00:00
Claude 97c913a25c docs: fair-use skankvoter 100/200/400 (matcha koden, ej 300/600/1000)
Beslut Johan: 100/200/400 racker val for betaltiers, hogre kan bara missbrukas. docs/13-subscriptions.md + docs/10-ai-kostnad.md. Koden (constants.ts) var redan ratt.
2026-08-17 17:19:12 +00:00
Claude 88876a24b7 fix(subscriptions): trial 14 dagar konsekvent i UI/docs/legal/butik
TRIAL_DAYS var redan 14 i koden men auth.trialNote (12 sprak), butiksmetadata, juridik-utkast, API-ref, exec-summary och UX-doc sa 7. Nu 14 overallt. Rorde EJ icke-trial 7-dagar (inbjudningslank, backup, S3-lifecycle, grace, retention). Beslut: Johan (battre onboarding).
2026-08-17 17:04:00 +00:00
Claude cacca3481c fix(subscriptions): free-niva 10 AI-skanningar/man (matcha paywall + spec §46)
Koden gav 5 men paywall-copy (12 sprak), butiksmetadata (docs/22) och subscriptions-testet sager 10. Enforcement (canUseAiScan) laser konstanten dynamiskt sa en rad racker. Beslut bekraftat av Johan: free=10.
2026-08-17 16:39:52 +00:00
Sven (AAMOS AI) 856b620891 fix(i18n): platta swap till punktnycklar + fyll paritetslucka (24 sv-nycklar) i 11 sprak, sv-fallback 2026-08-17 22:47:04 +07:00
Sven (AAMOS AI) 0478f7c930 feat(mobile): MIKRO WEEK-4b lägg swap-nycklar i 12 språkfiler 2026-08-17 21:57:40 +07:00
Sven (AAMOS AI) 375a951be1 feat(mobile): MIKRO WEEK-4 byt ut måltid i veckoplanen (swap-vy) 2026-08-17 21:50:18 +07:00
Sven (AAMOS AI) 6dcc404dc1 feat(mobile): MIKRO MEAL-2 tidsstyrd måltid i Vad ska vi äta 2026-08-17 21:41:59 +07:00
Sven (AAMOS AI) 6fe1955c9f feat(mobile): MIKRO POLISH-3 optimistisk favoritmarkering med rollback 2026-08-17 21:38:48 +07:00
Sven (AAMOS AI) 653f94de86 feat(mobile): MIKRO POLISH-2 cyklande laddningsmeddelanden på scan-väntan 2026-08-17 21:17:24 +07:00
Sven (AAMOS AI) b1a93be974 feat(mobile): MIKRO POLISH-1 haptik + tryck-skala i Button/Card 2026-08-17 21:01:09 +07:00
Sven (AAMOS AI) 260f816c83 feat(recommendations): MIKRO MEAL-1 måltids-lämplighet i rankningen (nedvikta frukost/dessert vid huvudmåltid) 2026-08-17 20:37:47 +07:00
Sven (AAMOS AI) 9473329708 feat(mobile): MIKRO STARS-3 byt mot Toppval-tagg på första förslaget 2026-08-17 20:13:54 +07:00
Sven (AAMOS AI) 343a18393a feat(mobile): MIKRO WEEK-3 interaktiv planera veckan-ruta (dagar x måltider) 2026-08-17 20:07:23 +07:00
Sven (AAMOS AI) 5a47140b76 feat(mobile): MIKRO STARS-2 visa snittbetyg på Vad ska vi äta-korten 2026-08-17 19:54:38 +07:00
Sven (AAMOS AI) ec0b64efe8 feat(recipes): MIKRO KRAM-1 variera Krämig-titlar (behåll ~4 genuint krämiga) 2026-08-17 19:34:42 +07:00
Sven (AAMOS AI) 97b5baa367 feat(weekplan): MIKRO WEEK-2 dagliga måltidsslots (vardag middag, helg lunch+middag) 2026-08-17 19:17:27 +07:00
Sven (AAMOS AI) 9777c2ff1b fix(api): round estimated shopping price to integer minor units 2026-08-16 22:49:09 +07:00
Sven (AAMOS AI) 8fe8900722 feat(mobile): week plan always starts today and moves forward 2026-08-16 22:36:22 +07:00
Sven (AAMOS AI) 05c6cf9e04 feat(mobile): refresh entitlements after scan + route QUOTA_EXCEEDED to paywall 2026-08-16 22:17:15 +07:00
Sven (AAMOS AI) baa5f6447a feat(worker): refund AI scan quota on definitive job failure + sanitize DLQ jobId 2026-08-16 21:43:19 +07:00
Sven (AAMOS AI) 305b6d1886 feat(seed): add aliases for milk, yoghurt, crème fraiche and carrot 2026-08-16 21:23:07 +07:00
Sven (AAMOS AI) 5ad6bf6f60 feat(seed): make sourdough bread and cardamom computable (gramsPerPiece/density) 2026-08-16 21:11:48 +07:00
Sven (AAMOS AI) 70021ebdf2 feat(seed): add pantry ingredients (balsamic, strawberry jam, fish/lobster stock, cornichons) + gramsPerPiece for dill/parsley 2026-08-16 21:01:08 +07:00
Sven (AAMOS AI) c0a15bb1b5 feat: kitchen screen, scan dedup, gemini-3.5-flash-lite, seed grapes/beetroot/pea shoots 2026-08-16 20:13:49 +07:00
Sven (AAMOS AI) d098bf705e feat(mobile): Sparade recept-sida (sökbar favoritlista) + länk på hemma (SAVED-1) 2026-08-16 00:55:32 +07:00
Sven (AAMOS AI) c2a8aa8fa1 feat(mobile): hemma-knapparnas skärmar som modaler (UX-3) 2026-08-16 00:38:55 +07:00
Sven (AAMOS AI) c115c3cb4b fix(mobile): enradiga snabblänks-etiketter + svep-tillbaka på hela sidan (UX-2) 2026-08-16 00:27:53 +07:00
Sven (AAMOS AI) 8035093ae5 feat(mobile): levande knappar – press-scale på Card + haptik på snabblänkar (UX-1) 2026-08-16 00:20:59 +07:00
Sven (AAMOS AI) bcd5f6d0db fix(mobile): montera inte om trädet när språket är oförändrat – bevarar nav-stacken (NAV-1) 2026-08-16 00:03:56 +07:00
Sven (AAMOS AI) 84a1606dd0 feat(mobile): glömt-lösenord via Firebase + upprepa-lösenord-fält (POLISH-2) 2026-08-15 23:20:32 +07:00
Sven (AAMOS AI) 448a523d64 fix(mobile): logga ut ur Firebase vid utloggning (POLISH-1) 2026-08-15 23:02:30 +07:00