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

1use super::super::super::db::queries as db;
2use super::types::{CreateResourcePricingRequest, UpdateResourcePricingRequest};
3use rocket::http::Status;
4use rocket::serde::json::{json, Json, Value};
5use rocket::{delete, get, post, put, State};
6use std::sync::Arc;
7use crate::DatabaseManager;
8
9use libomni::types::db::v1 as types;
10use types::cost::ResourcePricing;
11
12/// List resource pricing with pagination and filtering support.
13#[get("/platform/<platform_id>/resource_pricing?<page>&<per_page>&<resource_type_id>&<provider_id>&<region_id>&<pricing_model>&<tier_name>")]
14pub async fn list_resource_pricing(
15    platform_id: i64,
16    page: Option<i64>,
17    per_page: Option<i64>,
18    resource_type_id: Option<i32>,
19    provider_id: Option<i64>,
20    region_id: Option<i64>,
21    pricing_model: Option<String>,
22    tier_name: Option<String>,
23    db_manager: &State<Arc<DatabaseManager>>,
24) -> Result<Json<Value>, (Status, Json<Value>)> {
25    // Get platform information
26    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
27        Ok(platform) => platform,
28        Err(_) => {
29            return Err((
30                Status::NotFound,
31                Json(json!({
32                    "error": "Platform not found",
33                    "message": format!("Platform with ID {} does not exist", platform_id)
34                }))
35            ));
36        }
37    };
38
39    // Get platform-specific database pool
40    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
41        Ok(pool) => pool,
42        Err(_) => {
43            return Err((
44                Status::InternalServerError,
45                Json(json!({
46                    "error": "Database error",
47                    "message": "Failed to connect to platform database"
48                }))
49            ));
50        }
51    };
52
53    match (page, per_page) {
54        (Some(p), Some(pp)) => {
55            let pricing = match db::cost::list_resource_pricing(
56                &pool, p, pp, resource_type_id, provider_id, region_id, pricing_model.as_deref(), tier_name.as_deref()
57            ).await {
58                Ok(pricing) => pricing,
59                Err(_) => {
60                    return Err((
61                        Status::InternalServerError,
62                        Json(json!({
63                            "error": "Database error",
64                            "message": "Failed to retrieve resource pricing"
65                        }))
66                    ));
67                }
68            };
69            
70            let response = json!({
71                "resource_pricing": pricing,
72                "pagination": {
73                    "page": p,
74                    "per_page": pp
75                }
76            });
77
78            Ok(Json(response))
79        }
80        _ => Err((
81            Status::BadRequest,
82            Json(json!({
83                "error": "Missing pagination parameters",
84                "message": "Please provide both 'page' and 'per_page' parameters"
85            }))
86        ))
87    }
88}
89
90/// Get a specific resource pricing entry by ID.
91#[get("/platform/<platform_id>/resource_pricing/<id>")]
92pub async fn get_resource_pricing(
93    platform_id: i64,
94    id: i64,
95    db_manager: &State<Arc<DatabaseManager>>,
96) -> Result<Json<ResourcePricing>, (Status, Json<Value>)> {
97    // Get platform information
98    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
99        Ok(platform) => platform,
100        Err(_) => {
101            return Err((
102                Status::NotFound,
103                Json(json!({
104                    "error": "Platform not found",
105                    "message": format!("Platform with ID {} does not exist", platform_id)
106                }))
107            ));
108        }
109    };
110
111    // Get platform-specific database pool
112    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
113        Ok(pool) => pool,
114        Err(_) => {
115            return Err((
116                Status::InternalServerError,
117                Json(json!({
118                    "error": "Database error",
119                    "message": "Failed to connect to platform database"
120                }))
121            ));
122        }
123    };
124
125    match db::cost::get_resource_pricing_by_id(&pool, id).await {
126        Ok(pricing) => Ok(Json(pricing)),
127        Err(_) => Err((
128            Status::NotFound,
129            Json(json!({
130                "error": "Resource pricing not found",
131                "message": format!("Resource pricing with ID {} could not be found", id)
132            }))
133        )),
134    }
135}
136
137/// Create a new resource pricing entry.
138#[post("/platform/<platform_id>/resource_pricing", format = "json", data = "<request>")]
139pub async fn create_resource_pricing(
140    platform_id: i64,
141    request: Json<CreateResourcePricingRequest>,
142    db_manager: &State<Arc<DatabaseManager>>,
143) -> Result<Json<ResourcePricing>, (Status, Json<Value>)> {
144    // Get platform information
145    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
146        Ok(platform) => platform,
147        Err(_) => {
148            return Err((
149                Status::NotFound,
150                Json(json!({
151                    "error": "Platform not found",
152                    "message": format!("Platform with ID {} does not exist", platform_id)
153                }))
154            ));
155        }
156    };
157
158    // Get platform-specific database pool
159    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
160        Ok(pool) => pool,
161        Err(_) => {
162            return Err((
163                Status::InternalServerError,
164                Json(json!({
165                    "error": "Database error",
166                    "message": "Failed to connect to platform database"
167                }))
168            ));
169        }
170    };
171
172    match db::cost::create_resource_pricing(
173        &pool,
174        request.resource_type_id,
175        request.provider_id,
176        request.region_id,
177        &request.tier_name,
178        request.unit_price,
179        &request.currency,
180        request.effective_from,
181        request.effective_to,
182        &request.pricing_model,
183        request.commitment_period.as_deref(),
184        request.volume_discount_tiers.as_deref(),
185    ).await {
186        Ok(pricing) => Ok(Json(pricing)),
187        Err(e) => Err((
188            Status::InternalServerError,
189            Json(json!({
190                "error": "Failed to create resource pricing",
191                "message": format!("{}", e)
192            }))
193        )),
194    }
195}
196
197/// Update an existing resource pricing entry.
198#[put("/platform/<platform_id>/resource_pricing/<id>", format = "json", data = "<request>")]
199pub async fn update_resource_pricing(
200    platform_id: i64,
201    id: i64,
202    request: Json<UpdateResourcePricingRequest>,
203    db_manager: &State<Arc<DatabaseManager>>,
204) -> Result<Json<ResourcePricing>, (Status, Json<Value>)> {
205    // Get platform information
206    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
207        Ok(platform) => platform,
208        Err(_) => {
209            return Err((
210                Status::NotFound,
211                Json(json!({
212                    "error": "Platform not found",
213                    "message": format!("Platform with ID {} does not exist", platform_id)
214                }))
215            ));
216        }
217    };
218
219    // Get platform-specific database pool
220    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
221        Ok(pool) => pool,
222        Err(_) => {
223            return Err((
224                Status::InternalServerError,
225                Json(json!({
226                    "error": "Database error",
227                    "message": "Failed to connect to platform database"
228                }))
229            ));
230        }
231    };
232
233    match db::cost::update_resource_pricing(
234        &pool,
235        id,
236        request.unit_price,
237        request.effective_to,
238        request.volume_discount_tiers.as_deref(),
239    ).await {
240        Ok(pricing) => Ok(Json(pricing)),
241        Err(e) => Err((
242            Status::InternalServerError,
243            Json(json!({
244                "error": "Failed to update resource pricing",
245                "message": format!("{}", e)
246            }))
247        )),
248    }
249}
250
251/// Delete a resource pricing entry.
252#[delete("/platform/<platform_id>/resource_pricing/<id>")]
253pub async fn delete_resource_pricing(
254    platform_id: i64,
255    id: i64,
256    db_manager: &State<Arc<DatabaseManager>>,
257) -> Result<Json<Value>, (Status, Json<Value>)> {
258    // Get platform information
259    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
260        Ok(platform) => platform,
261        Err(_) => {
262            return Err((
263                Status::NotFound,
264                Json(json!({
265                    "error": "Platform not found",
266                    "message": format!("Platform with ID {} does not exist", platform_id)
267                }))
268            ));
269        }
270    };
271
272    // Get platform-specific database pool
273    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
274        Ok(pool) => pool,
275        Err(_) => {
276            return Err((
277                Status::InternalServerError,
278                Json(json!({
279                    "error": "Database error",
280                    "message": "Failed to connect to platform database"
281                }))
282            ));
283        }
284    };
285
286    match db::cost::delete_resource_pricing(&pool, id).await {
287        Ok(_) => Ok(Json(json!({ "status": "deleted" }))),
288        Err(e) => Err((
289            Status::InternalServerError,
290            Json(json!({
291                "error": "Failed to delete resource pricing",
292                "message": format!("{}", e)
293            }))
294        )),
295    }
296}