areev 0.2.0

Rust SDK for the Areev knowledge database — gRPC and HTTP transports
Documentation
//! `Scope` resource — hierarchical scope tree + scoped crypto-erasure.
//!
//! Mirrors the Python SDK's `client.scope.*` surface.

use serde_json::{json, Value};

use crate::error::Result;
use crate::http::HttpClient;
use crate::resources::grains::confirm_error;

/// Scope-tree management and scoped erasure.
///
/// Access via [`crate::Areev::scope`].
pub struct Scope<'a> {
    http: &'a HttpClient,
    memory_id: String,
}

impl<'a> Scope<'a> {
    /// Internal constructor — use [`crate::Areev::scope`].
    pub(crate) fn new(http: &'a HttpClient, memory_id: String) -> Self {
        Self { http, memory_id }
    }

    /// Read the memory's scope tree.
    pub async fn get_tree(&self) -> Result<Value> {
        let path = format!("/memories/{}/scope-tree", self.memory_id);
        self.http._get(&path, None).await
    }

    /// Replace the memory's scope tree. Requires: admin scope. Emits an
    /// audit event.
    pub async fn set_tree(&self, tree: Value) -> Result<Value> {
        let path = format!("/memories/{}/scope-tree", self.memory_id);
        self.http._put(&path, Some(&tree)).await
    }

    /// Delete the scope tree. Requires: admin scope. Emits an audit
    /// event.
    pub async fn delete_tree(&self) -> Result<()> {
        let path = format!("/memories/{}/scope-tree", self.memory_id);
        self.http._delete(&path).await.map(|_| ())
    }

    /// Crypto-erase every grain under `scope_path` (GDPR Art. 17).
    ///
    /// **IRREVERSIBLE.** Destroys the per-scope key material so the
    /// grains become permanently unrecoverable — there is no undo. Emits
    /// an audit event. Requires: admin scope.
    ///
    /// This is a data-subject-rights operation — always issued, never
    /// blocked by tier or credit gates. The body is excluded from SDK
    /// logging and the call is **not** auto-retried.
    ///
    /// # Errors
    ///
    /// Returns [`crate::AreevError::Validation`] (`SDK-E002`) when
    /// `confirm` is not `true`.
    pub async fn erase(&self, scope_path: &str, confirm: bool) -> Result<Value> {
        if !confirm {
            return Err(confirm_error("scope.erase"));
        }
        let body = json!({ "scope_path": scope_path });
        let path = format!("/memories/{}/scope-erase", self.memory_id);
        self.http._post_sensitive(&path, Some(&body), false).await
    }
}