Implementerer fire nye dynamiske sidetyper for publiseringssamlinger:
- Kategori-sider: filtrert på tag-edges, paginert med cache
- Arkiv: kronologisk med månedsgruppering, paginert med cache
- Søk: PG fulltekst med tsvector/ts_rank, paginert med cache
- Om-side: statisk CAS-node (page_role: "about"), immutable cache
Teknisk:
- Ny migrasjon (011): tsvector-kolonne + GIN-indeks + trigger for søk
- Nye Tera-templates: category.html, archive.html, search.html, about.html
- DynamicPageCache for in-memory caching av dynamiske sider
- Ruter for /pub/{slug}/kategori/{tag}, arkiv, sok, om
- Custom domain-varianter for alle nye sidetyper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Når theme eller theme_config endres på en samling, trigges paginert
bulk re-rendering av alle artikler (100 om gangen). Artikler serveres
med gammelt tema til de er re-rendret — renderer_version identifiserer
hvilke som gjenstår. Duplikatsjekk mot eksisterende pending/running jobber.
- publishing.rs: trigger_bulk_rerender() med paginert SQL-query
- intentions.rs: theme/theme_config endring detekteres i update_node
- RENDERER_VERSION bumped til 2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redaktør kan nå opprette en diskusjonstråd direkte fra den redaksjonelle
arbeidsflaten, knyttet til en innsendt artikkel og dens forfatter.
Backend:
- create_communication utvides med context_id som oppretter belongs_to-edge
fra kommunikasjonsnoden til kontekstnoden (artikkelen)
- editorial_board-spørringen returnerer discussion_ids per kort (kommunikasjonsnoder
med belongs_to til artikkelen)
Frontend:
- "Start samtale"-knapp på hvert redaksjonelt kort oppretter kommunikasjonsnode
med redaktør som owner og forfatter som member, og navigerer til chatten
- Eksisterende samtaler vises som lenker på kortet
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Legger til en bakgrunns-scheduler som hvert 60. sekund sjekker for
belongs_to-edges med publish_at i fortiden der artikkelen ikke er rendret.
Ved treff: oppretter render_article-jobb (og render_index for berørte
samlinger) i jobbkøen. RSS-feeden oppdateres automatisk siden den
genereres dynamisk fra DB.
Detaljer:
- find_due_articles(): SQL-spørring med deduplisering mot eksisterende jobber
- run_publish_scheduler(): orkestrerer én runde med publisering
- start_publish_scheduler(): tokio::spawn med 60s poll-intervall
- Hooks inn i main.rs ved oppstart, parallelt med jobbkø og pruning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redaktøren ser alle artikler med submitted_to-edge til samlingen,
gruppert i fire kolonner etter status. Drag-and-drop mellom kolonner
endrer status via update_edge. Siste kolonne ("Planlagt") åpner en
dialog for å sette publish_at i edge-metadata — klar for oppgave 14.12
(planlagt publisering).
Backend: GET /query/editorial_board med forfatterinfo og edge-metadata.
Frontend: /editorial/[id] med sanntidsoppdateringer via SpacetimeDB.
Lenke fra PublishingTrait når require_approval er aktivt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Maskinrommet håndhever nå publiseringsregler for samlinger med
require_approval: true i publishing-traiten:
- submitted_to-edge: kun roller i submission_roles (+ owner/admin) kan
opprette. Metadata settes automatisk: status=pending, submitted_at=now.
- belongs_to-edge til require_approval-samling: kun owner/admin.
- Status-endring på submitted_to: kun owner/admin av samlingen.
PublishingConfig utvidet med require_approval (default false) og
submission_roles (default ["member"]).
Nye hjelpefunksjoner: get_publishing_config, get_user_role_for_node,
user_is_owner_or_admin. EdgeRow utvidet med source_id/target_id.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Maskinrommet orkestrerer, CLI-verktøy gjør jobben
- Spatial canvas med drag-and-drop som primær interaksjon
- To retninger: dra ut = ny node, dra inn = transformer
- Arbeidsflaten er en node (rekursivt)
- Caddy flyttet til native i teknologitabellen
- CLI-verktøy lagt til i lagmodell og teknologivalg
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bryt ut all prosessering fra maskinrommet til standalone CLI-verktøy:
- 9 prosesseringsverktøy (transcribe, audio, render, rss, tts,
summarize, suggest-edges, respond, prune)
- 5 oppslagsverktøy for Claude (context, search, tasks,
feature-status, node)
- Jobbkø-dispatcher + felles lib
Maskinrommet og Claude deler samme verktøykasse.
Ref: docs/retninger/unix_filosofi.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tre hovedkomponenter:
1. custom_domain.rs — ny modul i maskinrommet:
- GET /internal/verify-domain?domain= — Caddy on-demand TLS callback.
Returnerer 200 hvis domenet er registrert i en publishing-trait, 404 ellers.
- DNS-validering (validate_dns): sjekker at domenet peker til serverens IP
via system DNS resolver. Kalles ved oppdatering av publishing-trait.
- Domene-basert serving: /custom-domain/index, /custom-domain/{article_id},
/custom-domain/feed.xml — Caddy rewriter custom domain-forespørsler hit,
Host-header brukes til å finne samlingen.
- Re-rendering: rerender_collection_articles() enqueuer render-jobber
for alle artikler + forside når custom_domain endres.
2. Caddy on-demand TLS (Caddyfile):
- Catch-all :443-blokk med on_demand ask-callback til maskinrommet.
- Rewrite-regler: / → /custom-domain/index, /feed.xml → /custom-domain/feed.xml,
/* → /custom-domain/{uri}. Host-header bevares for domene-oppslag.
3. intentions.rs — utvidet update_node:
- DNS-validering ved setting av custom_domain i publishing-trait.
- Detekterer endring i custom_domain og trigger re-rendering av
alle artikler (canonical URL endres).
Eksisterende kode (publishing.rs, rss.rs) bruker allerede custom_domain
for base_url/canonical_url — ingen endringer nødvendig der.
Ref: docs/concepts/publisering.md § "Custom domain-mekanisme"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Maskinrommet og Claude deler samme CLI-verktøykasse. Maskinrommet
kaller dem fra jobbkøen, Claude fra terminalen. Alt maskinrommet
gjør kan Claude simulere — nyttig for debugging, testing og utvikling.
Nye features bygges som CLI-verktøy fra start. Eksisterende kode
brytes ut gradvis.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Feeden i rss.rs var allerede implementert med full RSS 2.0 og Atom 1.0
støtte, inkl. podcast-enclosures. Det som manglet var integrasjon med
publiseringstemplates:
- base.html: <link rel="alternate"> for feed auto-discovery (kun når
samlingen har rss-trait)
- base.html: RSS-lenke i nav vises kun for samlinger med rss-trait
- publishing.rs: has_rss propageres fra CollectionRow gjennom alle
render-funksjoner til Tera-kontekst
- CAS-rendering (render_article_to_cas, render_index_to_cas) sjekker
også rss-trait for korrekt template-kontekst
Verifisert: kompilerer, alle 36 tester passerer, feed.xml returnerer
gyldig RSS/Atom, 404 for ukjente slugs, discovery-link i HTML.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Personlig publiseringsflyt for samlinger med publishing-trait der
require_approval: false. Bruker kan publisere artikler fra mottak
til samlingen, og avpublisere ved å fjerne belongs_to-edge.
Backend:
- Nytt delete_edge-endepunkt i maskinrommet med tilgangskontroll
og automatisk forside-cache-invalidering ved avpublisering
Frontend:
- PublishDialog: forhåndsvisning, slug-editor, tema-info, bekreftelse
- EditorTrait: publiser/avpubliser-knapper på innholdsnoder i
publiseringssamlinger, velger for upubliserte artikler
- deleteEdge i API-klienten
Docs:
- Oppdatert api_grensesnitt.md med delete_edge, update_edge, set_slot
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Arkitekturskiftet fra "vertikalt stablede traits" til "spatial canvas
med verktøy-paneler" krever:
Fase 19 — Arbeidsflaten:
- Canvas-primitiv (pan/zoom/viewport)
- BlockShell wrapper for alle paneler
- Collection-side rewrite til spatial layout
- Kontekst-header med node-velger
- Snarveier og personlig flate
Fase 20 — Universell overføring:
- message_placements tabell + STDB
- source_material edge-type
- BlockReceiver interface i alle traits
- Transfer service (innholdstransfer + triage)
- Panelrework for Chat, Kanban, Kalender, Editor, Studio
Ref: docs/retninger/arbeidsflaten.md, docs/features/universell_overfoering.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Visuell editor for redaksjonell forside-styring. Rute:
/collection/[id]/forside med tre soner (hero, featured, strøm).
- HTML5 drag-and-drop mellom hero/featured/strøm-plasser
- Pin-knapp per artikkel (forhindrer automatisk fjerning)
- Hurtigknapper for å flytte artikler mellom slots
- Forhåndsvisning via iframe av publisert forside
- Bruker POST /intentions/set_slot API fra maskinrommet
- Sanntidsdata fra SpacetimeDB (belongs_to-edges med slot-metadata)
- PublishingTrait viser nå «Rediger forside»-knapp og publisert-lenke
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ny retning: arbeidsflaten.md — spatial canvas med verktøy-paneler.
Drag-and-drop mellom verktøy oppretter nye noder med source_material-edges.
Noder muterer ikke — de føder nye noder.
Oppdatert docs:
- universell_input.md: "retyping" → "nye noder fra eksisterende"
- rom_ikke_forum.md: "bli" → "føde", siloer → verktøy-paneler
- universell_overfoering.md: blokker → verktøy-paneler, dual-modell
- meldingsboks.md: multi-rolle → visning i flere kontekster
Nye docs:
- arbeidsflaten.md: retning med kompatibilitetsmatrise og inkompatibilitet
- artikkelverktoy.md: langform TipTap-editor med drag-and-drop mottak
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ny intention `POST /intentions/set_slot` for redaksjonell
kontroll over forside-slots i publiseringssamlinger.
Håndhever:
- Maks 1 hero: gammel ikke-pinned hero flyttes til strøm
- featured_max: eldste ikke-pinned featured FIFO til strøm
- pinned-flagg beskytter mot automatisk fjerning
- Krever owner/admin-tilgang til samlingen
- Trigger forside-rerendering etter slot-endring
Returnerer liste over displaced edges slik at frontend
kan vise hva som ble flyttet.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
synops.no/pub/* proxyes nå til maskinrommet (port 3100) som eier
slug→hash-mappingen og setter Cache-Control-headere:
- Artikler fra CAS: immutable (1 år)
- Dynamisk forside: max-age=index_cache_ttl (default 300s)
- Kategori/arkiv/søk (14.15): kortere TTL når endepunktene kommer
Bruker `handle` (ikke `handle_path`) slik at /pub-prefixet
beholdes — maskinrommets ruter forventer /pub/{slug}/...
Verifisert: Caddy validerer OK, 404 for ukjent slug passerer
korrekt gjennom proxyen med `via: 1.1 Caddy`-header.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
serve_index støtter nå index_mode fra publishing-trait:
- "static": render_index-jobb rendrer forsiden til CAS ved publisering,
samlingens metadata.rendered_index.index_hash peker til CAS-fil,
serveres med Cache-Control: immutable
- "dynamic" (default): in-memory cache med konfigurerbar TTL
(index_cache_ttl, default 300s), invalidert ved belongs_to-endringer
Tre separate indekserte PG-spørringer erstatter den gamle
alt-i-ett-spørringen — filtrerer på slot i edge-metadata
(hero/featured/strøm) med LIMIT, bruker GIN-indeks.
Trigger-logikk utvidet: belongs_to-edge-opprettelse legger
render_index-jobb i kø (statisk) eller invaliderer cache (dynamisk).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kodegjennomgang av lydstudio-implementasjonen avdekket:
- Responsivt design mangler (mobil-layout)
- FFmpeg-parametervalidering bør strammes
- Fade/silence-logikkfeil (negativ start, margin-underflow)
- Frontend input-begrensninger mangler
- Job-polling lekker ved navigering
- Temp-filer ryddes ikke ved krasj
- FFmpeg-feilmeldinger når ikke bruker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer rendering-pipeline: metadata.document (TipTap JSON) → HTML
via Tera-templates → CAS-lagring → metadata.rendered oppdateres.
Nye moduler:
- tiptap.rs: Konverterer TipTap/ProseMirror JSON til HTML. Støtter
paragraph, heading, blockquote, lister, code_block, image, hr,
og marks (bold, italic, strike, code, link, underline).
XSS-sikker med HTML-escaping.
- render_article jobb i jobbkøen: Henter node + samling, konverterer
document → HTML, rendrer med Tera + tema, lagrer i CAS, oppdaterer
nodens metadata.rendered med html_hash og renderer_version.
Endringer:
- publishing.rs: SeoData-struct med OG-tags, canonical URL, JSON-LD.
render_article_to_cas() for full pipeline. serve_article() serverer
fra CAS (immutable cache) hvis pre-rendret, fallback til on-the-fly.
RENDERER_VERSION=1 for fremtidig bulk re-rendering.
- intentions.rs: Trigger render_article-jobb automatisk når belongs_to
edge opprettes til samling med publishing-trait.
- Alle 4 artikkel-templates: SEO-block med meta description, OG-tags
(type, title, description, url, site_name, image, published_time),
canonical URL, RSS-link, og JSON-LD structured data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer publiseringsmotoren med fire innebygde temaer:
- Avis: multi-kolonne, informasjonstung, hero+sidebar+rutenett
- Magasin: store bilder, luft, editorial, cards-layout
- Blogg: enkel, én kolonne, kronologisk liste
- Tidsskrift: akademisk, tekstdrevet, nummerert innholdsfortegnelse
Hvert tema har artikkelmal + forside-mal som Tera-templates (Jinja2-like).
CSS-variabler for theme_config-overstyring fra publishing-traiten —
fungerer meningsfullt med bare "theme": "magasin" (null konfigurasjon).
Teknisk:
- publishing.rs: Tera engine, render-funksjoner, DB-spørringer, HTTP-handlers
- Templates innebygd via include_str! (kompilert inn i binæren)
- Ruter: GET /pub/{slug} (forside), /pub/{slug}/{id} (artikkel),
/pub/{slug}/preview/{theme} (forhåndsvisning med testdata)
- 6 enhetstester for CSS-variabler, rendering og tema-fallback
Ref: docs/concepts/publisering.md § "Temaer"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Legger til et admin-panel på samlingssiden der man kan legge til/fjerne
traits fra katalogen og konfigurere per-trait-innstillinger. Endringene
sendes via updateNode til maskinrommet som validerer mot VALID_TRAITS.
- Ny updateNode-funksjon i api.ts
- Delt trait-katalog i lib/traits.ts (brukes av collection/new og TraitAdmin)
- TraitAdmin.svelte: toggle traits, rediger config-nøkler, lagre
- Integrasjon i collection/[id] med Traits-knapp i header
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ny side /collection/new med:
- 13 forhåndsdefinerte pakker (nettmagasin, podcaststudio, redaksjon osv.)
som kort-grid med ikon, beskrivelse og trait-liste
- Manuelt trait-valg med hele trait-katalogen kategorisert i 9 grupper
- Oppsummering med valgte traits og opprett-knapp
- Navigerer til /collection/[id] etter opprettelse
Knapp «Ny samling» lagt til i mottak-headeren.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>