Skip to main content

agent_office/storage/
mod.rs

1use crate::domain::{Edge, GraphQuery, Node, NodeId};
2use async_trait::async_trait;
3use thiserror::Error;
4use chrono::{DateTime, Utc};
5
6/// Advanced search query with full-text, time range, and pagination support
7#[derive(Debug, Clone)]
8pub struct SearchQuery {
9    /// Node types to search (e.g., "mail", "note", "agent")
10    pub node_types: Vec<String>,
11    /// Full-text search pattern (PostgreSQL tsquery compatible)
12    pub search_text: Option<String>,
13    /// Created/modified after this time
14    pub created_after: Option<DateTime<Utc>>,
15    /// Created/modified before this time
16    pub created_before: Option<DateTime<Utc>>,
17    /// Updated after this time
18    pub updated_after: Option<DateTime<Utc>>,
19    /// Property filters
20    pub property_filters: Vec<(String, String)>,
21    /// Maximum results to return
22    pub limit: usize,
23    /// Offset for pagination
24    pub offset: usize,
25}
26
27
28
29impl Default for SearchQuery {
30    fn default() -> Self {
31        Self {
32            node_types: vec![],
33            search_text: None,
34            created_after: None,
35            created_before: None,
36            updated_after: None,
37            property_filters: vec![],
38            limit: 50,
39            offset: 0,
40        }
41    }
42}
43
44/// Search results with pagination info
45#[derive(Debug, Clone)]
46pub struct SearchResults<T> {
47    pub items: Vec<T>,
48}
49
50#[derive(Error, Debug)]
51pub enum StorageError {
52    #[error("Node not found: {0}")]
53    NodeNotFound(NodeId),
54    
55    #[error("Database error: {0}")]
56    DatabaseError(String),
57    
58    #[error("Serialization error: {0}")]
59    SerializationError(String),
60    
61    #[error("Constraint violation: {0}")]
62    ConstraintViolation(String),
63}
64
65pub type Result<T> = std::result::Result<T, StorageError>;
66
67#[async_trait]
68pub trait GraphStorage: Send + Sync {
69    // Node operations
70    async fn create_node(&self, node: &Node) -> Result<Node>;
71    async fn get_node(&self, id: NodeId) -> Result<Node>;
72    async fn update_node(&self, node: &Node) -> Result<Node>;
73    async fn delete_node(&self, id: NodeId) -> Result<()>;
74    async fn query_nodes(&self, query: &GraphQuery) -> Result<Vec<Node>>;
75    
76    // Edge operations
77    async fn create_edge(&self, edge: &Edge) -> Result<Edge>;
78    async fn get_edges_from(&self, node_id: NodeId, edge_type: Option<&str>) -> Result<Vec<Edge>>;
79    async fn get_edges_to(&self, node_id: NodeId, edge_type: Option<&str>) -> Result<Vec<Edge>>;
80    
81    // Graph traversal
82    async fn get_neighbors(
83        &self,
84        node_id: NodeId,
85        edge_type: Option<&str>,
86        direction: EdgeDirection,
87    ) -> Result<Vec<Node>>;
88    
89    // Advanced search with full-text, time range, and pagination
90    async fn search_nodes(&self, query: &SearchQuery) -> Result<SearchResults<Node>>;
91}
92
93#[derive(Debug, Clone, Copy, PartialEq)]
94pub enum EdgeDirection {
95    Outgoing,
96    Incoming,
97}
98
99pub mod memory;
100pub mod postgres;