Skip to main content

relay_knowledge/storage/contracts/
graph.rs

1use serde::{Deserialize, Serialize};
2
3use crate::domain::{CommitReceipt, GraphMutationBatch, GraphVersion};
4
5use super::{
6    GraphCanvasStorageRequest, GraphCanvasStorageSnapshot, GraphInspection, GraphSearchOutcome,
7    GraphSearchRequest, HealthStorageSnapshot, StorageError, StorageFuture,
8};
9
10/// Graph fact persistence and query contract.
11pub trait GraphStore: Send + Sync {
12    fn commit_mutation_batch(&self, batch: GraphMutationBatch) -> StorageFuture<'_, CommitReceipt>;
13
14    fn inspect_graph(&self) -> StorageFuture<'_, GraphInspection>;
15
16    fn health_snapshot(&self, _now_ms: u64) -> StorageFuture<'_, HealthStorageSnapshot> {
17        Box::pin(async {
18            Err(StorageError::InvalidInput(
19                "health snapshot storage is unavailable".to_owned(),
20            ))
21        })
22    }
23
24    fn graph_canvas(
25        &self,
26        _request: GraphCanvasStorageRequest,
27    ) -> StorageFuture<'_, GraphCanvasStorageSnapshot> {
28        Box::pin(async {
29            Err(StorageError::InvalidInput(
30                "graph canvas storage is unavailable".to_owned(),
31            ))
32        })
33    }
34
35    fn search(&self, request: GraphSearchRequest) -> StorageFuture<'_, GraphSearchOutcome>;
36
37    fn current_graph_version(&self) -> StorageFuture<'_, GraphVersion>;
38}
39
40/// Mutation log contract consumed by reconcilers and indexers.
41pub trait MutationLogStore: Send + Sync {
42    fn read_after(
43        &self,
44        graph_version: GraphVersion,
45        limit: usize,
46    ) -> StorageFuture<'_, Vec<MutationLogEntry>>;
47}
48
49/// Mutation log entry returned for replay and index refresh planning.
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
51pub struct MutationLogEntry {
52    pub graph_version: GraphVersion,
53    pub evidence_count: usize,
54    pub entity_count: usize,
55    pub relation_count: usize,
56    pub claim_count: usize,
57    pub event_count: usize,
58    pub affected_scopes: Vec<String>,
59    pub affected_entity_ids: Vec<String>,
60    pub evidence_ids: Vec<String>,
61    pub source_hashes: Vec<String>,
62}
63
64#[cfg(test)]
65#[path = "graph_tests.rs"]
66mod tests;