fix(veckoplan+streckkod): byt ratt, planera om, variation, man-son + fota fram/bak

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).
This commit is contained in:
Claude
2026-08-20 13:45:35 +00:00
parent 2f596060b4
commit cac98b8dc7
18 changed files with 204 additions and 34 deletions
+5
View File
@@ -33,6 +33,11 @@
"barcode.contributing.title": "Leser av emballasjen…",
"barcode.contributing.body": "Vi henter næring, allergener og innhold og lagrer produktet i den delte katalogen, så den neste slipper å fotografere det.",
"barcode.contributing.failed": "Kunne ikke lese av emballasjen. Prøv igjen med et skarpt bilde og godt lys.",
"barcode.contributing.frontDone": "Forside tatt",
"barcode.contributing.backPrompt": "Ta nå bilde av baksiden med næringsinnhold og ingredienser da blir produktet komplett.",
"barcode.contributing.skipBack": "Ferdig, analyser",
"barcode.contributing.shootBack": "Ta bilde av baksiden",
"barcode.complete": "Ta bilde av baksiden (næring og innhold)",
"barcode.kcalPer100": "{kcal} kcal/100 g",
"barcode.needHousehold": "Du trenger en husstand først.",
"barcode.noLocation": "Fant ingen oppbevaringssteder.",