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).
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.
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).
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.
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}.
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.
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
- Nya toppnivåblock i /ops/v1/summary: ai_scan, aktivering, engagemang,
betalning, jobb, sakerhet. Alla värden läses från DB/cache; null där data
saknas, inga påhittade värden.
- AI-kostnad i USD mikrocent (native); intäkter fortsatt SEK-öre.
- product_analytics_events är källa för volym, latens, lyckandegrad,
felfrekvens, aktivering, retention och engagemang.
- Nya händelser: scan_started (API) och scan_failed/scan_completed med
latencyMs + felkod (worker). latencyMs flödar nu in i scan_completed.
- Safety canary-jobb varje timme: re-härleder allergener för alla recept,
räknar överifierade publika recept och food-safety-lint; skriver EN rad till
ops_safety_canary. Endpointen läser endast sista raden.
- Cache-refresh-jobb var 60 s skriver hela summariet till Redis; endpointen
serverar cachen med 503 vid cache-miss.
- Bearer-token-skydd med OPS_TOKEN; HTTPS-tvång i produktion; ingen PII.
- Tester för endpoint, auth, cache-miss och safety canary.
- confirm-loop sparar nu även action=accept som positivt exempel i ai_corrections
- imageS3Key sparas vid image_training-samtycke, annars null
- ai_corrections.proposal lagrar det specifika AI-förslaget per item
- BUILD_TRAINING_SAMPLE bankar lokalt till ai_training_bank (ej externt runTask)
- Jobbet kastar aldrig i AAMOS_MODE=gemini
- Migration 0020: ai_corrections.image_s3_key/proposal + ai_training_bank
- docs/28-lärande-loop.md: datakontrakt, samtycke, retention, GDPR-radering
- Tester: accept + bildref (ja/nej) + lokal bank i gemini-läge
- REQUIRE_REAL=1 är AI-fokuserat i gemini-läge; staging mail/S3 får vara mock