omni_orchestrator/schemas/v1/api/cost/
budgets.rs1use super::super::super::super::auth::User;
2use super::super::super::db::queries as db;
3use super::types::{CreateCostBudgetRequest, UpdateCostBudgetRequest};
4use rocket::http::Status;
5use rocket::serde::json::{json, Json, Value};
6use rocket::{delete, get, post, put, State};
7use std::sync::Arc;
8use crate::DatabaseManager;
9
10use libomni::types::db::v1 as types;
11use types::cost::CostBudget;
12
13#[get("/platform/<platform_id>/cost_budgets?<page>&<per_page>")]
15pub async fn list_cost_budgets(
16 platform_id: i64,
17 page: Option<i64>,
18 per_page: Option<i64>,
19 db_manager: &State<Arc<DatabaseManager>>,
20) -> Result<Json<Value>, (Status, Json<Value>)> {
21 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
23 Ok(platform) => platform,
24 Err(_) => {
25 return Err((
26 Status::NotFound,
27 Json(json!({
28 "error": "Platform not found",
29 "message": format!("Platform with ID {} does not exist", platform_id)
30 }))
31 ));
32 }
33 };
34
35 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
37 Ok(pool) => pool,
38 Err(_) => {
39 return Err((
40 Status::InternalServerError,
41 Json(json!({
42 "error": "Database error",
43 "message": "Failed to connect to platform database"
44 }))
45 ));
46 }
47 };
48
49 match (page, per_page) {
50 (Some(p), Some(pp)) => {
51 let cost_budgets = match db::cost::list_cost_budgets(&pool, p, pp).await {
52 Ok(budgets) => budgets,
53 Err(_) => {
54 return Err((
55 Status::InternalServerError,
56 Json(json!({
57 "error": "Database error",
58 "message": "Failed to retrieve cost budgets"
59 }))
60 ));
61 }
62 };
63
64 let total_count = match db::cost::count_cost_budgets(&pool).await {
65 Ok(count) => count,
66 Err(_) => {
67 return Err((
68 Status::InternalServerError,
69 Json(json!({
70 "error": "Database error",
71 "message": "Failed to count cost budgets"
72 }))
73 ));
74 }
75 };
76
77 let total_pages = (total_count as f64 / pp as f64).ceil() as i64;
78
79 let response = json!({
80 "cost_budgets": cost_budgets,
81 "pagination": {
82 "page": p,
83 "per_page": pp,
84 "total_count": total_count,
85 "total_pages": total_pages
86 }
87 });
88
89 Ok(Json(response))
90 }
91 _ => Err((
92 Status::BadRequest,
93 Json(json!({
94 "error": "Missing pagination parameters",
95 "message": "Please provide both 'page' and 'per_page' parameters"
96 }))
97 ))
98 }
99}
100
101#[get("/platform/<platform_id>/cost_budgets/<id>")]
103pub async fn get_cost_budget(
104 platform_id: i64,
105 id: i64,
106 db_manager: &State<Arc<DatabaseManager>>,
107) -> Result<Json<CostBudget>, (Status, Json<Value>)> {
108 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
110 Ok(platform) => platform,
111 Err(_) => {
112 return Err((
113 Status::NotFound,
114 Json(json!({
115 "error": "Platform not found",
116 "message": format!("Platform with ID {} does not exist", platform_id)
117 }))
118 ));
119 }
120 };
121
122 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
124 Ok(pool) => pool,
125 Err(_) => {
126 return Err((
127 Status::InternalServerError,
128 Json(json!({
129 "error": "Database error",
130 "message": "Failed to connect to platform database"
131 }))
132 ));
133 }
134 };
135
136 match db::cost::get_cost_budget_by_id(&pool, id).await {
137 Ok(budget) => Ok(Json(budget)),
138 Err(_) => Err((
139 Status::NotFound,
140 Json(json!({
141 "error": "Cost budget not found",
142 "message": format!("Cost budget with ID {} could not be found", id)
143 }))
144 )),
145 }
146}
147
148#[post("/platform/<platform_id>/cost_budgets", format = "json", data = "<request>")]
150pub async fn create_cost_budget(
151 platform_id: i64,
152 request: Json<CreateCostBudgetRequest>,
153 db_manager: &State<Arc<DatabaseManager>>,
154 user: User,
155) -> Result<Json<CostBudget>, (Status, Json<Value>)> {
156 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
158 Ok(platform) => platform,
159 Err(_) => {
160 return Err((
161 Status::NotFound,
162 Json(json!({
163 "error": "Platform not found",
164 "message": format!("Platform with ID {} does not exist", platform_id)
165 }))
166 ));
167 }
168 };
169
170 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
172 Ok(pool) => pool,
173 Err(_) => {
174 return Err((
175 Status::InternalServerError,
176 Json(json!({
177 "error": "Database error",
178 "message": "Failed to connect to platform database"
179 }))
180 ));
181 }
182 };
183
184 let user_id = user.id;
185
186 match db::cost::create_cost_budget(
189 &pool,
190 request.org_id,
191 request.app_id,
192 &request.budget_name,
193 request.budget_amount,
194 &request.currency,
195 &request.budget_period,
196 request.period_start,
197 request.period_end,
198 request.alert_threshold_percentage,
199 &request.alert_contacts,
200 user_id,
201 ).await {
202 Ok(budget) => Ok(Json(budget)),
203 Err(e) => Err((
204 Status::InternalServerError,
205 Json(json!({
206 "error": "Failed to create cost budget",
207 "message": format!("{}", e)
208 }))
209 )),
210 }
211}
212
213#[put("/platform/<platform_id>/cost_budgets/<id>", format = "json", data = "<request>")]
215pub async fn update_cost_budget(
216 platform_id: i64,
217 id: i64,
218 request: Json<UpdateCostBudgetRequest>,
219 db_manager: &State<Arc<DatabaseManager>>,
220) -> Result<Json<CostBudget>, (Status, Json<Value>)> {
221 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
223 Ok(platform) => platform,
224 Err(_) => {
225 return Err((
226 Status::NotFound,
227 Json(json!({
228 "error": "Platform not found",
229 "message": format!("Platform with ID {} does not exist", platform_id)
230 }))
231 ));
232 }
233 };
234
235 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
237 Ok(pool) => pool,
238 Err(_) => {
239 return Err((
240 Status::InternalServerError,
241 Json(json!({
242 "error": "Database error",
243 "message": "Failed to connect to platform database"
244 }))
245 ));
246 }
247 };
248
249 match db::cost::update_cost_budget(
250 &pool,
251 id,
252 request.budget_name.as_deref(),
253 request.budget_amount,
254 request.alert_threshold_percentage,
255 request.alert_contacts.as_deref(),
256 request.is_active,
257 ).await {
258 Ok(budget) => Ok(Json(budget)),
259 Err(e) => Err((
260 Status::InternalServerError,
261 Json(json!({
262 "error": "Failed to update cost budget",
263 "message": format!("{}", e)
264 }))
265 )),
266 }
267}
268
269#[delete("/platform/<platform_id>/cost_budgets/<id>")]
271pub async fn delete_cost_budget(
272 platform_id: i64,
273 id: i64,
274 db_manager: &State<Arc<DatabaseManager>>,
275) -> Result<Json<Value>, (Status, Json<Value>)> {
276 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
278 Ok(platform) => platform,
279 Err(_) => {
280 return Err((
281 Status::NotFound,
282 Json(json!({
283 "error": "Platform not found",
284 "message": format!("Platform with ID {} does not exist", platform_id)
285 }))
286 ));
287 }
288 };
289
290 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
292 Ok(pool) => pool,
293 Err(_) => {
294 return Err((
295 Status::InternalServerError,
296 Json(json!({
297 "error": "Database error",
298 "message": "Failed to connect to platform database"
299 }))
300 ));
301 }
302 };
303
304 match db::cost::delete_cost_budget(&pool, id).await {
305 Ok(_) => Ok(Json(json!({ "status": "deleted" }))),
306 Err(e) => Err((
307 Status::InternalServerError,
308 Json(json!({
309 "error": "Failed to delete cost budget",
310 "message": format!("{}", e)
311 }))
312 )),
313 }
314}