server/docs/proposals/artikkel_publisering.md
vegard a5985ef3f8 Dokumentasjon, erfaringslogg, migrasjoner og infra-oppdateringer
- Omorganiser docs/: konsepter, features, infra og proposals i egne mapper
- Ny docs/erfaringer/ med lærdommer fra chat-implementering (Svelte 5, SpacetimeDB, adapter-mønster)
- Oppdater ARCHITECTURE.md: Lag 1 status, ny §10 Erfaringslogg, SpacetimeDB i lokal dev
- Oppdater synkronisering.md med implementeringsstatus og designvalg
- Oppdater lokal.md med SpacetimeDB og AI Gateway
- Utvid PG-skjema med channels, messages, media_files, message_revisions
- Legg til seed_dev.sql, migration_safety.md, .env.example
- Nye feature-specs: chat, kanban, whiteboard, live_ai, lydmeldinger m.fl.
- Nye konsept-specs: studioet, møterommet, redaksjonen, den asynkrone gjesten m.fl.
- SpacetimeDB og AI Gateway i docker-compose.dev.yml
- collect-docs.sh inkluderer erfaringer/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 01:40:14 +01:00

128 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Forslag: Artikkel-publisering
## Idé
Utvide Sidelinja fra et rent podcast-verktøy til en fullverdig publiseringsplattform. Brukere kan skrive, redigere og publisere artikler — integrert i kunnskapsgrafen, med støtte for vitenskapelig notasjon og en visuell standard som matcher de beste uavhengige publikasjonene.
## Designfilosofi: Vakre tekster
Sidelinja-artikler skal føles som noe mellom en Substack-essay og en akademisk publikasjon. Ingen sidebar-rot, ingen widget-helvete, ingen distraksjoner. Bare tekst, typografi og innhold.
**Prinsipper:**
- **Typografi først.** Seriffont for brødtekst (Georgia, Literata eller lignende), god linjehøyde (1.61.8), komfortabel lesbredde (6075 tegn). Overskrifter i sans-serif for kontrast.
- **Luft.** Generøse marginer. Innholdet puster. Bilder og figurer får plass.
- **Mørk/lys.** Respekterer `prefers-color-scheme`. Begge moduser skal være like gjennomtenkte.
- **Matematikk er førsteklasses.** LaTeX-notasjon rendres med KaTeX (raskere enn MathJax, server-side-kompatibelt). Formler skal se like naturlige ut som brødtekst.
- **Ingen visuelt støy.** Metadata (forfatter, dato, temaer) er diskret plassert. Delingsknappar og navigasjon forsvinner under lesing. Fokus er teksten.
**Inspirasjon:** Gwern.net (typografi + fotnoter), Distill.pub (interaktive figurer), Stratechery (ren leseopplevelse), Edward Tufte (informasjonstetthet uten rot).
## Hvorfor er det interessant?
- **Naturlig forlengelse:** Redaksjonen har allerede chat, research-klipper og kunnskapsgraf. Artikler er neste logiske steg — fra intern diskusjon til publisert innhold.
- **Grafkobling:** Artikler som noder i kunnskapsgrafen arver automatisk koblinger til temaer, aktører og episoder. En artikkel om "Skolepolitikk" kobles til alle podcast-episoder, faktoider og research-klipp om samme tema.
- **SEO & Distribusjon:** Podcast-innhold er vanskelig å søkemotor-indeksere. Artikler gir tekstlig innhold som rangerer, med innebygde lenker tilbake til lydsegmenter.
- **Show notes 2.0:** Dagens show notes kan bli fullverdige artikler med egne URL-er, illustrasjoner og grafkoblinger.
- **Vitenskapelig troverdighet:** LaTeX-støtte gjør det mulig å publisere kvantitative analyser, statistikk og formelle argumenter med presisjon som matcher akademisk standard.
## Hva bygger den på?
- **Kunnskapsgrafen:** Artikkel som ny `node_type` (`'artikkel'`), med edges til temaer/aktører
- **Chat/Channels:** Hver artikkel kan ha en diskusjons-channel (kommentarfelt)
- **Jobbkø:** AI-assistert skriving, faktasjekk mot kunnskapsgrafen, automatisk oppsummering
- **Caddy:** Servering av publiserte artikler på egne URL-er
- **AI Gateway:** Forslag til relaterte temaer, faktoider og episodesegmenter under skriving
## Skisse
### Innholdsformat: Markdown + LaTeX + Embeds
Artikler skrives i utvidet Markdown med tre tillegg:
**1. LaTeX-notasjon (KaTeX)**
```markdown
Gini-koeffisienten beregnes som:
$$G = \frac{\sum_{i=1}^{n} \sum_{j=1}^{n} |x_i - x_j|}{2n^2 \bar{x}}$$
der $x_i$ er inntekten til individ $i$ og $\bar{x}$ er gjennomsnittsinntekten.
```
Inline-matte med `$...$`, blokk-matte med `$$...$$`. KaTeX rendrer server-side i SvelteKit (ingen klient-JS for lesere). Editoren viser live preview av formler.
**2. Podcast-embeds**
```markdown
{{segment:550e8400-e29b-41d4-a716-446655440000}}
```
Rendrer en innebygd lydspiller med transkripsjonstekst fra segmentet. Klikk for å lytte til akkurat det øyeblikket i episoden.
**3. Sidemerknad-fotnoter (Tufte-stil)**
```markdown
Dette er en påstand som trenger kontekst.^[Sidemerknad som vises i margen
på brede skjermer, som popup på mobil. Kan inneholde $\LaTeX$ og lenker.]
```
På brede skjermer (>1200px) vises fotnoter i margen ved siden av referansepunktet — aldri nederst på siden. På smale skjermer kollapses de til klikkbare popups.
### Datamodell
```sql
ALTER TYPE node_type ADD VALUE 'artikkel';
CREATE TABLE articles (
id UUID PRIMARY KEY REFERENCES nodes(id) ON DELETE CASCADE,
title TEXT NOT NULL,
slug TEXT NOT NULL, -- URL-vennlig tittel
body TEXT NOT NULL, -- Markdown + LaTeX + embeds (kildeformat)
body_html TEXT, -- Pre-rendret HTML (KaTeX + Markdown → HTML ved lagring)
excerpt TEXT, -- Kort oppsummering for RSS/OG-tags
status TEXT NOT NULL DEFAULT 'draft', -- 'draft', 'published', 'archived'
author_id TEXT REFERENCES users(authentik_id) ON DELETE SET NULL,
published_at TIMESTAMPTZ,
CONSTRAINT unique_slug_per_workspace UNIQUE (id) -- slug-unikhet via appkode + workspace
);
```
`body` er kildeformatet (Markdown + LaTeX). `body_html` er pre-rendret ved lagring, slik at lesere aldri venter på klient-side rendering. Editoren jobber mot `body`, leseren får `body_html`.
### Publiseringsflyt
```
Skriving (draft) → Intern review (channel) → Publisering → RSS + sitemap + OG-tags
```
### Funksjoner
- **Markdown + LaTeX editor** med split-view live preview i SvelteKit
- **KaTeX server-side rendering** — ingen JavaScript-avhengighet for lesere
- **Sidemerknad-fotnoter** (Tufte-stil) på brede skjermer, popup på mobil
- **#-mentions** i artikkeltekst som automatisk oppretter graf-edges
- **Innebygg podcast-klipp:** `{{segment:uuid}}` rendrer innebygd lydspiller
- **Relatert innhold:** Diskret panel under artikkelen med automatisk foreslåtte temaer, aktører og episoder basert på graf-nabolag
- **RSS-feed for artikler:** Separat fra podcast-RSS (Atom-format med full HTML-innhold)
- **OG-tags / deling:** Automatisk generert Open Graph-metadata
### Typografi-stack (CSS)
```
Brødtekst: Literata / Georgia / serif (1.6 linjehøyde, 6075ch bredde)
Overskrifter: Inter / system-ui / sans-serif (stramt, tydelig hierarki)
Kode: JetBrains Mono / monospace (med ligaturer)
Matematikk: KaTeX default (skalerer med brødtekst)
```
Fontene lastes som `font-display: swap` med system-fallback for umiddelbar rendering.
### URL-struktur
```
sidelinja.org/artikler/ → Artikkelliste (ren, minimal)
sidelinja.org/artikler/skolepolitikk-2026 → Enkeltartikkel (full leseopplevelse)
sidelinja.org/feed/artikler.xml → Artikkel-RSS (Atom)
```
## Innsats
**Middels** — Datamodellen er enkel (ny node_type + detailtabell). KaTeX har ferdig Svelte-integrasjon og SSR-støtte. Sidemerknad-fotnoter krever litt CSS-arbeid. Den tunge delen er å gjøre typografien og embed-syntaksen virkelig god.
## Wow-faktor
**Høy** — Kombinasjonen av vakker typografi, LaTeX-støtte og podcast-embeds skaper noe som ikke finnes andre steder. En publiseringsplattform der en politisk analyse kan ha både formler, lydklipp fra intervjuer, og koblinger til kunnskapsgrafen.
## Åpne spørsmål
- Skal artikler være multi-author (wiki-stil) eller single-author?
- Kommentarfelt for publikum, eller kun intern diskusjon?
- Versjonering av publiserte artikler (à la Wikipedia)?
- Skal draft-artikler leve i SpacetimeDB for sanntids-samskriving, eller er PG + autosave tilstrekkelig?
- Bilder: Content-addressable via `media_files`, eller ekstern hosting (CDN)?
- Skal KaTeX-rendering skje ved lagring (raskere serving) eller ved request (enklere oppdatering)?