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.
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.
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.
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.
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).
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.
- @app/storage med MockStorage + AwsStorage delas mellan API och worker
- Workerns readUrl() ger presignerad S3-URL i aws-läge (fixar mock-s3 404)
- sync-env-from-ssm.py hämtar /cibello/prod/* och skriver .env; first-deploy.sh kör det i prod
- /readyz returnerar 503 om app.aamos.healthCheck() misslyckas
- docs/SECRETS.md med rotations- och SSM-regler
- config.ts: tillåt AAMOS_MODE=http|gemini i prod; mock förbjudet
- first-deploy.sh: Grind 1 accepterar gemini (kräv GEMINI_API_KEY);
Grind 5 kör eval:scan mot gemini; Grind 8 behandlar gemini som riktig AI
- gemini.ts: stöd för data-URLer (inline base64-bilder) i fetchOneImage
- eval-fixtures: 4 lokala bilder (fridge-1, fridge-2, label-1, receipt-1)
- scan-eval.ts: läser lokala fixtures, inga externa hämtningar
- capture-eval.ts: använder lokal fixture som data-URL
- Utöka GeminiAamosClient med ANALYZE_MEAL_IMAGE, READ_NUTRITION_LABEL,
READ_EXPIRY_DATE och READ_RECEIPT (vision-prompts mot kontraktsscheman).
- Lägg till apps/worker/src/lib/shadow-capture.ts: S3/local fallback,
imageTraining-gating, ingen PII, aldrig faila användarvägen.
- Integrera capture i scan-processorn efter lyckad runTask med consentFlags.
- Lägg till @aws-sdk/client-s3 i worker samt eval:capture-skript.
- Uppdatera eval:scan till Wikimedia Special:FilePath + redirect-following.
- Exkludera .terraform i brand-guard för att undvika false positives.
- Uppdatera gemini-test för DEDUPLICATE_INVENTORY som unsupported.
- 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.
- processProactiveTips now iterates all expiring items sorted by urgency and
emits the first candidate with a recipe that clears 7-day dedup.
- Add pt-PT proactive-tip templates; remove en-GB duplicate; parity test
asserts against shared-types SUPPORTED_LANGUAGE_TAGS.
- Serialize DB test setup via turbo dependencies; seed truncates only *_test
DBs, guarded by both --test flag and DB name suffix.
- Ny notification_type 'proactive_tip' och consent_kind 'notifications'.
- Dubbelgrind: personalization + notifications samtycke måste vara granted.
- Mallbaserade pufftexter i 12 språk; ingen fri AI-text.
- Led med nyttan ('gurkan börjar bli slapp — recept du brukar gilla').
- Max 1 puff/hushåll/dag; ingen upprepning av samma vara+recept inom 7 dagar.
- UTC för all datummatte; createdAt sätts explicit från processorns now.
- Ny worker-jobbtyp SEND_PROACTIVE_TIPS.
- Integrationstester för dubbelgrind, revoke, frekvens, duplicate, UTC.
- Migration 0022 + worker test script kör db:test-setup.
- 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