1use crate::ids::{AccountId, AlertId, ConnectorId};
5use serde::{Deserialize, Serialize};
6use time::OffsetDateTime;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
9#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
10#[serde(rename_all = "snake_case")]
11pub enum Severity {
12 Info,
13 Warning,
14 Critical,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
18#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
19#[serde(rename_all = "snake_case")]
20pub enum AlertState {
21 Active,
22 Acknowledged,
23 Resolved,
24 Silenced,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
30pub struct Alert {
31 pub id: AlertId,
32 pub fingerprint: String,
35 pub severity: Severity,
36 pub title: String,
37 pub body: Option<String>,
38 pub connector: Option<ConnectorId>,
39 pub account: Option<AccountId>,
40 pub state: AlertState,
41 #[serde(with = "time::serde::rfc3339")]
42 #[cfg_attr(feature = "ts", ts(type = "string"))]
43 pub raised_at: OffsetDateTime,
44 #[serde(with = "time::serde::rfc3339::option")]
45 #[cfg_attr(feature = "ts", ts(type = "string | null"))]
46 pub resolved_at: Option<OffsetDateTime>,
47}
48
49impl Alert {
50 pub fn new(
51 fingerprint: impl Into<String>,
52 severity: Severity,
53 title: impl Into<String>,
54 raised_at: OffsetDateTime,
55 ) -> Self {
56 Self {
57 id: AlertId::generate(),
58 fingerprint: fingerprint.into(),
59 severity,
60 title: title.into(),
61 body: None,
62 connector: None,
63 account: None,
64 state: AlertState::Active,
65 raised_at,
66 resolved_at: None,
67 }
68 }
69
70 pub fn with_body(mut self, body: impl Into<String>) -> Self {
71 self.body = Some(body.into());
72 self
73 }
74
75 pub fn with_connector(mut self, connector: ConnectorId) -> Self {
76 self.connector = Some(connector);
77 self
78 }
79
80 pub fn is_visible(&self) -> bool {
82 matches!(self.state, AlertState::Active | AlertState::Acknowledged)
83 }
84
85 pub fn resolve(&mut self, at: OffsetDateTime) {
86 self.state = AlertState::Resolved;
87 self.resolved_at = Some(at);
88 }
89}