Files

56 lines
2.5 KiB
Go
Raw Permalink Normal View History

package callmemory
import (
"context"
"github.com/jackc/pgx/v5"
)
// The caller holds memory_user_state before expanding or locking any memory.
// Resolve original provenance once: a derived provider summary may cover a
// whole call, but deleting it as a consequence must not enlarge the requested
// source deletion to unrelated utterances from that call.
func expandSourceDeletionTargets(ctx context.Context, tx pgx.Tx, access Access, requested []string) ([]string, error) {
rows, err := tx.Query(ctx, `WITH refs AS (
SELECT cm.id AS memory_id,r FROM curated_memory cm JOIN memory_version mv ON mv.memory_id=cm.id
CROSS JOIN LATERAL jsonb_array_elements(mv.source_refs) r
WHERE cm.subject_id=$1::uuid AND cm.tenant_id=$2::uuid AND cm.status<>'DELETED'
), origins AS (
SELECT memory_id,r->>'session_id' AS session_id,r->>'utterance_id' AS utterance_id,
NULL::uuid AS turn_id,r->>'story_id' AS story_id FROM refs
UNION ALL
SELECT refs.memory_id,ss.call_session_id::text,ss.call_utterance_id,ss.conversation_turn_id,NULL::text
FROM refs JOIN story_draft sd ON sd.public_id::text=r->>'story_id' AND sd.subject_id=$1::uuid
JOIN story_revision sr ON sr.story_id=sd.id JOIN story_source ss ON ss.story_revision_id=sr.id
), requested_origins AS (
SELECT o.* FROM origins o JOIN curated_memory cm ON cm.id=o.memory_id
WHERE cm.public_id IN(SELECT value::uuid FROM jsonb_array_elements_text($3::jsonb))
)
SELECT cm.public_id::text,cm.sensitivity FROM curated_memory cm
WHERE cm.subject_id=$1::uuid AND cm.tenant_id=$2::uuid AND cm.status<>'DELETED'
AND cm.public_id NOT IN(SELECT value::uuid FROM jsonb_array_elements_text($3::jsonb))
AND EXISTS(SELECT 1 FROM origins o JOIN requested_origins wanted ON
(o.story_id IS NOT NULL AND o.story_id=wanted.story_id) OR
(o.turn_id IS NOT NULL AND o.turn_id=wanted.turn_id) OR
(o.session_id IS NOT NULL AND o.session_id=wanted.session_id AND
(o.utterance_id IS NULL OR wanted.utterance_id IS NULL OR o.utterance_id=wanted.utterance_id))
WHERE o.memory_id=cm.id)
ORDER BY cm.id FOR UPDATE OF cm`, access.Subject, access.Tenant, jsonBytes(requested))
if err != nil {
return nil, err
}
defer rows.Close()
ids := append([]string{}, requested...)
for rows.Next() {
var id, sensitivity string
if err = rows.Scan(&id, &sensitivity); err != nil {
return nil, err
}
if sensitivity != "normal" && !access.Sensitive {
return nil, fault(403, "SENSITIVE_MEMORY_ACCESS_DENIED")
}
ids = append(ids, id)
}
return ids, rows.Err()
}