systemprompt_models/notifications/
event.rs1use chrono::{DateTime, Utc};
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use systemprompt_identifiers::{NotificationStreamId, UserId};
10
11use super::attention::Attention;
12use super::kind::NotificationKind;
13use super::subject::SubjectRef;
14
15pub const NOTIFICATIONS_CONSUMER: &str = "notifications";
16pub const NOTIFICATION_EVENT_VERSION: u32 = 1;
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
20pub struct DirectRecipient {
21 pub user: UserId,
22 pub attention: Option<Attention>,
23}
24
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
27pub struct NotificationEvent {
28 pub kind: NotificationKind,
29 pub actor: UserId,
30 pub actor_is_agent: bool,
31 pub via_agent: Option<String>,
32 pub subjects: Vec<SubjectRef>,
33 pub stream: Option<NotificationStreamId>,
34 pub direct_recipients: Vec<DirectRecipient>,
35 pub sender_attention: Option<Attention>,
36 pub excerpt: Option<String>,
37 pub payload: serde_json::Value,
39 pub occurred_at: DateTime<Utc>,
40}
41
42impl NotificationEvent {
43 #[must_use]
44 pub const fn new(kind: NotificationKind, actor: UserId, occurred_at: DateTime<Utc>) -> Self {
45 Self {
46 kind,
47 actor,
48 actor_is_agent: false,
49 via_agent: None,
50 subjects: Vec::new(),
51 stream: None,
52 direct_recipients: Vec::new(),
53 sender_attention: None,
54 excerpt: None,
55 payload: serde_json::Value::Null,
56 occurred_at,
57 }
58 }
59
60 #[must_use]
61 pub const fn with_actor_is_agent(mut self, actor_is_agent: bool) -> Self {
62 self.actor_is_agent = actor_is_agent;
63 self
64 }
65
66 #[must_use]
67 pub fn with_via_agent(mut self, via_agent: impl Into<String>) -> Self {
68 self.via_agent = Some(via_agent.into());
69 self
70 }
71
72 #[must_use]
73 pub fn with_subject(mut self, subject: SubjectRef) -> Self {
74 self.subjects.push(subject);
75 self
76 }
77
78 #[must_use]
79 pub fn with_subjects(mut self, subjects: impl IntoIterator<Item = SubjectRef>) -> Self {
80 self.subjects.extend(subjects);
81 self
82 }
83
84 #[must_use]
85 pub fn with_stream(mut self, stream: NotificationStreamId) -> Self {
86 self.stream = Some(stream);
87 self
88 }
89
90 #[must_use]
91 pub fn with_direct_recipient(mut self, user: UserId, attention: Option<Attention>) -> Self {
92 self.direct_recipients
93 .push(DirectRecipient { user, attention });
94 self
95 }
96
97 #[must_use]
98 pub fn with_direct_recipients(
99 mut self,
100 recipients: impl IntoIterator<Item = DirectRecipient>,
101 ) -> Self {
102 self.direct_recipients.extend(recipients);
103 self
104 }
105
106 #[must_use]
107 pub const fn with_sender_attention(mut self, attention: Attention) -> Self {
108 self.sender_attention = Some(attention);
109 self
110 }
111
112 #[must_use]
113 pub fn with_excerpt(mut self, excerpt: impl Into<String>) -> Self {
114 self.excerpt = Some(excerpt.into());
115 self
116 }
117
118 #[must_use]
119 pub fn with_payload(mut self, payload: serde_json::Value) -> Self {
121 self.payload = payload;
122 self
123 }
124}