omni_orchestrator/schemas/v1/api/
audit_log.rs

1use std::sync::Arc;
2use crate::DatabaseManager;
3use crate::models::audit_log::AuditLog;
4use super::super::db::queries as db;
5use rocket::get;
6use rocket::post;
7use rocket::http::Status;
8use rocket::serde::json::{json, Json, Value};
9use rocket::State;
10
11/// Creates a new audit log entry in the system.
12#[post("/platform/<platform_id>/audit_log", format = "json", data = "<audit_log>")]
13pub async fn create_audit_log(
14    platform_id: i64,
15    audit_log: Json<AuditLog>,
16    db_manager: &State<Arc<DatabaseManager>>,
17) -> Result<Json<AuditLog>, (Status, Json<Value>)> {
18    // Get platform information
19    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
20        Ok(platform) => platform,
21        Err(_) => {
22            return Err((
23                Status::NotFound,
24                Json(json!({
25                    "error": "Platform not found",
26                    "message": format!("Platform with ID {} does not exist", platform_id)
27                }))
28            ));
29        }
30    };
31
32    // Get platform-specific database pool
33    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
34        Ok(pool) => pool,
35        Err(_) => {
36            return Err((
37                Status::InternalServerError,
38                Json(json!({
39                    "error": "Database error",
40                    "message": "Failed to connect to platform database"
41                }))
42            ));
43        }
44    };
45
46    match db::audit_log::create_audit_log(
47        &pool,
48        audit_log.user_id,
49        audit_log.org_id,
50        &audit_log.action,
51        &audit_log.resource_type,
52        audit_log.resource_id.clone(),
53    ).await {
54        Ok(result) => Ok(Json(result)),
55        Err(_) => Err((
56            Status::InternalServerError,
57            Json(json!({
58                "error": "Database error",
59                "message": "Failed to create audit log entry"
60            }))
61        )),
62    }
63}
64
65/// List audit log entries with pagination support.
66#[get("/platform/<platform_id>/audit_logs?<page>&<per_page>")]
67pub async fn list_audit_logs(
68    platform_id: i64,
69    page: Option<u32>,
70    per_page: Option<u32>,
71    db_manager: &State<Arc<DatabaseManager>>,
72) -> Result<Json<Value>, (Status, Json<Value>)> {
73    // Get platform information
74    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
75        Ok(platform) => platform,
76        Err(_) => {
77            return Err((
78                Status::NotFound,
79                Json(json!({
80                    "error": "Platform not found",
81                    "message": format!("Platform with ID {} does not exist", platform_id)
82                }))
83            ));
84        }
85    };
86
87    // Get platform-specific database pool
88    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
89        Ok(pool) => pool,
90        Err(_) => {
91            return Err((
92                Status::InternalServerError,
93                Json(json!({
94                    "error": "Database error",
95                    "message": "Failed to connect to platform database"
96                }))
97            ));
98        }
99    };
100
101    let p: i64 = page.unwrap_or(1).into();
102    let pp: i64 = per_page.unwrap_or(10).into();
103
104    let audit_logs = match db::audit_log::list_audit_logs_paginated(&pool, pp, p).await {
105        Ok(logs) => logs,
106        Err(_) => {
107            return Err((
108                Status::InternalServerError,
109                Json(json!({
110                    "error": "Database error",
111                    "message": "Failed to list audit logs"
112                }))
113            ));
114        }
115    };
116
117    let total_count = match db::audit_log::count_audit_logs(&pool).await {
118        Ok(count) => count,
119        Err(_) => {
120            return Err((
121                Status::InternalServerError,
122                Json(json!({
123                    "error": "Database error",
124                    "message": "Failed to count audit logs"
125                }))
126            ));
127        }
128    };
129
130    let total_pages = if pp > 0 {
131        (total_count + pp - 1) / pp
132    } else {
133        1
134    };
135
136    let response = json!({
137        "audit_logs": audit_logs,
138        "pagination": {
139            "page": p,
140            "per_page": pp,
141            "total_count": total_count,
142            "total_pages": total_pages
143        }
144    });
145
146    Ok(Json(response))
147}
148
149/// List all audit log entries for a given app_id with pagination support.
150#[get("/platform/<platform_id>/audit_logs/<app_id>?<page>&<per_page>")]
151pub async fn list_audit_logs_for_app(
152    platform_id: i64,
153    app_id: i64,
154    page: Option<i64>,
155    per_page: Option<i64>,
156    db_manager: &State<Arc<DatabaseManager>>,
157) -> Result<Json<Value>, (Status, Json<Value>)> {
158    // Get platform information
159    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
160        Ok(platform) => platform,
161        Err(_) => {
162            return Err((
163                Status::NotFound,
164                Json(json!({
165                    "error": "Platform not found",
166                    "message": format!("Platform with ID {} does not exist", platform_id)
167                }))
168            ));
169        }
170    };
171
172    // Get platform-specific database pool
173    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
174        Ok(pool) => pool,
175        Err(_) => {
176            return Err((
177                Status::InternalServerError,
178                Json(json!({
179                    "error": "Database error",
180                    "message": "Failed to connect to platform database"
181                }))
182            ));
183        }
184    };
185
186    let page: i64 = page.unwrap_or(1);
187    let per_page: i64 = per_page.unwrap_or(10);
188
189    let audit_logs = match db::audit_log::get_audit_logs_by_app(&pool, app_id, page, per_page).await {
190        Ok(logs) => logs,
191        Err(_) => {
192            return Err((
193                Status::InternalServerError,
194                Json(json!({
195                    "error": "Database error",
196                    "message": "Failed to retrieve audit logs for app"
197                }))
198            ));
199        }
200    };
201
202    let total_count = match db::audit_log::count_audit_logs_by_app(&pool, app_id).await {
203        Ok(count) => count,
204        Err(_) => {
205            return Err((
206                Status::InternalServerError,
207                Json(json!({
208                    "error": "Database error",
209                    "message": "Failed to count audit logs for app"
210                }))
211            ));
212        }
213    };
214
215    let total_pages = if per_page > 0 {
216        (total_count + per_page - 1) / per_page
217    } else {
218        1
219    };
220
221    let response = json!({
222        "audit_logs": audit_logs,
223        "pagination": {
224            "page": page,
225            "per_page": per_page,
226            "total_count": total_count,
227            "total_pages": total_pages
228        }
229    });
230
231    Ok(Json(response))
232}