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(
34 namespace: impl Into<String>,
35 kind: impl Into<String>,
36 name: impl Into<String>,
37 ) -> Self {
38 let now = chrono::Utc::now().timestamp_micros();
39 Self {
40 id: Uuid::new_v4(),
41 namespace: namespace.into(),
42 kind: kind.into(),
43 entity_type: None,
44 name: name.into(),
45 description: None,
46 properties: None,
47 tags: Vec::new(),
48 created_at: now,
49 updated_at: now,
50 deleted_at: None,
51 merged_into: None,
52 merge_event_id: None,
53 }
54 }
55
56 pub fn with_entity_type(mut self, t: Option<impl Into<String>>) -> Self {
57 self.entity_type = t.map(Into::into);
58 self
59 }
60
61 pub fn with_description(mut self, d: impl Into<String>) -> Self {
62 self.description = Some(d.into());
63 self
64 }
65
66 pub fn with_properties(mut self, p: Value) -> Self {
67 self.properties = Some(p);
68 self
69 }
70
71 pub fn with_tags(mut self, t: Vec<String>) -> Self {
72 self.tags = t;
73 self
74 }
75}
76
77#[derive(Clone, Debug, Default, Serialize, Deserialize)]
79pub struct EntityFilter {
80 pub ids: Vec<Uuid>,
81 pub kinds: Vec<String>,
82 pub entity_types: Vec<String>,
84 pub name_prefix: Option<String>,
85 pub tags_any: Vec<String>,
86}
87
88#[async_trait]
89pub trait EntityStore: Send + Sync + 'static {
90 async fn upsert_entity(&self, entity: Entity) -> StorageResult<()>;
91 async fn upsert_entities(&self, entities: Vec<Entity>) -> StorageResult<BatchWriteSummary>;
92 async fn get_entity(&self, id: Uuid) -> StorageResult<Option<Entity>>;
93 async fn delete_entity(&self, id: Uuid, mode: DeleteMode) -> StorageResult<bool>;
94 async fn query_entities(
95 &self,
96 namespace: &str,
97 filter: EntityFilter,
98 page: PageRequest,
99 ) -> StorageResult<Page<Entity>>;
100 async fn count_entities(&self, namespace: &str, filter: EntityFilter) -> StorageResult<u64>;
101}