1use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use uuid::Uuid;
7
8use khive_types::EntityKind;
9
10use crate::types::{BatchWriteSummary, DeleteMode, Page, PageRequest, StorageResult};
11
12#[derive(Clone, Debug, Serialize, Deserialize)]
15pub struct Entity {
16 pub id: Uuid,
17 pub namespace: String,
18 pub kind: EntityKind,
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}
27
28impl Entity {
29 pub fn new(namespace: impl Into<String>, kind: EntityKind, name: impl Into<String>) -> Self {
30 let now = chrono::Utc::now().timestamp_micros();
31 Self {
32 id: Uuid::new_v4(),
33 namespace: namespace.into(),
34 kind,
35 name: name.into(),
36 description: None,
37 properties: None,
38 tags: Vec::new(),
39 created_at: now,
40 updated_at: now,
41 deleted_at: None,
42 }
43 }
44
45 pub fn with_description(mut self, d: impl Into<String>) -> Self {
46 self.description = Some(d.into());
47 self
48 }
49
50 pub fn with_properties(mut self, p: Value) -> Self {
51 self.properties = Some(p);
52 self
53 }
54
55 pub fn with_tags(mut self, t: Vec<String>) -> Self {
56 self.tags = t;
57 self
58 }
59}
60
61#[derive(Clone, Debug, Default, Serialize, Deserialize)]
63pub struct EntityFilter {
64 pub ids: Vec<Uuid>,
65 pub kinds: Vec<EntityKind>,
66 pub name_prefix: Option<String>,
67 pub tags_any: Vec<String>,
68}
69
70#[async_trait]
71pub trait EntityStore: Send + Sync + 'static {
72 async fn upsert_entity(&self, entity: Entity) -> StorageResult<()>;
73 async fn upsert_entities(&self, entities: Vec<Entity>) -> StorageResult<BatchWriteSummary>;
74 async fn get_entity(&self, id: Uuid) -> StorageResult<Option<Entity>>;
75 async fn delete_entity(&self, id: Uuid, mode: DeleteMode) -> StorageResult<bool>;
76 async fn query_entities(
77 &self,
78 namespace: &str,
79 filter: EntityFilter,
80 page: PageRequest,
81 ) -> StorageResult<Page<Entity>>;
82 async fn count_entities(&self, namespace: &str, filter: EntityFilter) -> StorageResult<u64>;
83}