omni_orchestrator/schemas/v1/api/notifications/
acknowledge.rs

1use std::sync::Arc;
2use crate::DatabaseManager;
3use crate::schemas::v1::db::queries::{self as db};
4use super::types::AcknowledgeNotificationRequest;
5use rocket::http::Status;
6use rocket::serde::json::{json, Json, Value};
7use rocket::{post, State};
8
9use libomni::types::db::v1 as types;
10use types::user::User;
11
12/// Acknowledge a notification
13#[post("/platform/<platform_id>/notifications/acknowledge", format = "json", data = "<ack_data>")]
14pub async fn acknowledge_notification(
15    platform_id: i64,
16    ack_data: Json<AcknowledgeNotificationRequest>,
17    user: User, // For authentication
18    db_manager: &State<Arc<DatabaseManager>>,
19) -> Result<Json<Value>, (Status, Json<Value>)> {
20    // Get platform information
21    let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
22        Ok(platform) => platform,
23        Err(_) => {
24            return Err((
25                Status::NotFound,
26                Json(json!({
27                    "error": "Platform not found",
28                    "message": format!("Platform with ID {} does not exist", platform_id)
29                }))
30            ));
31        }
32    };
33
34    // Get platform-specific database pool
35    let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
36        Ok(pool) => pool,
37        Err(_) => {
38            return Err((
39                Status::InternalServerError,
40                Json(json!({
41                    "error": "Database error",
42                    "message": "Failed to connect to platform database"
43                }))
44            ));
45        }
46    };
47
48    let data = ack_data.into_inner();
49
50    // Validate input - either notification_id or role_notification_id must be provided
51    if data.notification_id.is_none() && data.role_notification_id.is_none() {
52        return Err((
53            Status::BadRequest,
54            Json(json!({
55                "error": "Bad request",
56                "message": "Either notification_id or role_notification_id must be provided"
57            }))
58        ));
59    }
60    if data.notification_id.is_some() && data.role_notification_id.is_some() {
61        return Err((
62            Status::BadRequest,
63            Json(json!({
64                "error": "Bad request",
65                "message": "Only one of notification_id or role_notification_id should be provided"
66            }))
67        ));
68    }
69
70    // If it's a user notification, verify ownership
71    if let Some(notification_id) = data.notification_id {
72        let notification = match db::notification::get_user_notification_by_id(
73            &pool,
74            notification_id,
75        ).await {
76            Ok(notification) => notification,
77            Err(e) => {
78                log::error!("Failed to fetch notification: {}", e);
79                if e.to_string().contains("no rows") {
80                    return Err((
81                        Status::NotFound,
82                        Json(json!({
83                            "error": "Not found",
84                            "message": format!("Notification with ID {} does not exist", notification_id)
85                        }))
86                    ));
87                } else {
88                    return Err((
89                        Status::InternalServerError,
90                        Json(json!({
91                            "error": "Database error",
92                            "message": "Failed to fetch notification"
93                        }))
94                    ));
95                }
96            }
97        };
98
99        // Authorization - only allow users to acknowledge their own notifications
100        // or administrators to acknowledge others' notifications
101        if notification.user_id != user.id {
102            return Err((
103                Status::Forbidden,
104                Json(json!({
105                    "error": "Forbidden",
106                    "message": "You do not have permission to acknowledge this notification"
107                }))
108            ));
109        }
110    }
111
112    match db::notification::create_notification_acknowledgment(
113        &pool,
114        user.id,
115        data.notification_id,
116        data.role_notification_id,
117    ).await {
118        Ok(acknowledgment) => Ok(Json(json!({
119            "message": "Notification acknowledged successfully",
120            "acknowledgment": acknowledgment
121        }))),
122        Err(e) => {
123            log::error!("Failed to acknowledge notification: {}", e);
124            Err((
125                Status::InternalServerError,
126                Json(json!({
127                    "error": "Database error",
128                    "message": "Failed to acknowledge notification"
129                }))
130            ))
131        }
132    }
133}