# 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                            |
