Skip to main content

DataSubjectService

Struct DataSubjectService 

Source
pub struct DataSubjectService {
    index: SqliteBackend,
    vector: Option<Arc<dyn VectorBackend + Send + Sync>>,
}
Expand description

Service for GDPR data subject rights operations.

Provides:

  • export_user_data(): Export all user data (Article 20)
  • delete_user_data(): Delete all user data (Article 17)

§Storage Layers

Operations affect all three storage layers:

  1. Persistence (SQLite) - Authoritative storage
  2. Index (SQLite FTS5) - Full-text search index
  3. Vector (usearch) - Embedding vectors

§Audit Logging

All operations are logged for compliance:

  • gdpr.export - Data export requests
  • gdpr.delete - Data deletion requests

Fields§

§index: SqliteBackend

SQLite index backend for listing and deleting memories.

§vector: Option<Arc<dyn VectorBackend + Send + Sync>>

Optional vector backend for deleting embeddings.

Implementations§

Source§

impl DataSubjectService

Source

pub const fn new(index: SqliteBackend) -> Self

Creates a new data subject service with an index backend.

§Arguments
  • index - SQLite index backend for memory operations
Source

pub fn with_vector(self, vector: Arc<dyn VectorBackend + Send + Sync>) -> Self

Adds a vector backend for complete deletion of embeddings.

Source

pub fn export_user_data(&self) -> Result<UserDataExport>

Exports all user data in a portable format.

Implements GDPR Article 20 (Right to Data Portability).

§Returns

A UserDataExport containing all memories in JSON-serializable format.

§Errors

Returns an error if:

  • The index backend fails to list memories
  • Memory retrieval fails
§Audit

Logs a gdpr.export event with the count of exported memories.

§Example
let service = DataSubjectService::new(index);
let export = service.export_user_data()?;

// Serialize to JSON for download
let json = serde_json::to_string_pretty(&export)?;
std::fs::write("my_data.json", json)?;
Source

pub fn delete_user_data(&self) -> Result<DeletionResult>

Deletes all user data from all storage layers.

Implements GDPR Article 17 (Right to Erasure / “Right to be Forgotten”).

§Storage Layers Affected
  1. Index (SQLite) - Memory metadata and FTS index
  2. Vector (usearch) - Embedding vectors (if configured)
  3. Persistence (SQLite) - Authoritative storage (if configured)
§Returns

A DeletionResult with counts and any failures.

§Errors

Returns an error if:

  • The index backend fails to list memories
  • Critical deletion operations fail

Note: Individual memory deletion failures are captured in the result rather than causing the entire operation to fail.

§Audit

Logs a gdpr.delete event with the count of deleted memories.

§Warning

This operation is irreversible. All user data will be permanently deleted.

§Example
let service = DataSubjectService::new(index)
    .with_vector(vector_backend);

let result = service.delete_user_data()?;

if result.complete {
    println!("Successfully deleted {} memories", result.deleted_count);
} else {
    eprintln!("Partial deletion: {} failed", result.failed_count);
}
Source

fn delete_memory_from_all_layers(&self, id: &MemoryId) -> Result<()>

Deletes a single memory from all storage layers.

§Deletion Order
  1. Vector backend (if configured) - Delete embedding
  2. SQLite Index - Delete from search index (authoritative)

Records consent for a specific purpose.

Implements GDPR Article 7 (Conditions for Consent).

§Arguments
  • record - The consent record to store
§Audit

Logs a gdpr.consent event with the purpose and grant status.

§Example
use subcog::services::{DataSubjectService, ConsentRecord, ConsentPurpose};

let service = DataSubjectService::new(index);
let record = ConsentRecord::grant(ConsentPurpose::DataStorage, "1.0")
    .with_method("cli");
service.record_consent(&record)?;
§Errors

Returns an error if consent recording fails.

Revokes consent for a specific purpose.

Creates a revocation record and logs the event for audit.

§Arguments
  • purpose - The purpose for which consent is being revoked
  • policy_version - The current policy version
§Audit

Logs a gdpr.consent_revoked event.

§Errors

Returns an error if consent revocation fails.

Checks if consent is granted for a specific purpose.

§Returns

true if consent is currently granted for the purpose.

§Note

Default implementation returns true for backward compatibility. Production systems should check persistent consent records.

Source

pub fn consent_status(&self) -> ConsentStatus

Returns the current consent status for all purposes.

§Returns

A ConsentStatus with the current state of all consents.

Logs a consent event to the audit log.

Source

fn log_export_event(memory_count: usize)

Logs an export event to the audit log.

Source

fn log_deletion_event(deleted_count: usize, failed_count: usize)

Logs a deletion event to the audit log.

Source

fn record_metrics( operation: &str, start: Instant, success_count: usize, failure_count: usize, )

Records metrics for the operation.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more