Skip to main content

khive_storage/
event.rs

1//! Event storage capability — append-only operation log (ADR-004).
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use uuid::Uuid;
7
8use khive_types::{EventOutcome, SubstrateKind};
9
10use crate::types::{BatchWriteSummary, Page, PageRequest, StorageResult};
11
12/// Storage-level event record. Every verb execution produces one.
13/// Immutable once appended — no update or soft-delete.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct Event {
16    pub id: Uuid,
17    pub namespace: String,
18    pub verb: String,
19    pub substrate: SubstrateKind,
20    pub actor: String,
21    pub outcome: EventOutcome,
22    pub data: Option<Value>,
23    pub duration_us: i64,
24    pub target_id: Option<Uuid>,
25    pub created_at: i64,
26}
27
28impl Event {
29    pub fn new(
30        namespace: impl Into<String>,
31        verb: impl Into<String>,
32        substrate: SubstrateKind,
33        actor: impl Into<String>,
34    ) -> Self {
35        Self {
36            id: Uuid::new_v4(),
37            namespace: namespace.into(),
38            verb: verb.into(),
39            substrate,
40            actor: actor.into(),
41            outcome: EventOutcome::Success,
42            data: None,
43            duration_us: 0,
44            target_id: None,
45            created_at: chrono::Utc::now().timestamp_micros(),
46        }
47    }
48
49    pub fn with_outcome(mut self, o: EventOutcome) -> Self {
50        self.outcome = o;
51        self
52    }
53
54    pub fn with_data(mut self, d: Value) -> Self {
55        self.data = Some(d);
56        self
57    }
58
59    pub fn with_duration_us(mut self, us: i64) -> Self {
60        self.duration_us = us;
61        self
62    }
63
64    pub fn with_target(mut self, id: Uuid) -> Self {
65        self.target_id = Some(id);
66        self
67    }
68}
69
70/// Filter for querying events.
71#[derive(Clone, Debug, Default, Serialize, Deserialize)]
72pub struct EventFilter {
73    pub ids: Vec<Uuid>,
74    pub verbs: Vec<String>,
75    pub substrates: Vec<SubstrateKind>,
76    pub actors: Vec<String>,
77    pub namespaces: Vec<String>,
78    pub after: Option<i64>,
79    pub before: Option<i64>,
80}
81
82#[async_trait]
83pub trait EventStore: Send + Sync + 'static {
84    async fn append_event(&self, event: Event) -> StorageResult<()>;
85    async fn append_events(&self, events: Vec<Event>) -> StorageResult<BatchWriteSummary>;
86    async fn get_event(&self, id: Uuid) -> StorageResult<Option<Event>>;
87    async fn query_events(
88        &self,
89        filter: EventFilter,
90        page: PageRequest,
91    ) -> StorageResult<Page<Event>>;
92    async fn count_events(&self, filter: EventFilter) -> StorageResult<u64>;
93}