1use std::sync::Arc;
2use crate::DatabaseManager;
3use crate::schemas::v1::db::queries::{self as db};
4use super::types::CreateUserNotificationRequest;
5use rocket::http::Status;
6use rocket::serde::json::{json, Json, Value};
7use rocket::{delete, get, post, put, State};
8
9use libomni::types::db::v1 as types;
10use types::user::User;
11
12#[get("/platform/<platform_id>/notifications/user/<user_id>?<page>&<per_page>&<include_read>")]
14pub async fn list_user_notifications(
15 platform_id: i64,
16 user_id: i64,
17 page: Option<i64>,
18 per_page: Option<i64>,
19 include_read: Option<bool>,
20 user: User, db_manager: &State<Arc<DatabaseManager>>,
22) -> Result<Json<Value>, (Status, Json<Value>)> {
23 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
25 Ok(platform) => platform,
26 Err(_) => {
27 return Err((
28 Status::NotFound,
29 Json(json!({
30 "error": "Platform not found",
31 "message": format!("Platform with ID {} does not exist", platform_id)
32 }))
33 ));
34 }
35 };
36
37 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
39 Ok(pool) => pool,
40 Err(_) => {
41 return Err((
42 Status::InternalServerError,
43 Json(json!({
44 "error": "Database error",
45 "message": "Failed to connect to platform database"
46 }))
47 ));
48 }
49 };
50
51 if user.id != user_id {
54 return Err((
55 Status::Forbidden,
56 Json(json!({
57 "error": "Forbidden",
58 "message": "You do not have permission to view this user's notifications"
59 }))
60 ));
61 }
62
63 let page = page.unwrap_or(0);
65 let per_page = per_page.unwrap_or(20);
66 let include_read = include_read.unwrap_or(false);
67
68 match db::notification::list_user_notifications(
69 &pool,
70 user_id,
71 page,
72 per_page,
73 include_read,
74 ).await {
75 Ok(notifications) => Ok(Json(json!({
76 "notifications": notifications,
77 "pagination": {
78 "page": page,
79 "per_page": per_page
80 }
81 }))),
82 Err(e) => {
83 log::error!("Failed to fetch user notifications: {}", e);
84 Err((
85 Status::InternalServerError,
86 Json(json!({
87 "error": "Database error",
88 "message": "Failed to fetch user notifications"
89 }))
90 ))
91 }
92 }
93}
94
95#[get("/platform/<platform_id>/notifications/user/count/<user_id>")]
97pub async fn count_unread_user_notifications(
98 platform_id: i64,
99 user_id: i64,
100 user: User, db_manager: &State<Arc<DatabaseManager>>,
102) -> Result<Json<Value>, (Status, Json<Value>)> {
103 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
105 Ok(platform) => platform,
106 Err(_) => {
107 return Err((
108 Status::NotFound,
109 Json(json!({
110 "error": "Platform not found",
111 "message": format!("Platform with ID {} does not exist", platform_id)
112 }))
113 ));
114 }
115 };
116
117 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
119 Ok(pool) => pool,
120 Err(_) => {
121 return Err((
122 Status::InternalServerError,
123 Json(json!({
124 "error": "Database error",
125 "message": "Failed to connect to platform database"
126 }))
127 ));
128 }
129 };
130
131 if user.id != user_id {
134 return Err((
135 Status::Forbidden,
136 Json(json!({
137 "error": "Forbidden",
138 "message": "You do not have permission to view this user's notification count"
139 }))
140 ));
141 }
142
143 match db::notification::count_unread_user_notifications(
144 &pool,
145 user_id,
146 ).await {
147 Ok(count) => Ok(Json(json!({ "unread_count": count }))),
148 Err(e) => {
149 log::error!("Failed to count unread notifications: {}", e);
150 Err((
151 Status::InternalServerError,
152 Json(json!({
153 "error": "Database error",
154 "message": "Failed to count unread notifications"
155 }))
156 ))
157 }
158 }
159}
160
161#[get("/platform/<platform_id>/notifications/<id>")]
163pub async fn get_user_notification_by_id(
164 platform_id: i64,
165 id: i64,
166 user: User, db_manager: &State<Arc<DatabaseManager>>,
168) -> Result<Json<Value>, (Status, Json<Value>)> {
169 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
171 Ok(platform) => platform,
172 Err(_) => {
173 return Err((
174 Status::NotFound,
175 Json(json!({
176 "error": "Platform not found",
177 "message": format!("Platform with ID {} does not exist", platform_id)
178 }))
179 ));
180 }
181 };
182
183 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
185 Ok(pool) => pool,
186 Err(_) => {
187 return Err((
188 Status::InternalServerError,
189 Json(json!({
190 "error": "Database error",
191 "message": "Failed to connect to platform database"
192 }))
193 ));
194 }
195 };
196
197 let notification = match db::notification::get_user_notification_by_id(
198 &pool,
199 id,
200 ).await {
201 Ok(notification) => notification,
202 Err(e) => {
203 log::error!("Failed to fetch notification: {}", e);
204 if e.to_string().contains("no rows") {
205 return Err((
206 Status::NotFound,
207 Json(json!({
208 "error": "Not found",
209 "message": format!("Notification with ID {} does not exist", id)
210 }))
211 ));
212 } else {
213 return Err((
214 Status::InternalServerError,
215 Json(json!({
216 "error": "Database error",
217 "message": "Failed to fetch notification"
218 }))
219 ));
220 }
221 }
222 };
223
224 if notification.user_id != user.id {
227 return Err((
228 Status::Forbidden,
229 Json(json!({
230 "error": "Forbidden",
231 "message": "You do not have permission to view this notification"
232 }))
233 ));
234 }
235
236 Ok(Json(json!({ "notification": notification })))
237}
238
239#[post("/platform/<platform_id>/notifications/user", format = "json", data = "<notification_data>")]
241pub async fn create_user_notification(
242 platform_id: i64,
243 notification_data: Json<CreateUserNotificationRequest>,
244 user: User, db_manager: &State<Arc<DatabaseManager>>,
246) -> Result<Json<Value>, (Status, Json<Value>)> {
247 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
249 Ok(platform) => platform,
250 Err(_) => {
251 return Err((
252 Status::NotFound,
253 Json(json!({
254 "error": "Platform not found",
255 "message": format!("Platform with ID {} does not exist", platform_id)
256 }))
257 ));
258 }
259 };
260
261 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
263 Ok(pool) => pool,
264 Err(_) => {
265 return Err((
266 Status::InternalServerError,
267 Json(json!({
268 "error": "Database error",
269 "message": "Failed to connect to platform database"
270 }))
271 ));
272 }
273 };
274
275 let data = notification_data.into_inner();
276
277 let target_user_id = user.id;
280
281 match db::notification::create_user_notification(
282 &pool,
283 target_user_id,
284 &data.message,
285 &data.notification_type,
286 data.org_id,
287 data.app_id,
288 data.importance.as_deref(),
289 data.action_url.as_deref(),
290 data.action_label.as_deref(),
291 data.expires_at,
292 ).await {
293 Ok(notification) => Ok(Json(json!({
294 "message": "Notification created successfully",
295 "notification": notification
296 }))),
297 Err(e) => {
298 log::error!("Failed to create notification: {}", e);
299 Err((
300 Status::InternalServerError,
301 Json(json!({
302 "error": "Database error",
303 "message": "Failed to create notification"
304 }))
305 ))
306 }
307 }
308}
309
310#[put("/platform/<platform_id>/notifications/<id>/read")]
312pub async fn mark_user_notification_as_read(
313 platform_id: i64,
314 id: i64,
315 user: User, db_manager: &State<Arc<DatabaseManager>>,
317) -> Result<Json<Value>, (Status, Json<Value>)> {
318 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
320 Ok(platform) => platform,
321 Err(_) => {
322 return Err((
323 Status::NotFound,
324 Json(json!({
325 "error": "Platform not found",
326 "message": format!("Platform with ID {} does not exist", platform_id)
327 }))
328 ));
329 }
330 };
331
332 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
334 Ok(pool) => pool,
335 Err(_) => {
336 return Err((
337 Status::InternalServerError,
338 Json(json!({
339 "error": "Database error",
340 "message": "Failed to connect to platform database"
341 }))
342 ));
343 }
344 };
345
346 let notification = match db::notification::get_user_notification_by_id(
348 &pool,
349 id,
350 ).await {
351 Ok(notification) => notification,
352 Err(e) => {
353 log::error!("Failed to fetch notification: {}", e);
354 if e.to_string().contains("no rows") {
355 return Err((
356 Status::NotFound,
357 Json(json!({
358 "error": "Not found",
359 "message": format!("Notification with ID {} does not exist", id)
360 }))
361 ));
362 } else {
363 return Err((
364 Status::InternalServerError,
365 Json(json!({
366 "error": "Database error",
367 "message": "Failed to fetch notification"
368 }))
369 ));
370 }
371 }
372 };
373
374 if notification.user_id != user.id {
377 return Err((
378 Status::Forbidden,
379 Json(json!({
380 "error": "Forbidden",
381 "message": "You do not have permission to mark this notification as read"
382 }))
383 ));
384 }
385
386 match db::notification::mark_user_notification_as_read(
387 &pool,
388 id,
389 ).await {
390 Ok(updated_notification) => Ok(Json(json!({
391 "message": "Notification marked as read",
392 "notification": updated_notification
393 }))),
394 Err(e) => {
395 log::error!("Failed to mark notification as read: {}", e);
396 Err((
397 Status::InternalServerError,
398 Json(json!({
399 "error": "Database error",
400 "message": "Failed to mark notification as read"
401 }))
402 ))
403 }
404 }
405}
406
407#[put("/platform/<platform_id>/notifications/user/<user_id>/read-all")]
409pub async fn mark_all_user_notifications_as_read(
410 platform_id: i64,
411 user_id: i64,
412 user: User, db_manager: &State<Arc<DatabaseManager>>,
414) -> Result<Json<Value>, (Status, Json<Value>)> {
415 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
417 Ok(platform) => platform,
418 Err(_) => {
419 return Err((
420 Status::NotFound,
421 Json(json!({
422 "error": "Platform not found",
423 "message": format!("Platform with ID {} does not exist", platform_id)
424 }))
425 ));
426 }
427 };
428
429 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
431 Ok(pool) => pool,
432 Err(_) => {
433 return Err((
434 Status::InternalServerError,
435 Json(json!({
436 "error": "Database error",
437 "message": "Failed to connect to platform database"
438 }))
439 ));
440 }
441 };
442
443 if user.id != user_id {
446 return Err((
447 Status::Forbidden,
448 Json(json!({
449 "error": "Forbidden",
450 "message": "You do not have permission to mark this user's notifications as read"
451 }))
452 ));
453 }
454
455 match db::notification::mark_all_user_notifications_as_read(
456 &pool,
457 user_id,
458 ).await {
459 Ok(_) => Ok(Json(json!({
460 "message": "All notifications marked as read",
461 }))),
462 Err(e) => {
463 log::error!("Failed to mark all notifications as read: {}", e);
464 Err((
465 Status::InternalServerError,
466 Json(json!({
467 "error": "Database error",
468 "message": "Failed to mark all notifications as read"
469 }))
470 ))
471 }
472 }
473}
474
475#[delete("/platform/<platform_id>/notifications/<id>")]
477pub async fn delete_user_notification(
478 platform_id: i64,
479 id: i64,
480 user: User, db_manager: &State<Arc<DatabaseManager>>,
482) -> Result<Json<Value>, (Status, Json<Value>)> {
483 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
485 Ok(platform) => platform,
486 Err(_) => {
487 return Err((
488 Status::NotFound,
489 Json(json!({
490 "error": "Platform not found",
491 "message": format!("Platform with ID {} does not exist", platform_id)
492 }))
493 ));
494 }
495 };
496
497 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
499 Ok(pool) => pool,
500 Err(_) => {
501 return Err((
502 Status::InternalServerError,
503 Json(json!({
504 "error": "Database error",
505 "message": "Failed to connect to platform database"
506 }))
507 ));
508 }
509 };
510
511 let notification = match db::notification::get_user_notification_by_id(
513 &pool,
514 id,
515 ).await {
516 Ok(notification) => notification,
517 Err(e) => {
518 log::error!("Failed to fetch notification: {}", e);
519 if e.to_string().contains("no rows") {
520 return Err((
521 Status::NotFound,
522 Json(json!({
523 "error": "Not found",
524 "message": format!("Notification with ID {} does not exist", id)
525 }))
526 ));
527 } else {
528 return Err((
529 Status::InternalServerError,
530 Json(json!({
531 "error": "Database error",
532 "message": "Failed to fetch notification"
533 }))
534 ));
535 }
536 }
537 };
538
539 if notification.user_id != user.id {
542 return Err((
543 Status::Forbidden,
544 Json(json!({
545 "error": "Forbidden",
546 "message": "You do not have permission to delete this notification"
547 }))
548 ));
549 }
550
551 match db::notification::delete_user_notification(
552 &pool,
553 id,
554 ).await {
555 Ok(_) => Ok(Json(json!({
556 "message": "Notification deleted successfully",
557 }))),
558 Err(e) => {
559 log::error!("Failed to delete notification: {}", e);
560 Err((
561 Status::InternalServerError,
562 Json(json!({
563 "error": "Database error",
564 "message": "Failed to delete notification"
565 }))
566 ))
567 }
568 }
569}
570
571#[delete("/platform/<platform_id>/notifications/user/<user_id>/read")]
573pub async fn delete_read_user_notifications(
574 platform_id: i64,
575 user_id: i64,
576 user: User, db_manager: &State<Arc<DatabaseManager>>,
578) -> Result<Json<Value>, (Status, Json<Value>)> {
579 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
581 Ok(platform) => platform,
582 Err(_) => {
583 return Err((
584 Status::NotFound,
585 Json(json!({
586 "error": "Platform not found",
587 "message": format!("Platform with ID {} does not exist", platform_id)
588 }))
589 ));
590 }
591 };
592
593 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
595 Ok(pool) => pool,
596 Err(_) => {
597 return Err((
598 Status::InternalServerError,
599 Json(json!({
600 "error": "Database error",
601 "message": "Failed to connect to platform database"
602 }))
603 ));
604 }
605 };
606
607 if user.id != user_id {
610 return Err((
611 Status::Forbidden,
612 Json(json!({
613 "error": "Forbidden",
614 "message": "You do not have permission to delete this user's notifications"
615 }))
616 ));
617 }
618
619 match db::notification::delete_read_user_notifications(
620 &pool,
621 user_id,
622 ).await {
623 Ok(count) => Ok(Json(json!({
624 "message": "Read notifications deleted successfully",
625 "count": count
626 }))),
627 Err(e) => {
628 log::error!("Failed to delete read notifications: {}", e);
629 Err((
630 Status::InternalServerError,
631 Json(json!({
632 "error": "Database error",
633 "message": "Failed to delete read notifications"
634 }))
635 ))
636 }
637 }
638}
639
640#[get("/platform/<platform_id>/notifications/user/<user_id>/all?<page>&<per_page>")]
642pub async fn get_all_user_notifications_with_count(
643 platform_id: i64,
644 user_id: i64,
645 page: Option<i64>,
646 per_page: Option<i64>,
647 user: User, db_manager: &State<Arc<DatabaseManager>>,
649) -> Result<Json<Value>, (Status, Json<Value>)> {
650 let platform = match db::platforms::get_platform_by_id(db_manager.get_main_pool(), platform_id).await {
652 Ok(platform) => platform,
653 Err(_) => {
654 return Err((
655 Status::NotFound,
656 Json(json!({
657 "error": "Platform not found",
658 "message": format!("Platform with ID {} does not exist", platform_id)
659 }))
660 ));
661 }
662 };
663
664 let pool = match db_manager.get_platform_pool(&platform.name, platform_id).await {
666 Ok(pool) => pool,
667 Err(_) => {
668 return Err((
669 Status::InternalServerError,
670 Json(json!({
671 "error": "Database error",
672 "message": "Failed to connect to platform database"
673 }))
674 ));
675 }
676 };
677
678 if user.id != user_id {
681 return Err((
682 Status::Forbidden,
683 Json(json!({
684 "error": "Forbidden",
685 "message": "You do not have permission to view this user's notifications"
686 }))
687 ));
688 }
689
690 let page = page.unwrap_or(0);
692 let per_page = per_page.unwrap_or(20);
693
694 match db::notification::get_all_user_notifications_with_count(
695 &pool,
696 user_id,
697 page,
698 per_page,
699 ).await {
700 Ok(notifications_with_count) => Ok(Json(json!(notifications_with_count))),
701 Err(e) => {
702 log::error!("Failed to fetch notifications with count: {}", e);
703 Err((
704 Status::InternalServerError,
705 Json(json!({
706 "error": "Database error",
707 "message": "Failed to fetch notifications with count"
708 }))
709 ))
710 }
711 }
712}