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

1use super::super::super::db::queries as db;
2use rocket::http::Status;
3use rocket::serde::json::{json, Json, Value};
4use rocket::{get, State};
5use std::sync::Arc;
6use crate::DatabaseManager;
7
8/// Get a paginated list of alerts with filtering options
9#[get("/platform/<platform_id>/alerts?<page>&<per_page>&<status>&<severity>&<org_id>&<app_id>&<service>&<from_date>&<to_date>")]
10pub async fn list_alerts(
11    platform_id: i64,
12    page: Option<i64>,
13    per_page: Option<i64>,
14    status: Option<String>,
15    severity: Option<String>,
16    org_id: Option<i64>,
17    app_id: Option<i64>,
18    service: Option<String>,
19    from_date: Option<String>,
20    to_date: Option<String>,
21    db_manager: &State<Arc<DatabaseManager>>,
22) -> Result<Json<Value>, (Status, Json<Value>)> {
23    // Get platform information
24    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
25        Ok(platform) => platform,
26        Err(_) => {
27            return Err((
28                Status::NotFound,
29                Json(json!({
30                    "error": "Platform not found",
31                    "message": format!("Platform with ID {} does not exist", platform_id)
32                }))
33            ));
34        }
35    };
36
37    // Get platform-specific database pool
38    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
39        Ok(pool) => pool,
40        Err(_) => {
41            return Err((
42                Status::InternalServerError,
43                Json(json!({
44                    "error": "Database error",
45                    "message": "Failed to connect to platform database"
46                }))
47            ));
48        }
49    };
50
51    // Set default pagination if not provided
52    let page = page.unwrap_or(0);
53    let per_page = per_page.unwrap_or(20);
54    
55    // Convert Optional String to Optional &str
56    let status_ref = status.as_deref();
57    let severity_ref = severity.as_deref();
58    let service_ref = service.as_deref();
59
60    // Fetch alerts with filters
61    let alerts = match db::alert::list_alerts(
62        &pool, 
63        page, 
64        per_page,
65        status_ref,
66        severity_ref,
67        org_id,
68        app_id,
69        service_ref,
70        from_date.and_then(|date_str| chrono::DateTime::parse_from_rfc3339(&date_str).ok().map(|dt| dt.with_timezone(&chrono::Utc))),
71        to_date.and_then(|date_str| chrono::DateTime::parse_from_rfc3339(&date_str).ok().map(|dt| dt.with_timezone(&chrono::Utc))),
72    ).await {
73        Ok(alerts) => alerts,
74        Err(e) => {
75            log::error!("Failed to fetch alerts: {}", e);
76            return Err((
77                Status::InternalServerError,
78                Json(json!({
79                    "error": "Database error",
80                    "message": "Failed to fetch alerts"
81                }))
82            ));
83        }
84    };
85
86    // Count total alerts with same filters for pagination
87    let total_count = match db::alert::count_alerts(
88        &pool,
89        status_ref,
90        severity_ref,
91        org_id,
92        app_id,
93    ).await {
94        Ok(count) => count,
95        Err(e) => {
96            log::error!("Failed to fetch alert count: {}", e);
97            return Err((
98                Status::InternalServerError,
99                Json(json!({
100                    "error": "Database error",
101                    "message": "Failed to count alerts"
102                }))
103            ));
104        }
105    };
106
107    let total_pages = (total_count as f64 / per_page as f64).ceil() as i64;
108    let response = json!({
109        "alerts": alerts,
110        "pagination": {
111            "page": page,
112            "per_page": per_page,
113            "total_count": total_count,
114            "total_pages": total_pages
115        }
116    });
117
118    Ok(Json(response))
119}