Dokumentationen / Skal
Skalet (apps/portal)
dok · skalid: skal
namn: Skalet (apps/portal)
sammanfattning: Komponerar modulerna till en sammanhängande sida och äger allt krom, all identitet och all layout.
uppdaterad: 2026-10-07
ansvar:
- Läsa modulregistret, filtrera på roll och rendera varje slot i ordning.
- Äga identiteten: rollen ur cookien, DemoUser, och UserContext som är allt modulerna får veta om användaren.
- Äga kromet: sidopanel, AI-fält, användarmeny, sidfot, fokuslägets topprad.
- Lägga ut rutnätet – nyckeltalsraden i fyra spår, arbetsytan i två spalter – och låta modulerna fylla det.
- Aldrig veta vad en widget innehåller. Skalet känner slotens namn, inte innehållet.
filer:
- shell/registry.ts — Modulregistret. En ny modul = en rad. Anropar provideRegistry för de aggregerande modulerna.
- shell/session.ts — getCurrentUser ur cookien, toContext som gör om DemoUser till UserContext.
- shell/demo-users.ts — Demoanvändarna – medarbetaren och fyra chefer på olika nivåer, för dialogstödet – sektionerna under "Sidor" och de verktygspunkter som ännu saknar modul. Kakan bär en roll eller en användares id.
- shell/actions.ts — switchRole, loggaInSom och loggaUt: server actions som sätter eller rensar rollcookien. sparaLayout för kortens ordning, även standardordningen (ADR-018). markeraLasta för notiserna (ADR-020). stangFokus och visaFokusIgen (demo) för fokusytan (ADR-021).
- shell/ShellFrame.tsx — Ramen: sidopanel plus arbetsyta. Klientkomponent för dockningsläget; children renderas på servern.
- shell/Sidebar.tsx — Sidopanelen: Verktyg, Sidor, notiser, användarmeny. Sektionerna kommer som prop från layouten.
- app/(skal)/verktyg/[...vag]/page.tsx — Modulvyer med mode "standard": slår upp vägen med routeFor och skickar vidare params (ADR-019).
- shell/fokus/FokusYta.tsx — Fokusytan under AI-fältet, formad som en nyhet: bild, datum, rubrik, ingress, avsändare. Ljusblå botten och blå ram. Stäng flyttar fokus till AI-fältet (ADR-021).
- shell/fokus/kaka.ts — Kakan med stängda fokus-id per roll. Samma logik och tak som de lästa notiserna.
- shell/notiser/Notiser.tsx — Klockan och panelen: modulernas notiser, olästa först i räknaren, kantfärg efter status. Intern notis navigerar, extern öppnas i ny flik (ADR-020).
- shell/notiser/lasta.ts — Kakan med lästa notis-id per roll: lasLasta, markera. Testad i lasta.test.ts.
- shell/Board.tsx — Rutnätet. Läser widgetsFor för kpi, main och side, och användarens ordning ur kakan (ADR-018).
- shell/AnpassaBoard.tsx — Spalterna i användarens ordning och läget "Anpassa startsidan": @dnd-kit, flyttknappar, svenska utrop. Ordningen ändras först när kortet släpps; målet är kortet under pekaren. Fokus stannar efter flytt, utropen anger ny plats, reducerad rörelse respekteras, Ångra och Återställ standardordning (ADR-018, WCAG 2.2). Varje kort i en @container.
- shell/layout/ordning.ts — Ren logik: layoutSchema, lasLayout, tillampa (sparad över standard), flytta, hitta. Testad i ordning.test.ts.
- shell/AskBand.tsx — AI-fältet på startsidan: hälsningen runt AskField.
- shell/AskField.tsx — Själva AI-fältet: frågan, förslagen och det korta svaret från POST /api/assistant. Används av AskBand och av en sidas ingång.
- app/(skal)/sidor/[...vag]/page.tsx — Sidtypen: slår upp sektion, ingång eller artikel, löser innehållet och sätter ctx.page.
- shell/sida/SidaIngang.tsx — Ingången enligt it-support-prototyp.html: sidhuvud, AI-fält, snabbvägar, redaktionella kort (cards), modulens egna kort (slots), undersidor, källa (ADR-022).
- shell/sida/SidaArtikel.tsx — Artikeln enligt innehallssida-prototyp.html: kicker, ingress, brödtext i kort, sidansvarig-fot.
- shell/sida/Innehall.tsx — Den enda renderaren för ContentBlock, rekursiv för details (native <details> med chip). Intern länk via next/link, extern med ↗.
- shell/Webbmeny.tsx — En webbplats meny som rad överst i arbetsytan (ADR-017). Fast höjd 5.2rem, som ramen räknar med. Klientkomponent för aktivt val.
- shell/sida/SidaInbaddad.tsx — Sidan i en sandlådad ram som fyller arbetsytan under menyraden (100dvh − 5.2rem), eller förklaringen när källan blockerar inbäddning.
- shell/sida/inbaddning.ts — tillaterInbaddning (ren) och kontrolleraInbaddning: läser X-Frame-Options och frame-ancestors mot vår origin.
- shell/sida/Lanklista.tsx — PageLink som lista; en länk med children blir en hopfälld <details> med sidan själv först.
- shell/sida/Kallmarkning.tsx — Källa, datum och länk till originalet; gult chip för sparad version.
- shell/sida/ — Även Brodsmulor, Snabbvagar, SektionSida, Aterkoppling och datum.
- shell/sektioner.test.ts — Varje sidas sektion finns i skalets lista; registrets invarianter håller.
- shell/FlowBar.tsx — Fokuslägets topprad med Avbryt.
- shell/store.ts — Zustand. Enda äkta klientstate: dockad sidopanel.
- shell/shell.css — Kromets CSS, porterad 1:1 ur prototypen. Ägs av skalet – moduler skriver inte här.
api:
- getCurrentUser: () => Promise<DemoUser>
Den inloggade användaren. Läser rollcookien; i skarp drift SAML-sessionen. Anropsstället är detsamma.
- toContext: (user: DemoUser, page?: string) => UserContext
Det modulerna får se om användaren. Fler uppgifter hämtar modulen själv.
- switchRole: (role: Role) => Promise<void>
Server action bakom rollväxlaren i sidopanelen. Sätter httpOnly-cookie i 30 dagar och revaliderar layouten.
- loggaInSom / loggaUt: (role: Role) => Promise<void> / () => Promise<void>
Prototypingångens start och utloggning. Samma cookie, men med redirect till /start respektive /portal.
- registry: ModuleManifest[]
Modulregistret. Ordningen styr nav och fallordning när order saknas.
kontrakt:
- Identiteten kommer alltid från servern. En profil som klienten skickar vore en injektionsväg rakt in i ärendet.
- Rollcookien heter startsidan-roll, är httpOnly och faller tillbaka på chef.
- Skalet renderar vilken modulrutt som helst: modulen äger vyn, skalet äger kromet.
- Rutterna: / är projektsidan och /portal prototypens ingång (båda utan krom), /start är startsidan, /flode/<namn> är fokusflöden, /verktyg/<väg> är modulvyer med skalets krom (ADR-019) – med mode "full" över hela arbetsytan i skärmens höjd, utan sidfot och AI-knapp (ADR-025), /sidor/<sektion>[/<ingång>[/<artikel>]] är sidor, /las-upp är åtkomstspärren.
- Skalet äger sektionerna under "Sidor". En sektion länkar först när någon modul har en ingång där.
- Modulernas genvägar (genvagarFor) står bredvid hälsningen i AI-fältet; en AI-genväg har AI-tonen och märks ✦ (ADR-025, ADR-026).
- Startsidan visar den nyaste fokusytan från fokusFor som användaren inte stängt, under AI-fältet (ADR-021). Användarmenyn har "Visa fokusnyheten igen (demo)".
- Klockans notiser kommer från modulerna via notificationsFor; layouten lägger på läst-status ur kakan startsidan-notiser-lasta-<roll> (ADR-020).
- Användaren ordnar korten i main och side (ADR-018). Ordningen sparas per roll i kakan startsidan-layout-<roll>, valideras på servern och läggs över modulernas order. Nya kort hamnar sist i sin standardspalt.
- Skalet äger också webbplatserna (ADR-017): samma form som en sektion, men visade som menyrad överst – bara inne på webbplatsen. Med under blir webbplatsen ett kort på en sektions sida. Sidopanelen står kvar runt en inramad sida.
- En sida får ctx.page = sidans slug, så att modulernas ai.suggestions kan svara på sidans ämne.
beroenden: module-sdk, tokens, ui
beslut: ADR-001, ADR-003, ADR-004, ADR-006, ADR-007, ADR-016, ADR-017, ADR-018, ADR-019, ADR-020, ADR-021, ADR-022
kvarstår:
- pendingTools och pendingSuggestions i demo-users.ts är platshållare tills modulerna tar över.
- Fyra av sex sektioner under "Sidor" saknar sidor och står kvar som "#".
- Återkopplingen på en artikel sparas inte – det finns ingen mottagare än.
- Kortens ordning följer webbläsaren, inte personen, tills SAML-sessionen finns i fas 4.