# Beslutslogg – låsta beslut med motivering > Beslut refereras löpande i respektive dokument (arkitektur, subscriptions, > säkerhet, i18n). Här samlas de centralt. Nummerserien är stabil – återanvänd > aldrig ett nummer. | # | Beslut | Motivering | Var det syns | | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | D-011 | Zod-validering via central `parse()`-hjälpare i stället för Fastify type-provider | Full kontroll över felformatet (VALIDATION_ERROR + correlationId) och samma mönster i alla routes | `apps/api/src/lib/errors.ts` | | D-014 | Ingen hälso-/kostdata till reklam; inga annons-SDK:er i appen | Policybeslut (spec §56): förtroende är produktens kärna | docs/12 | | D-021 | Val av butiksbibliotek i mobilen (StoreKit2/expo-iap) skjuts till fas 7 | Backend-verifieringen är kontraktet; klientbiblioteket kan väljas när butikskonton finns | docs/13 | | D-023 | Interims-t() byggdes namespace-format ("home._", "scan._") för mekanisk flytt till i18next | Undvika total omskrivning i M4 – flytten blev ren datamigrering av nycklar | docs/20, M4 | | D-024 | Adminpanelen förblir svensk tills internationell ops finns | Internverktyg; nyckel-migrering (M9) kostar mer än den ger före internationell drift | docs/20 | | D-025 | i18next med inbyggd Intl.PluralRules-plural (`_one`/`_other`) i stället för ICU-tilläggspaket | Samma korrekthet för våra språk utan extra runtime-beroende; ICU-syntax kan läggas till per-nyckel senare om behov uppstår | `apps/mobile/src/lib/i18n.ts`, M4 | | D-026 | Varumärket är ENDAST konfiguration: neutrala platshållare i `brand.config.json` tills namnet beslutas; git-historiken tillplattad så inget arbetsnamn förekommer någonstans | Namnet är inte beslutat; ett byte ska vara en enradsändring, inte en kodsanering. Extern historik-backup finns utanför repot | brand.config.json, docs/namnbyte.md | | D-027 | Översättningar är RADER per språk (aldrig kolumner), svensk källtext är sanningen, endast `status=published` serveras användare; AI-utkast verifieras deterministiskt (stegantal, bevarade tal, konfidens) före mänsklig publicering | Skalar till godtyckligt många språk utan schemaändring; AI kan aldrig tyst ändra mängder/struktur (spec §61.1) | packages/database/schema/translations.ts, worker/translation.ts, M2–M3 | | D-028 | Katalogpriser (ingredienser, receptkostnad, inköpsuppskattningar) ligger i basvaluta SEK tills M8 inför per-marknadspriser; hushållets `currency_code` styr användarens egna belopp | Undviker låtsas-valutakonvertering utan riktiga växelkurser – ärlighet före skenprecision | schema/ingredients.ts, routes/shopping.ts, M1 | | D-029 | Måttvisning konverterar ALDRIG lagrade värden: kanoniskt värde är sanning, `displayQuantity` räknar fram visning per måttsystem och märker konverterade värden med ≈ | Förlustfrihet (i18n-spec §30) + ärlig osäkerhet (spec §61.4) | shared-types/measurement.ts, M5 | | D-030 | Marknadsprofiler (nutrition/allergener) styr endast VISNING – användarens personliga allergisäkerhet filtrerar alltid, oavsett marknad | En marknadsregel får aldrig försvaga en säkerhetsspärr (spec §61.2) | schema/markets.ts, M6 | | D-031 | Språkpolicy: (1) första start → enhetens språk om stött, (2) ostött → engelska, (3) manuellt val i profilen vinner alltid och synkas till backend; registreringen bär enhetens locale så att välkomstmejl + preferenser är rätt från första sekunden | Spanjoren som laddar ner appen får spanska automatiskt; spanjoren i Sverige väljer själv. Nytt språk = en JSON-fil + SUPPORTED_LANGUAGES-rad + seed-rader (paritet testvaktad) | apps/mobile/src/lib/i18n.ts, routes/auth.ts, D-031-tester | | D-032 | Första utgåvans språk: sv, en, es, it, de, fr, da, nb, fi, nl, pl, pt (Norden + de stora EU-marknaderna + engelska). Norska varianter (no/nn) mappas till nb. Fler EU-språk läggs till efter behov via språkmallen | Täcker spec-fasernas lanseringsmarknader (Norden→EU→UK/US/CA) med korrekt pluralhantering (polskans one/few/many). Seed-översättningar är AI-skrivna – native-granskning före lansering står i runbooken | locales/, D-031/D-032-tester, seed | | D-033 | UTC-kalenderpolicy: alla deterministiska motorer och API:ts server-side-datummatte räknar i UTC (`Date.UTC`/`getUTC*`, datumsträngar tolkas `T00:00:00Z`); tester skrivs med UTC-datum och verifieras under flera tidszoner | Fältfynd från första OpenClaw-deployen: två tester var tidszonkänsliga (lokal `new Date(y,m,d)` mot UTC-`toISOString`). Motorer ska ge identiskt resultat oavsett serverns TZ – och UTC saknar sommartid | inventory-engine/expiry.ts, recommendation-engine/season.ts, budget.ts | | D-034 | Docker är valfritt i first-deploy: Grind 0 noterar bara om docker finns; Grind 2 avgör på faktisk nåbarhet (Postgres via pg-klient, Redis via rå TCP-PING) och använder Docker enbart som reservstart i staging | Fältfynd: WSL-värd utan Docker tvingade agenten bygga ett docker-shim trots att native Postgres/Redis fungerade perfekt. Nåbarhet är sanningen, inte verktygslistan | infrastructure/deployment/first-deploy.sh, OPENCLAW-DEPLOY-PROMPT.md | | D-035 | Mjölkprincipen: passerat "bäst före" är en KVALITETSsignal (status expiring + pastBestBefore, aldrig expired; FEFO räddar den FÖRST; täckning räknar den som tillgänglig; UI säger "lukta och smaka"), medan "sista förbrukningsdag" är en hård säkerhetsgräns. Användaren väljer datumtyp vid skanningsgranskning | "Bara för att mjölken gick ut igår är den inte automatiskt dålig" – appen får varken döma ätbar mat (svinn) eller mjuka upp riktiga säkerhetsgränser (spec §13, §61.3). Ingen automatisk kassering finns någonstans | expiry.ts, fefo.ts, matching.ts, scan-review, home, mjölkprincip-tester | | D-036 | Inga hårdkodade UI-strängar: samtliga användarsynliga texter i mobilappen går via i18n-katalogen (svep 2026-08-05: ~130 nycklar flyttade ur 15 skärmar till alla 12 språk) | Testprotokollets löfte "byt språk → HELA appen byter direkt" ska vara sant bokstavligen; hårdkodade etikettkartor (mål, allergener, butikssektioner, måltidstyper, dialoger) bröt det | apps/mobile/src/app/_, locales/_/common.json |