Skip to main content

khive_storage/
graph.rs

1//! Graph storage capability — edge CRUD and traversal.
2
3use async_trait::async_trait;
4use uuid::Uuid;
5
6use crate::types::{
7    BatchWriteSummary, DeleteMode, Edge, EdgeFilter, EdgeSortField, GraphPath, LinkId, NeighborHit,
8    NeighborQuery, Page, PageRequest, SortOrder, StorageResult, TraversalRequest,
9};
10
11/// Directed edge CRUD and graph traversal over the knowledge graph.
12#[async_trait]
13pub trait GraphStore: Send + Sync + 'static {
14    /// Insert or update a single edge.
15    async fn upsert_edge(&self, edge: Edge) -> StorageResult<()>;
16    /// Insert or update a batch of edges.
17    async fn upsert_edges(&self, edges: Vec<Edge>) -> StorageResult<BatchWriteSummary>;
18    /// Fetch an edge by link ID, returning `None` if absent. Filters soft-deleted rows.
19    async fn get_edge(&self, id: LinkId) -> StorageResult<Option<Edge>>;
20    /// Fetch an edge by link ID including soft-deleted rows. Used by the runtime hard-delete path
21    /// to locate and namespace-check an already-soft-deleted edge before purging it.
22    async fn get_edge_including_deleted(&self, id: LinkId) -> StorageResult<Option<Edge>>;
23    /// Delete an edge by link ID using the specified delete mode.
24    async fn delete_edge(&self, id: LinkId, mode: DeleteMode) -> StorageResult<bool>;
25    /// Query edges with filter, sort, and pagination.
26    async fn query_edges(
27        &self,
28        filter: EdgeFilter,
29        sort: Vec<SortOrder<EdgeSortField>>,
30        page: PageRequest,
31    ) -> StorageResult<Page<Edge>>;
32    /// Count edges matching the given filter.
33    async fn count_edges(&self, filter: EdgeFilter) -> StorageResult<u64>;
34    /// Return immediate neighbors of a graph node.
35    async fn neighbors(
36        &self,
37        node_id: Uuid,
38        query: NeighborQuery,
39    ) -> StorageResult<Vec<NeighborHit>>;
40    /// Multi-hop BFS traversal from the given roots.
41    async fn traverse(&self, request: TraversalRequest) -> StorageResult<Vec<GraphPath>>;
42    /// Hard-delete every incident edge (source or target) for `node_id`, regardless of soft-delete
43    /// state. Used during endpoint hard-delete to prevent dangling `graph_edges` rows (ADR-002
44    /// no-dangling-references contract).
45    async fn purge_incident_edges(&self, node_id: Uuid) -> StorageResult<u64>;
46}