Commit Graph

9 Commits

Author SHA1 Message Date
Claude b2c2ce72a3 Språksidan: vad som är översatt, vad som är granskat, och skillnaden
En vanlig språkmeny påstår att produkten finns på tio språk och slutar
där. Sidan i foten redovisar i stället skillnaden mellan att en text ÄR
översatt och att den är GRANSKAD av någon som kan yrket — och visar det
på de strängar där skillnaden betyder något: grindens hinder, alltså de
meningar som nekar en tekniker att avsluta ett ärende.

Att välja just dem är avsiktligt. En spärr ingen förstår är en spärr
utan väg förbi, så det är rätt strängar att döma en översättning efter.
Väljaren byter språk direkt i provet; åtta av tio språk möts därefter av
beskedet att metodiken inte är fackgranskad på språket. Det är ett
obekvämt sätt att presentera sin egen produkt och hela poängen med
sidan: en verkstadschef i Rumänien som får veta det i förväg kan planera
för det, samma chef som får veta det av en tekniker som missförstått en
säkerhetsinstruktion kan inte.

Varningen står UNDER provet, inte över. Den som just läst fem meningar
på sitt eget språk ska mötas av vad de inte garanterar — inte varnas i
förväg och sedan lugnas av att texten ser bra ut.

Sidan ligger i foten och inte i portalens navigation. Den är
dokumentation snarare än ett arbetsverktyg, och portalraden har redan
tio poster.

Språkknapparna ligger i rutnät, inte flexradbrytning. Tio språk bröts av
flex till nio plus ett ensamt, och den ensamma knappen läste sig som en
eftertanke i stället för som ett språk bland tio. Två kolumner på telefon
och fem på skärm gör tio jämnt i båda riktningarna.

Utgåva 3.2 dokumenterad.

602 tester, typkontroll och lint rena. Artefakten byggd och mätt på 390
och 1280 px över femton vyer: inget spill, inga externa begäranden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 16:51:44 +00:00
Claude 5579006e79 Abonnemang: gratis start, månadsfaktura, och en låsning som aldrig rör historiken
Kontot startar på Free och stannar där tills någon väljer annat. En
provperiod som tyst börjar kosta är samma sorts fälla produkten finns för
att undvika. Fakturan skapas ändå vid registreringen — på noll kronor —
därför att den etablerar serien och visar kunden exakt vad den inte
betalar för.

Fyra nivåer: Free (hela metoden, två konton), Standard, Premium,
Enterprise. Enterprise har inget listpris i stället för ett påhittat.
Basavgift plus per aktiv användare, och nivån är en HÄNDELSE — vilken
nivå som gällde när en faktura utfärdades måste gå att svara på i
efterhand, och en kolumn som skrivits över kan inte svara.

Månadsjobbet är idempotent på perioden: kör det två gånger samma dygn och
den andra körningen fakturerar ingenting. Ett fakturajobb som
dubbelfakturerar vid en omstart är värre än ett som inte kör alls.
Perioden räknas från registreringsdagen, inte från den första i månaden —
den som registrerar sig den 20:e ska inte få en faktura på elva dagar som
sin första upplevelse av produkten.

PDF utan beroenden. Kravet var inga beroenden, och ett PDF-bibliotek drar
in fem till för att rita text i två spalter. PDF är ett textformat;
generatorn är tvåhundra rader som går att läsa. Renderad och verifierad i
Chromium. Kunden hämtar fakturan själv eller anger en adress — bägge
vägar leder till samma dokument, och e-post är ett tillägg, inte den enda
vägen till sitt eget underlag.

---- Låsningen och dess gräns ------------------------------------------

Vi litar på kunden: inget kort, ingen förskottsbetalning, ingen spärr
innan någon fått veta. Förfallen faktura ger synlig nedräkning i 14 dagar
och sedan stopp för nya ärenden.

Men läsning och export är sanna i ALLA tillstånd, och det är inte
generositet. Ärendeloggen är verkstadens underlag i en garanti- eller
försäkringstvist som gäller DERAS kund — en tredje part utan del i vår
obetalda faktura. Att göra det oåtkomligt vore att använda någon annans
rättsliga ställning som påtryckningsmedel. Prövat från flera håll,
eftersom det är en regel som är lätt att tumma på under press.

En nollfaktura kan aldrig låsa någon. Free fakturerar noll, och en
obetald nollfaktura är en bokföringspost, inte en skuld.

---- Tre fynd som testerna grävde fram ----------------------------------

1. En kuverterad nyckel gjorde HELA organisationens övriga ärenden
   oläsbara när huvudnyckeln saknades — nycklarFor laddar alla nycklar,
   och en enda som inte gick att öppna kastade. En delvis migrerad
   organisation blev alltså helt stum av ett fel som gällde ett ärende.
   Nu hoppas den över, med varning i loggen, och fälten maskeras — vilket
   dessutom är rätt utfall i sak: det är precis vad krypto-shredding
   lämnar efter sig.

2. Integrationstestet försökte backdatera abonnemangets registrering och
   stoppades av min egen trigger. Att testet fick böja sig för regeln och
   inte tvärtom är poängen med regeln.

3. Palettestet räknade upp färgerna som en andra lista — samma dubblering
   som M-7 handlade om. Det läser dem nu ur FARG, med ett tak på åtta
   värden som motvikt: en palett som växer förbi det är en färglåda.

491 enhetstester · 179 integrationskontroller · genomgången 4/4 ·
portalspärren 18/18.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 15:55:13 +00:00
Claude ae5acbed92 Fotograferad mätarställning, versionshistorik och tysk kravbild i foten
---- Mätarställningen ska fotograferas ----------------------------------

Klienten krävde redan fotot: värdefältet visas först efter bilden. Men
GRINDEN gjorde det inte, och en regel som bara finns i gränssnittet är en
vana — inte en spärr. Det är samma förhållande som QUALITET C-2 gällde,
fast åt andra hållet: här var servern svagare, vilket är värre, eftersom
servern är den auktoritativa.

Skillnaden är hela uppgiftens bevisvärde. En inskriven siffra är
teknikerns påstående om vad som stod på mätaren; ett foto visar vad som
stod där. Mätarställningen avgör garanti- och försäkringsfrågor i
efterhand och är den enda uppgift i ärendet någon kan ha ett intresse av
att skriva fel. Evidensgraderingen följer nu med: fotograferad ger E2,
inskriven ger E1 och märks som inskriven i rapporten.

Undantag finns och måste finnas — slocknad display, oåtkomlig timräknare
— men kräver motivering, som det nekade historiksvaret.

---- Versionen räknades aldrig upp --------------------------------------

Systemet påstod "ALVA 1.0" efter tre revisioner, en fakturamodul och en
stängd portal. Versionen sa alltså ingenting om vad man fick.

Historiken är HÄRLEDD UR VAD SOM FAKTISKT LEVERERATS och varje post pekar
på sin commit. En utgåva som inte går att peka på hör inte hemma i listan
— en påhittad ändringslogg är samma obefogade säkerhet som produkten
finns för att undvika. Första siffran höjs bara när GARANTIERNA ändras,
vilket hänt två gånger: 2.0 när fakturan blev ett härlett dokument, 3.0
när TÜV-härdningen ändrade vad loggen garanterar. Nuvarande: 3.1.

Och ett fynd på vägen: ritningsstämpeln läste versionen ur den AKTUELLA
konstanten, så ett ärende stängt under 1.0 visade 3.1 — precis det
stämpelns egen beskrivning säger att den inte ska göra. Avslutshändelsen
bär numera versionen, och stämpeln läser den därifrån. Äldre ärenden
säger uttryckligen "ej registrerad" i stället för att låna dagens siffra.

---- Tysk kravbild i foten ----------------------------------------------

Listan är tysk därför att § 5 DDG är den strängaste och mest utkrävbara i
EU: klarar man den klarar man de andra marknaderna på köpet.

Två fällor som är aktuella just nu, och bägge ser fortfarande ut som
upplysningar:

  ODR-LÄNKEN SKA BORT. Förordning 524/2013 upphävdes genom förordning
  (EU) 2024/3228 och plattformen stängdes 20 juli 2025. Länken har legat
  i tiotusentals fotnoter sedan 2016 och pekar numera ingenstans. Foten
  saknar den medvetet.

  § 5 TMG HETER § 5 DDG sedan 14 maj 2024.

Modulen hittar inte på uppgifter. Ett Impressum med påhittad adress är
inte ett halvfärdigt Impressum utan ett vilseledande, och skadan större
än den tomma rutans. Osatta fält redovisas som en åtgärdslista med
rättslig grund, så driften kan spärra en driftsättning på listan i
stället för att upptäcka bristen när brevet kommer.

460 enhetstester · genomgången 4/4 · typkontroll ren.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 15:15:35 +00:00
Claude a94c228cab Garantiregimer, försäkringsvillkor och felanmälan i ärendet
---- Garantier (ALVA-SPEC-040) -----------------------------------------

Skiljelinjen mellan LAGSTADGAT och AVTALAT bär allt annat, och den
förväxlas dagligen åt bägge håll. Överraskande lite av det verkstaden
kallar garanti är lagstadgat:

  nybilsgaranti      avtalad. Ingen lag i EU eller USA kräver den.
  rostskyddsgaranti  avtalad. Ingen lag kräver den, någonstans.
  lackgaranti        avtalad.
  drivlinegaranti    avtalad.
  avgasgaranti       LAGSTADGAD i bägge, och den enda som är det.

Att kalla rostskyddet lagstadgat är fel; att kalla avgasgarantin en
tillverkarutfästelse är fel åt andra hållet, och det andra felet kostar
kunden pengar — en katalysator på en sexårig bil offereras rutinmässigt
som en betald reparation när den inte är det.

Varje lagstadgad post bär källa och kontrolldatum: 2019/771 (2 år,
säljaren — inte tillverkaren), MVBER 461/2010 förlängd till 2028,
715/2007 (5 år/100 000 km), 2024/1257 (8 år/160 000 km, batteri 80 %
vid 5 år och 72 % vid 8), CAA § 207 (2/24 000 och 8/80 000 miles),
Magnuson–Moss § 2302(c), CARB (3/50 000 och 7/70 000), ACC II (70 % SoH
vid 8 år/100 000 miles).

Bedömningen skiljer INOM, UTANFÖR och OKLART. Saknas underlag blir det
oklart, aldrig utanför — att påstå att en garanti gått ut när underlaget
inte räcker är det enda felet här som kostar kunden pengar.

---- Försäkring (ALVA-SPEC-041) ----------------------------------------

Modulen avgör ingenting och kan inte avgöra något. Vad som gäller
bestäms av kundens eget försäkringsbrev och villkoren vid tecknandet —
inte av vad ett bolag skriver i dag och inte av vad vi noterat. Testerna
låser att resultatet inte innehåller något fält som liknar ett utfall,
och att ett fordon utanför samtliga noterade gränser ändå inte får ett
nej: registret kan vara ofullständigt och produkten en annan.

Det som står överst är de sju villkoren som avgör en maskinskadefråga.
Ålder och sträcka är två av dem; de fem andra avgör oftare. Registret
med If, Folksam, Trygg-Hansa, Svedea, WaterCircles och Hedvig ligger
under, med källa och avläsningsdatum per post, och märks som föråldrat
efter 180 dagar i stället för att se aktuellt ut.

---- Felanmälan i ärendet (ALVA-PROC-0050) -----------------------------

En anmälningsknapp som bara finns i en portalvy nås aldrig av den som
står med händerna i en bil. Den ligger därför i varje ärende, och tar
med sitt sammanhang självt: ärende, metodik, plattformsversion och
spår-id. Teknikern minns inte plattformsversionen, och att fråga efter
den är att lägga över vårt problem på verkstaden.

Sammanhanget HÄRLEDS och kan inte smugglas: ett regnr i anropet släpps
inte igenom. En supportanmälan är inte ett skäl att flytta
personuppgifter till ett annat system. Bevisat i integrationstestet.

Anmälan är oföränderlig och statusen en projektion av inläggen — samma
skäl som för fakturan: en anmälan vars historia kan skrivas om är inte
ett underlag när någon frågar hur länge felet var känt. Verkstaden
svarar i sitt eget ärende; status sätts av supporten med egen nyckel.

---- Historikkontrollen -------------------------------------------------

Kravet fanns redan: klienten öppnar inte metodiken förrän
pre-diagnostiken är besvarad, och ett nej kräver skriven motivering.
Det var dock aldrig BEVISAT att spärren håller. Genomgången prövar nu
att metodiken inte går att nå medan historikfrågan står obesvarad — i
det enda ögonblick det går att pröva, eftersom svaret därefter redan är
avgivet.

429 enhetstester · 157 integrationskontroller mot riktig Postgres ·
genomgången 4/4 · portalspärren 16/16.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 14:56:48 +00:00
Claude 3b83fc94e9 Portalen är stängd på riktigt — m-9 stängd
Anmärkningen var att en inloggning som SER ut att autentisera ger
portalen bakom den en auktoritet den inte har. Rättelsen är inte att ta
bort skylten utan att göra spärren verklig där det finns något att
spärra mot.

Med plattformen konfigurerad autentiserar inloggningen mot
/api/auth/logga-in, varje portalväg går genom Portalvakt, och
fakturavyn läser organisationens egna fakturor ur GET /api/fakturor.
Misslyckas hämtningen visas felet — inte exemplet: data som ser äkta ut
men inte är det är värre än ett synligt fel. Utloggningen finns i
portalhuvudet och rensar sessionen på riktigt.

Utan konfigurerad plattform finns ingen session att kräva, och
demonstrationsmärkningen visas exakt i det läget.

---- Varför garantin inte är ett källkodstest ------------------------

Sviten kan bara läsa koden och se att vakten är inkopplad. Släpper den
igenom ändå — fel villkor, fel ordning, ett <Navigate> som aldrig hinner
rendera — ser koden likadan ut. Och en spärr som inte spärrar är precis
det m-9 handlade om.

e2e/portalsparr.mjs bygger därför med plattformen konfigurerad och
tittar var besökaren faktiskt hamnar: fem vägar spärrade utan session,
fem öppna med, utloggning som rensar token och stänger portalen igen.
Mutationstestad — att plocka bort vakten från en enda route fäller den.

Bevisad: 374 enhetstester, typkontroll, genomgången 4/4 ärenden,
portalspärren 14/14.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 12:08:18 +00:00
Claude b457543ede Fakturering i systemet — och ingen betalleverantör
ALVA säljs inte över disk. Aktiveringssekvensen på webbplatsen har hela
tiden sagt det: ansökan granskas, faktura utfärdas, betalning
registreras, organisationen aktiveras. Ändå laddade sidan Stripe.

Stripe. `@stripe/stripe-js` injicerar sitt skript redan vid import, inte
när någon ska betala, så ALVA hämtade en betalleverantör vid varje
sidvisning trots att produkten aldrig tar emot en betalning. Bakom
artefaktens CSP blockerades anropet och syntes som ett fel i konsolen på
ett system som inte har en kassa. Importen går nu mot `/pure`, som är
samma modul utan sidoeffekten. Butikens kassa fungerar som förut, men
bara när någon faktiskt öppnar den. Externa begäranden på ALVA-ytan:
noll.

Faktureringen. Beloppet måste komma någonstans ifrån, och det enda
hållbara stället är organisationens faktiska tillstånd: aktiva konton,
licensperiod, påslagna moduler. En summa någon skriver in kan säga emot
verkligheten — en härledd kan inte det. Samma resonemang som
sammanfattningen. Varje rad bär sitt underlag, så en granskare ser varför
summan blev den den blev utan att fråga någon.

Beloppen räknas i öre, momsen på nettot och inte per rad, och en utfärdad
faktura ändras aldrig: en felaktig faktura krediteras med en post som
pekar tillbaka och kräver ett skäl. Samma regel som för händelseloggen.

Prislistan ligger på ett ställe och är märkt som platshållare — den ska
sättas per marknad. Mekanismen är oberoende av siffrorna.

Ingen betalningshantering, inga kortuppgifter, ingen extern tjänst.
Betalning registreras av en administratör när pengarna kommit in;
systemet påstår aldrig att något är betalt utan att en människa sagt det.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-06 09:38:52 +00:00
Claude 3ec25dea9c ALVA: analysvy, sammanfattning och integrationsgränssnitt
---- Statistiken är ett produktbeslut ----------------------------------

Vilka siffror som visas avgör vad organisationen optimerar, så tre mått
är uteslutna med avsikt och låsta av test: ärenden per tekniker,
genomsnittlig ledtid och aktivitet. Alla tre belönar den som hoppar över
kontroller, och ett svårt fel SKA ta längre tid.

Medtagna, var och en handlingsbar:

  VERIFIERINGSGRAD   Andel avslut med fastställd orsak. Det enda mått
                     ett försäkringsbolag egentligen bryr sig om. Att
                     den inte är 100 % är friskt.
  REPRODUKTIONSGRAD  Låg siffra förutsäger återkommande fordon — man kan
                     inte åtgärda det man inte sett.
  OMARBETNING        Samma fordon tillbaka med samma orsakskategori inom
                     ett fönster. Det dyraste felet i en verkstad och det
                     enda ingen mäter, eftersom det kräver att två
                     ärenden kopplas ihop. Här är kopplingen gratis.
  UNDANTAGSFREKVENS  Vilka kontroller som hoppas över, per steg och fas.
                     Ett steg högt i listan är antingen felskrivet eller
                     kräver utrustning som saknas — bägge åtgärdbara.

Ett mått utan underlag visas som NOT APPLICABLE, aldrig som noll.
Skillnaden avgör om någon fattar beslut på en siffra som inte finns.

---- Sammanfattningen är härledd, inte genererad -----------------------

Frestelsen är att låta modellen skriva den. Det vore fel av tre skäl:
den blir en del av ett beslutsunderlag och måste därför gå att lita på
utan att granskas mot loggen varje gång; samma ärende måste ge samma
text om två år; och verkstadsgolvet har dålig täckning.

Den är alltså en projektion som briefen och rapporten. Den innehåller
inget som inte står i loggen och säger uttryckligen när något saknas i
stället för att utelämna det. Ett test kräver att den aldrig skriver
"felet konstaterat" när orsaken inte fastställts.

---- Integration utan påhittade endpoints ------------------------------

Jag känner inte Beonodes, ServiceCams eller CABAS faktiska gränssnitt.
En uppfunnen endpoint som ser färdig ut är sämre än en tom: den ser ut
att fungera tills någon försöker.

Därför ett profildrivet gränssnitt. En profil beskriver vad en KATEGORI
av system förväntar sig, och märks validated först efter att den körts
mot leverantören. Tills dess står den som draft, och det syns i
gränssnittet — en integrationslista där allt ser färdigt ut är den
snabbaste vägen till ett misslyckat införande, eftersom verkstaden
planerar efter den.

Kategorier: diagnosprotokoll, DMS, videooffert, fordonsdata,
skadekalkyl (CABAS är nordisk standard), garanti och försäkring.

Skadekalkyl går åt båda håll. Det ALVA tillför en kalkyl är inte fler
poster utan beviskedjan bakom dem: vad som kontrollerades, vad som
uteslöts och varför. Det är den enda del av en kalkyl som i dag inte går
att granska i efterhand.

Inkommande protokoll blir evidens, inte bilagor, med härkomsten bevarad
i varje post — ett värde som kommit utifrån får aldrig se ut som något
teknikern själv mätt. Saknas instrumentets identitet nedgraderas värdet
till E1 enligt samma regel som gäller manuella mätningar.

Utgående leveranser signeras med HMAC över tidsstämpel och kropp;
tidsstämpeln ligger inne i signaturen så en fångad leverans inte går att
spela upp i morgon. Verifieringsfunktionen exporteras så mottagaren kan
använda exakt samma kod — de flesta integrationsfel uppstår i glappet
mellan två implementationer av samma signatur.

Prenumerationer går genom samma SSRF-gräns som leverantörsuppslagen, och
leverans sker efter att loggen skrivits: en mottagare ska aldrig kunna
se en händelse som inte finns i loggen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 15:51:30 +00:00
Claude a8fdc9ebcc ALVA: webbplats, portal och kunskapskällor
Webbplatsen och plattformen är ett system. Samma komponentbibliotek,
samma rutnät, samma ord — besökaren lämnar aldrig marknadswebben när den
loggar in, eftersom den inte gör det. När apparna kommer återanvänder de
samma bibliotek.

Det som saknas på startsidan är lika avsiktligt som det som finns: ingen
hjältebild, ingen gradient, ingen animation, inga kundlogotyper, ingen
uppmaning att boka demo. En sida som försöker övertyga läser som
marknadsföring; en sida som redovisar läser som dokumentation. Den
senare är vad en teknisk chef fattar beslut utifrån.

Kunskapskällorna är byggda som Operational Knowledge Infrastructure:
leverantörsoberoende gränssnitt där organisationen ansluter det den har
licens till. Det gör att produkten aldrig behöver marknadsföras med "vi
stödjer X". En betainstallation fungerar på enbart egna dokument.

Livscykeln har fem tillstånd med avsikt. Configured och Connected är
inte samma sak — en nyckel kan vara ifylld och ändå fel — och Validated
skiljer sig från Connected: anslutningen svarar, men har den data för de
fordon organisationen faktiskt arbetar med? Det är den frågan som avgör
om källan är till nytta.

Portalens nyckeltal visas som NOT APPLICABLE i stället för som tomma
grafer. Att visa noll vore att lova något som inte finns; att dölja
raderna vore att dölja riktningen.

Ett test läser den faktiska källkoden och låser disciplinen: inga
gradienter, ingen animation, inga emojier utanför ✓ ○ □ →, ingen färg
utanför paletten, inga marknadsföringsord. Ett designsystem som bara
finns i ett dokument blir urvattnat på tredje sidan någon lägger till.

Testet avslöjade att min egen kod använde py-3 — 12 px — och alltså bröt
8 px-rutnätet på sju ställen. Jag rättade koden, inte testet. Ett rutnät
med undantag är inget rutnät.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-05 14:01:24 +00:00
Claude 301c477e25 Merge main: Guidad Felsökning flyttar ur roten till felsokning/
Main är sedan den här grenen skapades en helt annan produkt — Semantika,
en mobilapp med egen CDK-infrastruktur. Den äger nu repots rot: en
npm-workspaces-monorepo med apps/mobile, services/api och infra.

För att båda ska rymmas i samma repo flyttar Guidad Felsökning in i en
egen katalog i stället för att göra anspråk på roten:

  felsokning/app        webbklienten (Vite, egen package.json och
                        eslint-/vitest-konfiguration)
  felsokning/services   plattformstjänsten och AI-orkestern
  felsokning/infra      Terraform och databasschemat
  felsokning/docs       vision, moduler, drift
  felsokning/supabase   edge-funktion och migrationer

Merge:n hade tagit bort 128 filer som Guidad Felsökning bygger på —
värdapplikationens komponenter, Supabase-klienten, tillgångar — eftersom
main raderat dem och den här grenen inte råkat ändra just dem. De är
återställda på sin nya plats. Utan dem gick varken bygget eller
testerna: ai.ts och synk.ts importerar Supabase-klienten.

Semantikas rotfiler är orörda: package.json, eslint.config.js och
.github/workflows/ är deras. Guidad Felsökning har egna motsvarigheter i
sin katalog.

CI flyttar samtidigt från GitHub Actions till .gitea/workflows — samma
syntax, egna runners. .github/workflows/ tillhör Semantika härefter.

Verifierat på den nya platsen: 96 vitest-tester, typkontroll, eslint på
både klient och tjänster, bygge, och integrationstest mot riktig Postgres.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-04 12:22:49 +00:00