omni_orchestrator/schemas/v1/api/cost/
analysis.rs

1use super::super::super::db::queries as db;
2use super::types::{CostAnalysisByDimensionRequest, CostOverTimeRequest};
3use rocket::http::Status;
4use rocket::serde::json::{json, Json, Value};
5use rocket::{post, State};
6use std::sync::Arc;
7use crate::DatabaseManager;
8use chrono::{DateTime, Utc};
9
10/// Get cost analysis by dimension (app, provider, resource_type, etc.)
11#[post("/platform/<platform_id>/cost_analysis/by_dimension", format = "json", data = "<request>")]
12pub async fn analyze_costs_by_dimension(
13    platform_id: i64,
14    request: Json<CostAnalysisByDimensionRequest>,
15    db_manager: &State<Arc<DatabaseManager>>,
16) -> Result<Json<Vec<(String, f64)>>, (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    match db::cost::get_cost_metrics_by_dimension(
46        &pool,
47        &request.dimension,
48        request.start_date,
49        request.end_date,
50        request.limit,
51    ).await {
52        Ok(results) => Ok(Json(results)),
53        Err(e) => Err((
54            Status::InternalServerError,
55            Json(json!({
56                "error": "Failed to analyze costs by dimension",
57                "message": format!("{}", e)
58            }))
59        )),
60    }
61}
62
63/// Get application cost over time
64#[post("/platform/<platform_id>/cost_analysis/over_time", format = "json", data = "<request>")]
65pub async fn analyze_cost_over_time(
66    platform_id: i64,
67    request: Json<CostOverTimeRequest>,
68    db_manager: &State<Arc<DatabaseManager>>,
69) -> Result<Json<Vec<(DateTime<Utc>, f64)>>, (Status, Json<Value>)> {
70    // Get platform information
71    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
72        Ok(platform) => platform,
73        Err(_) => {
74            return Err((
75                Status::NotFound,
76                Json(json!({
77                    "error": "Platform not found",
78                    "message": format!("Platform with ID {} does not exist", platform_id)
79                }))
80            ));
81        }
82    };
83
84    // Get platform-specific database pool
85    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
86        Ok(pool) => pool,
87        Err(_) => {
88            return Err((
89                Status::InternalServerError,
90                Json(json!({
91                    "error": "Database error",
92                    "message": "Failed to connect to platform database"
93                }))
94            ));
95        }
96    };
97
98    match db::cost::get_app_cost_over_time(
99        &pool,
100        request.app_id,
101        &request.interval,
102        request.start_date,
103        request.end_date,
104    ).await {
105        Ok(results) => Ok(Json(results)),
106        Err(e) => Err((
107            Status::InternalServerError,
108            Json(json!({
109                "error": "Failed to analyze cost over time",
110                "message": format!("{}", e)
111            }))
112        )),
113    }
114}