1use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use uuid::Uuid;
7
8use crate::types::{BatchWriteSummary, DeleteMode, Page, PageRequest, StorageResult};
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
13pub struct Entity {
14 pub id: Uuid,
15 pub namespace: String,
16 pub kind: String,
17 pub entity_type: Option<String>,
19 pub name: String,
20 pub description: Option<String>,
21 pub properties: Option<Value>,
22 pub tags: Vec<String>,
23 pub created_at: i64,
24 pub updated_at: i64,
25 pub deleted_at: Option<i64>,
26 pub merged_into: Option<Uuid>,
28 pub merge_event_id: Option<Uuid>,
30}
31
32impl Entity {
33 pub fn new(
35 namespace: impl Into<String>,
36 kind: impl Into<String>,
37 name: impl Into<String>,
38 ) -> Self {
39 let now = chrono::Utc::now().timestamp_micros();
40 Self {
41 id: Uuid::new_v4(),
42 namespace: namespace.into(),
43 kind: kind.into(),
44 entity_type: None,
45 name: name.into(),
46 description: None,
47 properties: None,
48 tags: Vec::new(),
49 created_at: now,
50 updated_at: now,
51 deleted_at: None,
52 merged_into: None,
53 merge_event_id: None,
54 }
55 }
56
57 pub fn with_entity_type(mut self, t: Option<impl Into<String>>) -> Self {
59 self.entity_type = t.map(Into::into);
60 self
61 }
62
63 pub fn with_description(mut self, d: impl Into<String>) -> Self {
65 self.description = Some(d.into());
66 self
67 }
68
69 pub fn with_properties(mut self, p: Value) -> Self {
71 self.properties = Some(p);
72 self
73 }
74
75 pub fn with_tags(mut self, t: Vec<String>) -> Self {
77 self.tags = t;
78 self
79 }
80}
81
82#[derive(Clone, Debug, Default, Serialize, Deserialize)]
84pub struct EntityFilter {
85 pub ids: Vec<Uuid>,
86 pub kinds: Vec<String>,
87 pub entity_types: Vec<String>,
89 pub name_prefix: Option<String>,
90 pub tags_any: Vec<String>,
91}
92
93#[async_trait]
95pub trait EntityStore: Send + Sync + 'static {
96 async fn upsert_entity(&self, entity: Entity) -> StorageResult<()>;
98 async fn upsert_entities(&self, entities: Vec<Entity>) -> StorageResult<BatchWriteSummary>;
100 async fn get_entity(&self, id: Uuid) -> StorageResult<Option<Entity>>;
102 async fn delete_entity(&self, id: Uuid, mode: DeleteMode) -> StorageResult<bool>;
104 async fn query_entities(
106 &self,
107 namespace: &str,
108 filter: EntityFilter,
109 page: PageRequest,
110 ) -> StorageResult<Page<Entity>>;
111 async fn count_entities(&self, namespace: &str, filter: EntityFilter) -> StorageResult<u64>;
113}