diff --git a/docs/primitiver/edges.md b/docs/primitiver/edges.md index 9ea892e..67d0ff6 100644 --- a/docs/primitiver/edges.md +++ b/docs/primitiver/edges.md @@ -90,6 +90,9 @@ JSONB-feltet bærer kontekstspesifikk data om relasjonen: - `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`. +- `source_material`-edge: `{ "context": "quoted", "excerpt": "Den aktuelle teksten..." }` + Context-verdier: `quoted` (sitert verbatim), `summarized` (oppsummert/omskrevet), + `referenced` (referert uten sitat). Begge felt er påkrevd og valideres i maskinrommet. Metadata er fleksibelt og spørrbart uten migrering. diff --git a/maskinrommet/src/intentions.rs b/maskinrommet/src/intentions.rs index 0c83ea1..04ca886 100644 --- a/maskinrommet/src/intentions.rs +++ b/maskinrommet/src/intentions.rs @@ -808,6 +808,39 @@ pub async fn create_edge( } } + // -- Validering av source_material-metadata -- + if req.edge_type == "source_material" { + if let Some(obj) = metadata.as_object() { + // context er påkrevd og må være en av tre gyldige verdier + match obj.get("context").and_then(|v| v.as_str()) { + Some("quoted" | "summarized" | "referenced") => {} + Some(other) => { + return Err(bad_request(&format!( + "source_material context må være 'quoted', 'summarized' eller 'referenced', fikk '{other}'" + ))); + } + None => { + return Err(bad_request( + "source_material krever 'context'-felt (quoted, summarized eller referenced)", + )); + } + } + // excerpt er påkrevd og må være en ikke-tom streng + match obj.get("excerpt").and_then(|v| v.as_str()) { + Some(s) if !s.trim().is_empty() => {} + _ => { + return Err(bad_request( + "source_material krever et ikke-tomt 'excerpt'-felt", + )); + } + } + } else { + return Err(bad_request( + "source_material krever metadata med 'context' og 'excerpt'", + )); + } + } + let metadata_str = metadata.to_string(); // -- Generer UUIDv7 -- @@ -1273,6 +1306,37 @@ pub async fn update_edge( } } + // -- Validering av source_material-metadata ved oppdatering -- + if edge_type == "source_material" { + if let Some(obj) = metadata.as_object() { + match obj.get("context").and_then(|v| v.as_str()) { + Some("quoted" | "summarized" | "referenced") => {} + Some(other) => { + return Err(bad_request(&format!( + "source_material context må være 'quoted', 'summarized' eller 'referenced', fikk '{other}'" + ))); + } + None => { + return Err(bad_request( + "source_material krever 'context'-felt (quoted, summarized eller referenced)", + )); + } + } + match obj.get("excerpt").and_then(|v| v.as_str()) { + Some(s) if !s.trim().is_empty() => {} + _ => { + return Err(bad_request( + "source_material krever et ikke-tomt 'excerpt'-felt", + )); + } + } + } else { + return Err(bad_request( + "source_material krever metadata med 'context' og 'excerpt'", + )); + } + } + let metadata_str = metadata.to_string(); let edge_id_str = req.edge_id.to_string(); diff --git a/tasks.md b/tasks.md index be1b296..ab82d17 100644 --- a/tasks.md +++ b/tasks.md @@ -224,8 +224,7 @@ Ref: `docs/retninger/arbeidsflaten.md`, `docs/features/canvas_primitiv.md` Ref: `docs/features/universell_overfoering.md`, `docs/retninger/arbeidsflaten.md` § "Kompatibilitetsmatrise" - [x] 20.1 message_placements tabell: PG-migrasjon + SpacetimeDB-modul med `place_message`, `remove_placement`, `move_on_canvas` reducers. Synk STDB→PG. Ref: `docs/features/universell_overfoering.md` § 2. -- [~] 20.2 source_material edge-type: legg til i edge-skjema + maskinrommet-validering. Støtt kontekst-metadata (quoted, summarized, referenced) og excerpt-felt. Ref: `docs/retninger/arbeidsflaten.md` § "source_material-edge". - > Påbegynt: 2026-03-18T08:00 +- [x] 20.2 source_material edge-type: legg til i edge-skjema + maskinrommet-validering. Støtt kontekst-metadata (quoted, summarized, referenced) og excerpt-felt. Ref: `docs/retninger/arbeidsflaten.md` § "source_material-edge". - [ ] 20.3 BlockReceiver interface: implementer `canReceive()`, `receive()`, `renderDropZone()` i alle trait-komponenter (Chat, Kanban, Kalender, Editor, Studio). Kompatibilitetsmatrise bestemmer godkjente drops. Ref: `docs/features/universell_overfoering.md` § 4–5. - [ ] 20.4 Transfer service: `innholdstransfer`-modus (ny node + source_material edge) og `lettvekts-triage` (eksisterende node + ny edge/placement). Bestem modus fra verktøy-par. Shift-modifier for override. Ref: `docs/features/universell_overfoering.md` § 1, 3. - [ ] 20.5 Panelrework — Chat: gjør ChatTrait til fullverdig BlockShell-panel med BlockReceiver, fullskjerm-toggle, og responsivt design innenfor begrenset container.