omni_orchestrator/schemas/v1/api/alerts/
actions.rs

1use super::super::super::db::queries as db;
2use super::types::{AcknowledgeAlertRequest, CreateEscalationRequest};
3use rocket::http::Status;
4use rocket::serde::json::{json, Json, Value};
5use rocket::{post, State};
6use std::collections::HashMap;
7use std::sync::Arc;
8use crate::DatabaseManager;
9
10use libomni::types::db::v1 as types;
11use types::user::User;
12
13/// Acknowledge an alert
14#[post("/platform/<platform_id>/alerts/<id>/acknowledge", format = "json", data = "<ack_data>")]
15pub 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>")]
88pub 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>")]
162pub 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}