synops-respond: node+edge+access i én transaksjon for sanntid

PG NOTIFY fyrer ved COMMIT. Når alt skrives i én transaksjon
eksisterer node_access allerede når WS mottar node_changed,
og kan levere noden til alle deltakere i sanntid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-20 06:32:31 +00:00
parent 6cf421dbc7
commit 6be0bfdfb0

View file

@ -511,7 +511,12 @@ async fn write_to_db(
let edge_id = Uuid::now_v7(); let edge_id = Uuid::now_v7();
let metadata = serde_json::json!({}); let metadata = serde_json::json!({});
// Svar-node // Alt i én transaksjon: node + edge + access.
// PG NOTIFY fyrer ved COMMIT — da eksisterer access allerede,
// og WS kan levere noden til alle deltakere i sanntid.
let mut tx = db.begin().await
.map_err(|e| format!("Kunne ikke starte transaksjon: {e}"))?;
sqlx::query( sqlx::query(
"INSERT INTO nodes (id, node_kind, content, visibility, metadata, created_by) \ "INSERT INTO nodes (id, node_kind, content, visibility, metadata, created_by) \
VALUES ($1, 'content', $2, 'hidden'::visibility, $3, $4)", VALUES ($1, 'content', $2, 'hidden'::visibility, $3, $4)",
@ -520,13 +525,10 @@ async fn write_to_db(
.bind(response_text) .bind(response_text)
.bind(&metadata) .bind(&metadata)
.bind(agent_node_id) .bind(agent_node_id)
.execute(db) .execute(&mut *tx)
.await .await
.map_err(|e| format!("PG insert svar-node feilet: {e}"))?; .map_err(|e| format!("PG insert svar-node feilet: {e}"))?;
tracing::info!(reply_node_id = %reply_id, "Svar-node opprettet");
// belongs_to-edge: svar → kommunikasjonsnode
sqlx::query( sqlx::query(
"INSERT INTO edges (id, source_id, target_id, edge_type, metadata, system, created_by) \ "INSERT INTO edges (id, source_id, target_id, edge_type, metadata, system, created_by) \
VALUES ($1, $2, $3, 'belongs_to', '{}', false, $4)", VALUES ($1, $2, $3, 'belongs_to', '{}', false, $4)",
@ -535,11 +537,10 @@ async fn write_to_db(
.bind(reply_id) .bind(reply_id)
.bind(communication_id) .bind(communication_id)
.bind(agent_node_id) .bind(agent_node_id)
.execute(db) .execute(&mut *tx)
.await .await
.map_err(|e| format!("PG insert belongs_to-edge feilet: {e}"))?; .map_err(|e| format!("PG insert belongs_to-edge feilet: {e}"))?;
// Propager access: alle deltakere i chatten får lesetilgang til svaret
sqlx::query( sqlx::query(
"INSERT INTO node_access (subject_id, object_id, access, via_edge) "INSERT INTO node_access (subject_id, object_id, access, via_edge)
SELECT e.source_id, $1, 'reader', $2 SELECT e.source_id, $1, 'reader', $2
@ -551,11 +552,14 @@ async fn write_to_db(
.bind(reply_id) .bind(reply_id)
.bind(edge_id) .bind(edge_id)
.bind(communication_id) .bind(communication_id)
.execute(db) .execute(&mut *tx)
.await .await
.map_err(|e| format!("PG access-propagering feilet: {e}"))?; .map_err(|e| format!("PG access-propagering feilet: {e}"))?;
tracing::info!(reply_node_id = %reply_id, "Access propagert til chat-deltakere"); tx.commit().await
.map_err(|e| format!("Kunne ikke committe transaksjon: {e}"))?;
tracing::info!(reply_node_id = %reply_id, "Svar + edge + access committet i én transaksjon");
// ai_usage_log // ai_usage_log
sqlx::query( sqlx::query(