# Ändringslogg ## 2026-08-06 – testmiljö, analytics + namnbyte till Cibello - **Varumärke beslutat**: projektet heter från och med nu **Cibello**. - `brand.config.json` uppdaterad med namn, slug, bundle-ID, domäner och supportmejl. - `scripts/brand-guard.sh` uppdaterad: tidigare arbets-/platshållarnamn är förbjudna överallt utanför konfigurationen; `Cibello` tillåtet endast i `brand.config.json`. - Stale platshållare rensade ur docs och loggar. - `turbo.json`: test-tasken deklarerar `TEST_DATABASE_URL` i strict env-mode (`DATABASE_URL` tas bort därifrån; tester får inte längre använda den). - `packages/database/src/client.ts`: skärpt – tester läser **endast** `TEST_DATABASE_URL`; saknas den kastas ett tydligt fel. Dev/runtime använder `DATABASE_URL`. - Dedikerad testdatabas `cibello_test` skapad; `TEST_DATABASE_URL` lagd i `.env` och `.env.example`. `packages/database` test-skript migrerar automatiskt testdatabasen före varje körning (`tsx src/migrate.ts --test`). - **Buggrättning (kritisk):** `createDatabase()` var lägesberoende men föredrog ändå `TEST_DATABASE_URL` före `DATABASE_URL`. Åtgärdat så att runtime **endast** ser `DATABASE_URL` och tester **endast** ser `TEST_DATABASE_URL`. - `apps/worker/src/context.ts`: skickar nu `DATABASE_URL` explicit till `createDatabase()`, samma mönster som API:et. - `packages/database/src/migrate.ts` och `src/seed/run.ts`: stöd för `--test` / `MIGRATE_TARGET=test` / `SEED_TARGET=test`. Utan flagga används endast `DATABASE_URL` – deploy kan aldrig migrera/seed test-DB. - Driftsreparation: staging migrerad explicit, worker omstartad med ny build, expiry-notis skapad i staging-databasens `notifications`-tabell. Kontroll av `cibello_test` visade 0 worker-skrivna rader i `notifications` / `domain_events` / `inventory_items` / `households`. - Bevis: radantal i staging-databasen före/efter full `pnpm test` är identiska (users=6, households=0, household_members=0, product_analytics_events=0, user_consents=3). - Staging-databasen städad från testanvändare (4 st) och deras samtycken. - **Analytics tracker kopplad i mobilappen**: `AnalyticsProvider` initierar trackern i app-roten; events gate:as klientsidigt på `product_analytics`-samtycket och skickas inte vid opt-out. - Instrumenterade nyckelevents (spec §8.2): `onboarding_started`, `onboarding_step_completed`, `scan_started`, `scan_review_opened`, `recommendations_viewed`, `paywall_viewed`. - Känd v1-gräns dokumenterad: trackerns kö är endast in-memory; events som inte hunnit flushas förloras vid appomstart. - `pnpm typecheck`, `pnpm test`, `pnpm build` samt varumärkesvakt gröna. - Staging deployad om med nya namnet; healthz rapporterar `cibello-api`. ## 2026-08-05 – fältfynd åtgärdade + mjölkprincipen + i18n-svep Svar på första skarpa OpenClaw-deployen (WSL, alla grindar gröna) samt Johans princip om bäst före-datum: - **Tidszonsoberoende tester (D-033)**: de två TZ-känsliga testerna ur deployrapporten är fixade i grunden – inventory-engine (expiry) och recommendation-engine (season: påsk/midsommar/advent/årstider) räknar nu helt i UTC, liksom API:ts vecko-/månadsbudget och ålder/veckodag. Hela sviten verifierad under Europe/Stockholm, Pacific/Auckland och America/Los_Angeles (30/30 tasks utan cache i alla tre). TZ=UTC-workaround behövs inte längre. - **Docker valfritt (D-034)**: Grind 0 kräver inte längre docker – den noterar bara. Grind 2 avgör på faktisk nåbarhet och testar nu även Redis (rå TCP-PING) utöver Postgres; Docker används enbart som reservstart i staging. WSL/native-tjänster är en förstklassig väg (inga shims). Prompt uppdaterad. - **Mjölkprincipen (D-035)**: "gick ut igår ≠ dålig". Motorn hade grunden (bäst före → expiring + pastBestBefore, aldrig auto-expired; endast sista förbrukningsdag → expired). Nu förstärkt hela vägen: skanningsgranskningen låter användaren välja datumtyp (bäst före/sista förbrukningsdag → rätt kolumn), kontextnot förklarar kvalitet vs säkerhet, Hemma-fliken visar "lukta och smaka"-legend när något passerat bäst före, och nya tester låser beteendet: FEFO räddar passerade varor FÖRST (aldrig utesluter), täckningen räknar dem som tillgängliga, ingen automatisk kassering existerar. - **i18n-svep (D-036)**: ~130 hårdkodade svenska UI-strängar i 15 skärmar (onboarding-mål/dieter/allergener, butikssektioner, måltidstyper, samtyckesetiketter, roller, dialoger m.m.) flyttade till i18n-katalogen och översatta till alla 12 språk (1 564 nya strängar, paritetstestat, polska pluraler). "Byt språk → hela appen byter" gäller nu bokstavligen. ## 2026-08-04 – inga mockar i drift: riktig S3 + riktig SMTP + äkthetsgrind - Riktig S3-lagring (@aws-sdk/client-s3 + presigner): presignade upp-/ nedladdnings-URL:er mot AWS S3 eller S3-kompatibel lagring (S3_ENDPOINT för MinIO/R2). Bucket-hälsokontroll vid uppstart; produktion vägrar starta mot onåbar bucket. VERIFIERAD med äkta rundtur (presign→PUT→läs-URL→GET, byte-identiskt) och fullstack via API:t (fysisk fil i bucket). - Riktig SMTP (nodemailer): leverantörsoberoende (SES/Postmark/Resend/egen); okonfigurerad SMTP vägrar högljutt. VERIFIERAD med äkta nätverksrundtur och fullstack (välkomst- + återställningsmejl levererade till SMTP-server). Rättade även SMTP_SECURE-tolkningen ("false" blev true med z.coerce). - first-deploy.sh: INTEGRATIONSSTATUS i slututskriften + REQUIRE_REAL=1-grind som underkänner deployen om någon integration kör mock; riktiga värden kan ges som miljövariabler vid första körningen och skrivs in i .env. - OpenClaw-prompten: "PÅ RIKTIGT FRÅN START"-sektion med ifyllnadstabell + innehållsförteckning över vad zipen innehåller. ## 2026-08-04 – tolv språk (D-032) + deploy-paket för agentkörning - 6 nya språk: danska, norska (bokmål, no/nn mappas), finska, nederländska, polska (fullständiga one/few/many-pluraler), portugisiska → totalt 12. - 1111 ingrediensöversättningar (101 × 11 språk), 216 enhetsetiketter (12 språk), mejlmallar + minnesrubriker på alla 12, regiondefaults NL/PL/PT. - first-deploy.sh: idempotent helautomatisk uppsättning med 8 grindar (staging: genererade hemligheter + Docker-DB + seed; produktion: vägrar dev-värden, kräver AAMOS http, backup före migration, seedar aldrig). Körd skarpt i staging – alla grindar gröna. - OPENCLAW-DEPLOY-PROMPT.md: komplett agent-prompt med hårda regler, grindtabell, egen-verifiering, rapportformat, felsökningslista och rollback. ## 2026-08-04 – sex språk + automatisk språkdetektering (D-031) - UI på 6 språk: sv/en/es/it/de/fr – 200 nycklar per språk, paritetstestade, pluralformer per språk via Intl.PluralRules. - Automatik: enhetens språk vid första start (stött → det, ostött → engelska); registreringen bär enhetens locale → välkomstmejl OCH locale-preferenser (region, valuta, tidszon, måttsystem) rätt från första sekunden. - Manuellt språkval i profilen (6 språk, dynamisk väljare) vinner alltid och synkas till backend – mejl, notiser, innehåll och sök följer valet. - Innehåll: 505 ingrediensöversättningar (101 × 5 språk), 108 enhetsetiketter (18 × 6), mejlmallar och minnesrubriker på alla språk, regiondefaults ES/IT. - Receptöversättning till nya språk sker via M3-flödet (AAMOS-utkast → deterministisk verifiering → mänsklig publicering) – skalar utan kodändring. ## 2026-08-04 – "allt som kan göras klart är klart" - AAMOS-utvärderingssvit (spec §40): `pnpm eval:aamos`, 6 golden cases med 30 semantiska kontroller, resultat till ai_eval_runs, exitkod för CI-grind. - Admin-2FA: TOTP enligt RFC 6238 utan externa beroenden (testvektorer gröna), step-up-inloggning med preauth-token, MFA-tvång på admin-API, UI i panelen. - E-postverifiering: icke-blockerande, mallar sv/en, resend, deep link-skärm. - Retentionsjobb (GDPR): dagligt, konservativa fönster; larmwebhook för 5xx och fallerade jobb; backup-restore-övning skriptad och GENOMFÖRD (protokoll arkiverat). - Lasttest med trösklar: GODKÄND (recept 754 req/s p99 74 ms; rekommendationer 135 req/s p99 290 ms; 0 fel). - Lanseringsrunbook (docs/21), butiksmetadata-utkast sv/en (docs/22), juridiska utkast med juristkrav (docs/23), lasttestreferens (docs/24). ## 2026-08-04 – deploy-förberedelser - **Lösenordsåterställning**: komplett flöde (forgot → mejl → engångstoken → nytt lösenord) med anti-enumeration, hashade tokens, familjeåterkallelse, mejlmallar sv/en via utbytbar mailer, mobilskärmar + app-länk. E2E-verifierat inklusive säkerhetsegenskaperna (återanvänd token 401, gamla sessioner 401). - **CI-hårdning**: varumärkesvakt (scripts/brand-guard.sh), migrate+seed mot riktig Postgres 16 med sök-extensions, API-röktest i pipelinen. - **EAS**: byggprofiler (development/preview/production) förberedda – butiksfält fylls i när konto + namn finns. ## 2026-08-04 – i18n M1–M7 + M10 komplett, varumärkesneutralt - **M1 Pengar**: alla `*_sek`-kolumner → `*_minor` (integer, minor units); `households.currency_code` (ISO 4217); Money-typ + Intl-formattering i mobilen; planpriser och seed-priser i minor. Validering kräver heltal. - **M2 Översättningsdata**: `ingredient_translations` (en seedad ur nameEn), `unit_translations` (sv+en) + `GET /v1/i18n/units`; ingredienssök matchar och visar användarens språk. - **M3 Receptöversättning**: `recipe_translations` + `recipe_step_translations`; AAMOS-uppgift TRANSLATE_RECIPE; worker-verifiering (stegantal, bevarade tal, konfidens); adminflöde beställ → granska → publicera (med redaktionell rättning); API serverar publicerat språk med sv-fallback. - **M4 i18next**: locales/{sv,en}/common.json (175 nycklar, paritetstestade), Intl-plural, {brand}-injektion, språkbyte utan omstart, språkval i profilen synkat med backend-preferenser. - **M5 Måttvisning**: `displayQuantity` (METRIC/US_CUSTOMARY/MIXED) med kvartsavrundning och ≈-märkning; mobilen visar per användarens måttsystem. - **M6 Marknadsprofiler**: `nutrition_display_profiles` + `allergen_market_rules` (EU/SE/GB 14, US 9, CA 12) + `GET /v1/i18n/nutrition-profile` (EU-fallback); kJ- och natrium↔salt-hjälpare. - **M7 Sök**: unaccent + pg_trgm + trigramindex; accentokänslig och stavfelstolerant ingredienssök på alla språk. - **M10 Minne**: minnesvyn renderas på användarens språk (rubriker + deterministisk summary ur strukturerad value, sv-fallback). - **Varumärke**: namnet lever endast i `brand.config.json` (neutrala platshållare tills namnbeslut); historik tillplattad; runbook i `namnbyte.md`. - **Verifiering**: typecheck 17/17, 103 tester, build 3/3, migrate+seed, E2E på hela språk-/valuta-/måttflödet. ## Tidigare - Grundplattform: mobilapp, Food API (~70 endpoints), worker, admin, deterministiska motorer, AAMOS-kontrakt, subscriptions, GDPR, infrastruktur. - i18n steg 1: språkneutrala enhetskoder, locale-preferenser, AAMOS-localeContext, notismallar, Money-typ.