omni_orchestrator/schemas/v1/api/alerts/
actions.rs1use 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#[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, db_manager: &State<Arc<DatabaseManager>>,
21) -> Result<Json<Value>, (Status, Json<Value>)> {
22 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 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#[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, db_manager: &State<Arc<DatabaseManager>>,
94) -> Result<Json<Value>, (Status, Json<Value>)> {
95 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 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 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#[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 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 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}