synops/docs/primitiver/edges.md
vegard f593b1e320 Redaksjonell innsending (oppgave 14.10): submitted_to-edge med rollevalidering
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>
2026-03-18 02:01:11 +00:00

4.9 KiB

Edges — spesifikasjon

Status: Besluttet.

Edges er relasjoner mellom noder. De er retningsbestemte, typede med freeform strenger, og kan bære metadata. Hva en node "er" bestemmes av dens edges, ikke av noden selv.

Skjema

CREATE TABLE edges (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    source_id   UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    target_id   UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
    edge_type   TEXT NOT NULL,
    metadata    JSONB NOT NULL DEFAULT '{}',
    system      BOOLEAN NOT NULL DEFAULT false,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    created_by  UUID REFERENCES nodes(id),

    UNIQUE (source_id, target_id, edge_type)
);

CREATE INDEX idx_edges_source ON edges (source_id);
CREATE INDEX idx_edges_target ON edges (target_id);
CREATE INDEX idx_edges_type   ON edges (edge_type);

Retning

Edges er retningsbestemte: source_id → target_id. "Vegard eier Sidelinja" er en annen edge enn "Sidelinja eier Vegard" (som ikke gir mening). Retningen leses naturlig:

Vegard  ──owner──→   Sidelinja       (Vegard eier Sidelinja)
Referat ──belongs_to──→ Møte         (referatet tilhører møtet)
Episode ──mentions──→ Jonas Gahr Støre (episoden nevner ham)

Symmetriske relasjoner (f.eks. vennskap) modelleres som to edges eller som en edge-type maskinrommet vet er symmetrisk.

Edge-typer

Freeform strenger med konvensjoner — ikke en hard enum. Nye relasjonstyper krever ingen migrering. Systemkritiske typer valideres i maskinrommet.

Kjente edge-typer

Type Betydning Metadata
owner Eier noden
admin Administrerer noden
member_of Er medlem av
reader Kan kun lese
belongs_to Tilhører (innhold → samling) { "slot": "hero"/"featured"/null, "slot_order": 1, "pinned": true, "publish_at": "..." }
alias Identitet (systemedge) system: true
mentions Refererer til
reply_to Svar på
scheduled Tidsplanlagt { "at": "2026-03-20T14:00Z" }
status Tilstand { "value": "done" }
tagged Merket med { "tag": "urgent" }
host_of Vert i
has_media Har mediefil (innhold → CAS-node)
intended_for Ment for publisering i (arbeidsfase)
submitted_to Innsendt til redaksjonell vurdering { "status": "pending", "submitted_at": "ISO8601" }
title Publisert overskrift (presentasjonsnode → innhold) { "variant": "editorial" }
subtitle Undertittel { "variant": "editorial" }
summary Ingress / forhåndsvisning { "variant": "ai" }
og_image Forsidebilde / OpenGraph-bilde (media → innhold) { "variant": "editorial" }
show_notes Show notes for episode { "variant": "ai" }
chapter Kapittelmarkør for episode { "at": "00:05:23" }
source_material Kildemateriale (avledet node → kilde) { "context": "quoted", "excerpt": "..." }
derived_from Prosessert versjon av (f.eks. lydstudio-output → original)
has_studio Studio-sesjon (sesjon → medienode)

Listen vokser organisk. Nye typer legges til ved behov uten skjemaendring.

Metadata

JSONB-feltet bærer kontekstspesifikk data om relasjonen:

  • status-edge: { "value": "in_progress" }
  • scheduled-edge: { "at": "2026-03-20T14:00Z" }
  • tagged-edge: { "tag": "urgent", "color": "#ff0000" }
  • submitted_to-edge: { "status": "pending", "submitted_at": "2026-03-17T10:00:00Z" } Status-verdier: pending, in_review, revision_requested, rejected, approved. Ved tilbakemelding: feedback, feedback_by, feedback_at.

Metadata er fleksibelt og spørrbart uten migrering.

Systemedges

Edges med system: true er usynlige ved traversering. De eksisterer for systemet, ikke for brukere.

Kjente systemedges:

  • alias — identitetskobling, aldri eksponert

Unique-constraint

UNIQUE (source_id, target_id, edge_type) betyr: én edge av hver type mellom to noder. Vegard kan ha owner-edge og member_of-edge til Sidelinja, men ikke to owner-edges.

Hva edges gjør med noder

Edges definerer hva en node "er" — ikke noden selv:

Node + member_of → kanal       = chatmelding
Node + belongs_to → board
     + status → "todo"         = kanban-kort
Node + scheduled → tidspunkt   = kalenderoppføring
Node + belongs_to → kun bruker = privat notat
Node + mentions → topic        = faktoid i kunnskapsgrafen
Node uten edges                = løs tanke

Retyping er å endre edges. Ingen datamigrasjon.

Tilgangsmatrise-oppdatering

Når en edge med tilgangsrolle (owner, admin, member_of, reader) opprettes eller slettes, oppdaterer maskinrommet node_access-matrisen i samme transaksjon. Se noder er sentrum for full spesifikasjon.