Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions src/alerts/alert_structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,10 @@ pub struct StateTransition {
pub state: AlertState,
/// Timestamp when this state was set/updated
pub last_updated_at: DateTime<Utc>,
/// The previous alert state before this transition, if any
pub previous_alert_state: Option<AlertState>,
/// Duration in seconds
pub previous_state_duration: Option<i64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -768,10 +772,20 @@ pub struct AlertStateEntry {

impl StateTransition {
/// Creates a new state transition with the current timestamp
pub fn new(state: AlertState) -> Self {
pub fn new(
state: AlertState,
previous_alert_state: Option<AlertState>,
previous_alert_time: Option<DateTime<Utc>>,
) -> Self {
let now = Utc::now();
// calculate duration if previous alert time is provided
let previous_state_duration =
previous_alert_time.map(|alert_time| (now - alert_time).num_seconds());
Self {
state,
last_updated_at: Utc::now(),
last_updated_at: now,
previous_alert_state,
previous_state_duration,
}
}
}
Expand All @@ -781,7 +795,7 @@ impl AlertStateEntry {
pub fn new(alert_id: Ulid, initial_state: AlertState) -> Self {
Self {
alert_id,
states: vec![StateTransition::new(initial_state)],
states: vec![StateTransition::new(initial_state, None, None)],
}
}

Expand All @@ -792,7 +806,11 @@ impl AlertStateEntry {
Some(last_transition) => {
if last_transition.state != new_state {
// State changed - add new transition
self.states.push(StateTransition::new(new_state));
self.states.push(StateTransition::new(
new_state,
Some(last_transition.state),
Some(last_transition.last_updated_at),
));
true
} else {
// If state hasn't changed, do nothing - preserve the original timestamp
Expand All @@ -801,7 +819,8 @@ impl AlertStateEntry {
}
None => {
// No previous states - add the first one
self.states.push(StateTransition::new(new_state));
self.states
.push(StateTransition::new(new_state, None, None));
true
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/handlers/http/alerts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,19 @@ const MAX_LIMIT: usize = 1000;
const DEFAULT_LIMIT: usize = 100;

/// Query parameters for listing alerts
struct ListQueryParams {
tags_list: Vec<String>,
offset: usize,
limit: usize,
other_fields_filters: HashMap<String, String>,
pub struct ListQueryParams {
/// Comma-separated tag filters; empty if no tag filtering
pub tags_list: Vec<String>,
/// Number of results to skip (default: 0)
pub offset: usize,
/// Maximum results to return (1-1000, default: 100)
pub limit: usize,
/// Additional field filters not covered by reserved params
pub other_fields_filters: HashMap<String, String>,
}

/// Parse and validate query parameters for listing alerts
fn parse_list_query_params(
pub fn parse_list_query_params(
query_map: &HashMap<String, String>,
) -> Result<ListQueryParams, AlertError> {
let mut tags_list = Vec::new();
Expand Down
Loading