diff --git a/maskinrommet/src/ws.rs b/maskinrommet/src/ws.rs index 3aaa309..9081b38 100644 --- a/maskinrommet/src/ws.rs +++ b/maskinrommet/src/ws.rs @@ -490,7 +490,7 @@ async fn handle_socket(mut socket: WebSocket, user: WsUser, state: crate::AppSta result = rx.recv() => { match result { Ok(event) => { - let should_send = should_send_to_user(&event, user_id, &visible_nodes).await; + let should_send = should_send_to_user(&event, user_id, &visible_nodes, &state.db).await; if should_send { // Oppdater tilgangsmatrise ved access-endringer if let BroadcastEvent::AccessChanged { ref op, subject_id, object_id, .. } = event { @@ -557,11 +557,31 @@ async fn should_send_to_user( event: &BroadcastEvent, user_id: Uuid, visible_nodes: &tokio::sync::RwLock>, + db: &sqlx::PgPool, ) -> bool { match event { - BroadcastEvent::NodeChanged { id, .. } => { - let vn = visible_nodes.read().await; - vn.contains(id) + BroadcastEvent::NodeChanged { op, id, .. } => { + // Eksisterende noder: bruk cache (raskt) + { + let vn = visible_nodes.read().await; + if vn.contains(id) { + return true; + } + } + // Nye noder: sjekk PG direkte (access kan ha blitt propagert + // i samme transaksjon som node-opprettelsen) + if op == "INSERT" { + let has_access = sqlx::query_scalar::<_, bool>( + "SELECT EXISTS(SELECT 1 FROM node_access WHERE subject_id = $1 AND object_id = $2) OR EXISTS(SELECT 1 FROM nodes WHERE id = $2 AND created_by = $1)" + ).bind(user_id).bind(id) + .fetch_one(db).await.unwrap_or(false); + if has_access { + let mut vn = visible_nodes.write().await; + vn.insert(*id); + } + return has_access; + } + false } BroadcastEvent::EdgeChanged { source_id, target_id, .. } => { let vn = visible_nodes.read().await; diff --git a/scripts/chat-reply.sh b/scripts/chat-reply.sh new file mode 100755 index 0000000..205cf29 --- /dev/null +++ b/scripts/chat-reply.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Skriv en melding til en chat som Claude Code. +# Bruker PG direkte med access-propagering. +# +# Bruk: ./scripts/chat-reply.sh "" + +set -euo pipefail + +CHAT_ID="${1:?Mangler chat-id}" +MESSAGE="${2:?Mangler melding}" +CLAUDE_ID="d3eebc99-9c0b-4ef8-bb6d-6bb9bd380a44" + +# Skriv melding + edge + propager access til alle chat-deltakere +docker exec sidelinja-postgres-1 psql -U sidelinja -d synops -q -c " +DO \$\$ +DECLARE + new_id UUID := gen_random_uuid(); + new_edge UUID := gen_random_uuid(); + member_rec RECORD; +BEGIN + -- Opprett meldings-node + INSERT INTO nodes (id, node_kind, content, visibility, created_by) + VALUES (new_id, 'content', '$MESSAGE', 'hidden', '$CLAUDE_ID'); + + -- belongs_to-edge til chatten + INSERT INTO edges (id, source_id, target_id, edge_type) + VALUES (new_edge, new_id, '$CHAT_ID', 'belongs_to'); + + -- Propager access til alle deltakere i chatten + FOR member_rec IN + SELECT e.source_id FROM edges e + WHERE e.target_id = '$CHAT_ID' + AND e.edge_type IN ('owner', 'member_of') + LOOP + INSERT INTO node_access (subject_id, object_id, access, via_edge) + VALUES (member_rec.source_id, new_id, 'reader', new_edge) + ON CONFLICT DO NOTHING; + END LOOP; +END \$\$; +" + +echo "Svar sendt til chat $CHAT_ID"