Skip to content

Commit 964e71c

Browse files
committed
Refactor alerts API into modular route files
Split the monolithic alerts.rs file into multiple focused modules: actions, app_alerts, auto_resolve, bulk, create, escalation, get, list, org_alerts, search, types, and update. This improves maintainability and clarity by grouping related API endpoints and types into separate files. Also applied similar modularization to audit_log.rs. No functional changes to endpoint logic.
1 parent 227e01b commit 964e71c

File tree

19 files changed

+1466
-1350
lines changed

19 files changed

+1466
-1350
lines changed

src/schemas/v1/api/alerts.rs

Lines changed: 0 additions & 1116 deletions
This file was deleted.
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
use super::super::db::queries as db;
2+
use super::types::{AcknowledgeAlertRequest, CreateEscalationRequest};
3+
use rocket::http::Status;
4+
use rocket::serde::json::{json, Json, Value};
5+
use rocket::{post, State};
6+
use std::collections::HashMap;
7+
use std::sync::Arc;
8+
use crate::DatabaseManager;
9+
10+
use libomni::types::db::v1 as types;
11+
use types::user::User;
12+
13+
/// Acknowledge an alert
14+
#[post("/platform/<platform_id>/alerts/<id>/acknowledge", format = "json", data = "<ack_data>")]
15+
pub async fn acknowledge_alert(
16+
platform_id: i64,
17+
id: i64,
18+
ack_data: Json<AcknowledgeAlertRequest>,
19+
user: User, // Extract user from request guard
20+
db_manager: &State<Arc<DatabaseManager>>,
21+
) -> Result<Json<Value>, (Status, Json<Value>)> {
22+
// Get platform information
23+
let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
24+
Ok(platform) => platform,
25+
Err(_) => {
26+
return Err((
27+
Status::NotFound,
28+
Json(json!({
29+
"error": "Platform not found",
30+
"message": format!("Platform with ID {} does not exist", platform_id)
31+
}))
32+
));
33+
}
34+
};
35+
36+
// Get platform-specific database pool
37+
let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
38+
Ok(pool) => pool,
39+
Err(_) => {
40+
return Err((
41+
Status::InternalServerError,
42+
Json(json!({
43+
"error": "Database error",
44+
"message": "Failed to connect to platform database"
45+
}))
46+
));
47+
}
48+
};
49+
50+
let data = ack_data.into_inner();
51+
52+
let acknowledgment = match db::alert::acknowledge_alert(
53+
&pool,
54+
id,
55+
user.id,
56+
data.notes.as_deref(),
57+
data.update_status,
58+
).await {
59+
Ok(ack) => ack,
60+
Err(e) => {
61+
log::error!("Failed to acknowledge alert: {}", e);
62+
return Err((
63+
if e.to_string().contains("no rows") {
64+
Status::NotFound
65+
} else {
66+
Status::InternalServerError
67+
},
68+
Json(json!({
69+
"error": if e.to_string().contains("no rows") { "Alert not found" } else { "Database error" },
70+
"message": if e.to_string().contains("no rows") {
71+
format!("Alert with ID {} does not exist", id)
72+
} else {
73+
"Failed to acknowledge alert".to_string()
74+
}
75+
}))
76+
));
77+
}
78+
};
79+
80+
Ok(Json(json!({
81+
"message": "Alert acknowledged successfully",
82+
"acknowledgment": acknowledgment
83+
})))
84+
}
85+
86+
/// Resolve an alert
87+
#[post("/platform/<platform_id>/alerts/<id>/resolve", format = "json", data = "<resolve_data>")]
88+
pub async fn resolve_alert(
89+
platform_id: i64,
90+
id: i64,
91+
resolve_data: Option<Json<HashMap<String, String>>>,
92+
user: User, // Extract user from request guard
93+
db_manager: &State<Arc<DatabaseManager>>,
94+
) -> Result<Json<Value>, (Status, Json<Value>)> {
95+
// Get platform information
96+
let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
97+
Ok(platform) => platform,
98+
Err(_) => {
99+
return Err((
100+
Status::NotFound,
101+
Json(json!({
102+
"error": "Platform not found",
103+
"message": format!("Platform with ID {} does not exist", platform_id)
104+
}))
105+
));
106+
}
107+
};
108+
109+
// Get platform-specific database pool
110+
let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
111+
Ok(pool) => pool,
112+
Err(_) => {
113+
return Err((
114+
Status::InternalServerError,
115+
Json(json!({
116+
"error": "Database error",
117+
"message": "Failed to connect to platform database"
118+
}))
119+
));
120+
}
121+
};
122+
123+
// Extract notes if provided
124+
let notes = resolve_data
125+
.and_then(|data| data.get("notes").cloned());
126+
127+
let resolved_alert = match db::alert::resolve_alert(
128+
&pool,
129+
id,
130+
user.id,
131+
notes.as_deref(),
132+
).await {
133+
Ok(alert) => alert,
134+
Err(e) => {
135+
log::error!("Failed to resolve alert: {}", e);
136+
return Err((
137+
if e.to_string().contains("no rows") {
138+
Status::NotFound
139+
} else {
140+
Status::InternalServerError
141+
},
142+
Json(json!({
143+
"error": if e.to_string().contains("no rows") { "Alert not found" } else { "Database error" },
144+
"message": if e.to_string().contains("no rows") {
145+
format!("Alert with ID {} does not exist", id)
146+
} else {
147+
"Failed to resolve alert".to_string()
148+
}
149+
}))
150+
));
151+
}
152+
};
153+
154+
Ok(Json(json!({
155+
"message": "Alert resolved successfully",
156+
"alert": resolved_alert
157+
})))
158+
}
159+
160+
/// Create an escalation for an alert
161+
#[post("/platform/<platform_id>/alerts/<id>/escalate", format = "json", data = "<escalation_data>")]
162+
pub async fn escalate_alert(
163+
platform_id: i64,
164+
id: i64,
165+
escalation_data: Json<CreateEscalationRequest>,
166+
db_manager: &State<Arc<DatabaseManager>>,
167+
) -> Result<Json<Value>, (Status, Json<Value>)> {
168+
// Get platform information
169+
let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
170+
Ok(platform) => platform,
171+
Err(_) => {
172+
return Err((
173+
Status::NotFound,
174+
Json(json!({
175+
"error": "Platform not found",
176+
"message": format!("Platform with ID {} does not exist", platform_id)
177+
}))
178+
));
179+
}
180+
};
181+
182+
// Get platform-specific database pool
183+
let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
184+
Ok(pool) => pool,
185+
Err(_) => {
186+
return Err((
187+
Status::InternalServerError,
188+
Json(json!({
189+
"error": "Database error",
190+
"message": "Failed to connect to platform database"
191+
}))
192+
));
193+
}
194+
};
195+
196+
let data = escalation_data.into_inner();
197+
198+
let escalation = match db::alert::create_alert_escalation(
199+
&pool,
200+
id,
201+
data.escalation_level,
202+
data.escalated_to,
203+
&data.escalation_method,
204+
data.response_required_by,
205+
).await {
206+
Ok(esc) => esc,
207+
Err(e) => {
208+
log::error!("Failed to escalate alert: {}", e);
209+
return Err((
210+
if e.to_string().contains("no rows") {
211+
Status::NotFound
212+
} else {
213+
Status::InternalServerError
214+
},
215+
Json(json!({
216+
"error": if e.to_string().contains("no rows") { "Alert not found" } else { "Database error" },
217+
"message": if e.to_string().contains("no rows") {
218+
format!("Alert with ID {} does not exist", id)
219+
} else {
220+
"Failed to escalate alert".to_string()
221+
}
222+
}))
223+
));
224+
}
225+
};
226+
227+
Ok(Json(json!({
228+
"message": "Alert escalated successfully",
229+
"escalation": escalation
230+
})))
231+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use super::super::db::queries as db;
2+
use rocket::http::Status;
3+
use rocket::serde::json::{json, Json, Value};
4+
use rocket::{get, State};
5+
use std::sync::Arc;
6+
use crate::DatabaseManager;
7+
8+
/// Get alerts for a specific application
9+
#[get("/platform/<platform_id>/apps/<app_id>/alerts?<limit>&<include_resolved>")]
10+
pub async fn get_app_alerts(
11+
platform_id: i64,
12+
app_id: i64,
13+
limit: Option<i64>,
14+
include_resolved: Option<bool>,
15+
db_manager: &State<Arc<DatabaseManager>>,
16+
) -> Result<Json<Value>, (Status, Json<Value>)> {
17+
// Get platform information
18+
let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
19+
Ok(platform) => platform,
20+
Err(_) => {
21+
return Err((
22+
Status::NotFound,
23+
Json(json!({
24+
"error": "Platform not found",
25+
"message": format!("Platform with ID {} does not exist", platform_id)
26+
}))
27+
));
28+
}
29+
};
30+
31+
// Get platform-specific database pool
32+
let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
33+
Ok(pool) => pool,
34+
Err(_) => {
35+
return Err((
36+
Status::InternalServerError,
37+
Json(json!({
38+
"error": "Database error",
39+
"message": "Failed to connect to platform database"
40+
}))
41+
));
42+
}
43+
};
44+
45+
let limit = limit.unwrap_or(20);
46+
let include_resolved = include_resolved.unwrap_or(false);
47+
48+
let alerts = match db::alert::get_recent_app_alerts(
49+
&pool,
50+
app_id,
51+
limit,
52+
include_resolved,
53+
).await {
54+
Ok(alerts) => alerts,
55+
Err(e) => {
56+
log::error!("Failed to fetch app alerts: {}", e);
57+
return Err((
58+
Status::InternalServerError,
59+
Json(json!({
60+
"error": "Database error",
61+
"message": "Failed to fetch application alerts"
62+
}))
63+
));
64+
}
65+
};
66+
67+
Ok(Json(json!({ "alerts": alerts })))
68+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use super::super::db::queries as db;
2+
use rocket::http::Status;
3+
use rocket::serde::json::{json, Json, Value};
4+
use rocket::{post, State};
5+
use std::sync::Arc;
6+
use crate::DatabaseManager;
7+
8+
/// Auto-resolve old alerts
9+
#[post("/platform/<platform_id>/alerts/auto-resolve?<days_threshold>&<severity_level>")]
10+
pub async fn auto_resolve_old_alerts(
11+
platform_id: i64,
12+
days_threshold: Option<i64>,
13+
severity_level: Option<Vec<String>>, // Can provide multiple severity levels
14+
db_manager: &State<Arc<DatabaseManager>>,
15+
) -> Result<Json<Value>, (Status, Json<Value>)> {
16+
// Get platform information
17+
let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
18+
Ok(platform) => platform,
19+
Err(_) => {
20+
return Err((
21+
Status::NotFound,
22+
Json(json!({
23+
"error": "Platform not found",
24+
"message": format!("Platform with ID {} does not exist", platform_id)
25+
}))
26+
));
27+
}
28+
};
29+
30+
// Get platform-specific database pool
31+
let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
32+
Ok(pool) => pool,
33+
Err(_) => {
34+
return Err((
35+
Status::InternalServerError,
36+
Json(json!({
37+
"error": "Database error",
38+
"message": "Failed to connect to platform database"
39+
}))
40+
));
41+
}
42+
};
43+
44+
let days_threshold = days_threshold.unwrap_or(7); // Default to 7 days
45+
46+
// Convert Vec<String> to Vec<&str>
47+
let severity_refs: Option<Vec<&str>> = severity_level
48+
.as_ref()
49+
.map(|levels| levels.iter().map(AsRef::as_ref).collect());
50+
51+
let count = match db::alert::auto_resolve_old_alerts(
52+
&pool,
53+
days_threshold,
54+
severity_refs,
55+
).await {
56+
Ok(count) => count,
57+
Err(e) => {
58+
log::error!("Failed to auto-resolve old alerts: {}", e);
59+
return Err((
60+
Status::InternalServerError,
61+
Json(json!({
62+
"error": "Database error",
63+
"message": "Failed to auto-resolve old alerts"
64+
}))
65+
));
66+
}
67+
};
68+
69+
Ok(Json(json!({
70+
"message": "Successfully auto-resolved old alerts",
71+
"count": count
72+
})))
73+
}

0 commit comments

Comments
 (0)