Hoppa till innehållet

Devportalen /portal/dev

Startsideportalens ekosystem för människa och agent

Devportalen

Teknisk stack

Valen, versionerna och skälen – plus container, deploy och miljövariabler.

Valen

Kommunens stack, utan deras byggblock. Avvikelserna är medvetna och dokumenterade som ADR:er.

Tabell: Lager, Val, Version, Varför
LagerValVersionVarför
RamverkNext.js, App Router16.3.1Kommunens starter kör Pages Router; App Router är Next:s huvudspår och passar modulkompositionen (ADR-001).
UIReact19.2.8Server components som default.
SpråkTypeScript strict~6.0.3Inga any. Varianter som unionstyper.
StilTailwind v4 med egna tokens4.3.3Tokens som @theme i packages/tokens, porterade 1:1 ur prototypen.
Komponentgrundshadcn/ui i repotnew-yorkRadix bär tillgängligheten, färgen är vår (ADR-008).
StateZustand5.0.15Som kommunens starter. Roll och dockningsläge.
ValideringZod4.4.3Inkommande data och schemat bakom structured outputs.
Dra och släpp@dnd-kit (core, sortable)6.3.1 / 10.0.0Användarens ordning av korten (ADR-018). Tangentbord och skärmläsare ingår; ett eget dragsystem skulle inte göra det.
AI@anthropic-ai/sdk0.120.0Provider-agnostisk adapter bakom AI_PROVIDER.
Monorepoyarn workspacesyarn 4.9.1Kommunen kör yarn. Turborepo först om byggtiderna kräver.
TestVitest4.1.11Kommunens grindar i lättviktig prototypversion.
RuntimeNode>= 24Som kommunens starter.

Container och deploy

  • next.config.ts har output: "standalone" och basePath: "/portal" – containern kör node apps/portal/server.js.
  • outputFileTracingRoot pekar två nivåer upp, annars gissar Next fel monorepo-rot.
  • Varje nytt modulpaket måste läggas i transpilePackages.
  • Dokploy pekar på docker-compose.yml. Git-push ger deploy.
  • En Compose-tjänst får inga Traefik-etiketter automatiskt – bara Application-typen gör det. Etiketterna och dokploy-network står därför i compose-filen. Utan dem svarar Traefik 404 med sitt standardcertifikat, och Let's Encrypt får inget att utfärda för.
  • Healthchecken använder 127.0.0.1, inte localhost: busybox wget provar ::1 först och Next lyssnar bara på IPv4.
  • Tjänsterna heter start-web, och framåt start-bff, start-redis, start-db. Prefixet skiljer stacken från andra på samma värd.
  • Vid isolerad deploy ligger start-web i två nätverk: stackens eget och dokploy-network. traefik.docker.network avgör vilket Traefik ska använda – utan den kan den välja fel IP. Framtida tjänster ska bara ligga i det egna nätverket.
  • Hemligheter läggs som Environment i Dokploy, aldrig i repot. Men de måste också listas under environment i docker-compose.yml – Dokploys Environment fyller bara compose-interpolationen, och en variabel som saknas i listan når aldrig containern.
  • /api/health svarar { ok: true } och används både som healthcheck och rökkontroll efter deploy.

Verifiera som Dokploy gör

docker network create dokploy-network   # en gång; på servern gör Dokploy det
docker compose up -d --build
docker inspect $(docker compose ps -q start-web) \
  --format '{{.State.Health.Status}}'          # ska bli healthy

Miljövariabler

Tabell: Variabel, Värden, Betydelse
VariabelVärdenBetydelse
DOMAINvärdnamnDomänen Traefik ska svara på. Standard start.sundsvall.dev; sätts i Dokploy om den ändras.
ACCESS_CODEvalfri strängLåser demon bakom en kod (ADR-012). Projektets yta på roten (utom ritningen och ändringsloggen), prototypens ingång /portal, /vision och /dev är alltid öppna. Osatt eller tom = ingen spärr alls, vilket betyder att en deploy utan variabeln är helt öppen.
AI_PROVIDERmock | anthropicmock ger regelmotorn för offline-demo. Standard är mock.
AI_MODELLmodell-idStandard claude-sonnet-5. Bytbar utan kodändring.
ANTHROPIC_API_KEYhemlighetBara på servern. Saknas den faller adaptern tillbaka på mock – och varnar en gång i loggen, så att tystnaden inte döljer det.
MIN_AI_MCPJSON-listaMCP-tjänster som Min AI får ansluta till: [{ id, namn, beskrivning, url, token? }], bara https (ADR-024). Tom = inga. Listas i docker-compose.yml.
ROSTNING_ADMIN_KODhemlighetSlår på workshoprösten och låser /rosta/admin (ADR-028). Tom = röstningen är avstängd.
STATUS_SKRIVNYCKELhemlighetKrävs för att skriva statusrapporter, som Bearer-token mot /api/status eller i formuläret på /status/ny (ADR-032). Skild från ACCESS_CODE. Tom = ingen kan skriva; läsningen är öppen.

Kvalitetsgrindar

  • yarn lint och yarn test gröna före varje commit. Båda körs från roten – eslint.config.mjs och vitest.config.mts – och täcker alla paket, så ett nytt modulpaket omfattas utan att något läggs till.
  • yarn typecheck kör tsc i varje paket. Modulpaketen har noUncheckedIndexedAccess, så en uppslagning ger T | undefined.
  • Drifttesterna i dev/portal/portal.test.ts fäller bygget när portalen beskriver något som inte finns: en modul utan katalogpost eller dok, ett dok som saknar ett obligatoriskt fält, eller en manifestkopia som glidit från module-sdk.
  • docker compose up --build före push.
  • Katalogpost och dok skrivna innan funktionen lämnas över för test. Täckningen syns på /dev/docs och kontrolleras av yarn test.
  • Conventional Commits, ämnesraden på svenska.
  • Ett arkitekturbeslut skrivs som en kort ADR i docs/beslut/ i samma commit som ändringen.