agent_office/domain/
mod.rs1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4pub type NodeId = uuid::Uuid;
5pub type EdgeId = uuid::Uuid;
6pub type Timestamp = chrono::DateTime<chrono::Utc>;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9#[serde(rename_all = "snake_case")]
10pub enum PropertyValue {
11 String(String),
12 Integer(i64),
13 Float(f64),
14 Boolean(bool),
15 Timestamp(Timestamp),
16 List(Vec<PropertyValue>),
17 Map(HashMap<String, PropertyValue>),
18 Null,
19}
20
21pub type Properties = HashMap<String, PropertyValue>;
22
23impl PropertyValue {
24 pub fn as_str(&self) -> Option<&str> {
25 match self {
26 PropertyValue::String(s) => Some(s.as_str()),
27 _ => None,
28 }
29 }
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
33pub struct Node {
34 pub id: NodeId,
35 pub node_type: String,
36 pub properties: Properties,
37 pub created_at: Timestamp,
38 pub updated_at: Timestamp,
39}
40
41impl Node {
42 pub fn new(node_type: impl Into<String>, properties: Properties) -> Self {
43 let now = chrono::Utc::now();
44 Self {
45 id: NodeId::new_v4(),
46 node_type: node_type.into(),
47 properties,
48 created_at: now,
49 updated_at: now,
50 }
51 }
52
53 pub fn get_property(&self, key: &str) -> Option<&PropertyValue> {
54 self.properties.get(key)
55 }
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
59pub struct Edge {
60 pub id: EdgeId,
61 pub edge_type: String,
62 pub from_node_id: NodeId,
63 pub to_node_id: NodeId,
64 pub properties: Properties,
65 pub created_at: Timestamp,
66}
67
68impl Edge {
69 pub fn new(
70 edge_type: impl Into<String>,
71 from_node_id: NodeId,
72 to_node_id: NodeId,
73 properties: Properties,
74 ) -> Self {
75 Self {
76 id: EdgeId::new_v4(),
77 edge_type: edge_type.into(),
78 from_node_id,
79 to_node_id,
80 properties,
81 created_at: chrono::Utc::now(),
82 }
83 }
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct GraphQuery {
88 pub node_types: Option<Vec<String>>,
89 pub edge_types: Option<Vec<String>>,
90 pub property_filters: Option<HashMap<String, PropertyValue>>,
91 pub limit: Option<usize>,
92}
93
94impl GraphQuery {
95 pub fn new() -> Self {
96 Self {
97 node_types: None,
98 edge_types: None,
99 property_filters: None,
100 limit: None,
101 }
102 }
103
104 pub fn with_node_type(mut self, node_type: impl Into<String>) -> Self {
105 self.node_types = Some(vec![node_type.into()]);
106 self
107 }
108}
109
110impl Default for GraphQuery {
111 fn default() -> Self {
112 Self::new()
113 }
114}
115
116pub fn string_to_node_id(s: &str) -> NodeId {
119 let namespace = uuid::Uuid::from_bytes([
122 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
123 0xc8,
124 ]);
125 uuid::Uuid::new_v5(&namespace, s.as_bytes())
126}