gitdataai/libs/api/room/notification.rs
2026-04-15 09:08:09 +08:00

133 lines
3.8 KiB
Rust

use crate::{ApiResponse, error::ApiError};
use actix_web::{HttpResponse, Result, web};
use room::ws_context::WsUserContext;
use service::AppService;
use session::Session;
use utoipa::IntoParams;
use uuid::Uuid;
#[derive(Debug, serde::Deserialize, IntoParams)]
pub struct NotificationListQuery {
pub only_unread: Option<bool>,
pub archived: Option<bool>,
pub limit: Option<u64>,
}
#[utoipa::path(
get,
path = "/api/me/notifications",
params(
("only_unread" = Option<bool>, Query),
("archived" = Option<bool>, Query),
("limit" = Option<u64>, Query),
),
responses(
(status = 200, description = "List notifications", body = ApiResponse<room::NotificationListResponse>),
(status = 401, description = "Unauthorized"),
),
tag = "Room"
)]
pub async fn notification_list(
service: web::Data<AppService>,
session: Session,
query: web::Query<NotificationListQuery>,
) -> Result<HttpResponse, ApiError> {
let user_id = session
.user()
.ok_or_else(|| ApiError::from(service::error::AppError::Unauthorized))?;
let ctx = WsUserContext::new(user_id);
let resp = service
.room
.notification_list(query.only_unread, query.archived, query.limit, &ctx)
.await
.map_err(ApiError::from)?;
Ok(ApiResponse::ok(resp).to_response())
}
#[utoipa::path(
post,
path = "/api/me/notifications/{notification_id}/read",
params(
("notification_id" = Uuid, Path),
),
responses(
(status = 200, description = "Mark notification as read"),
(status = 401, description = "Unauthorized"),
(status = 404, description = "Not found"),
),
tag = "Room"
)]
pub async fn notification_mark_read(
service: web::Data<AppService>,
session: Session,
path: web::Path<Uuid>,
) -> Result<HttpResponse, ApiError> {
let notification_id = path.into_inner();
let user_id = session
.user()
.ok_or_else(|| ApiError::from(service::error::AppError::Unauthorized))?;
let ctx = WsUserContext::new(user_id);
service
.room
.notification_mark_read(notification_id, &ctx)
.await
.map_err(ApiError::from)?;
Ok(ApiResponse::ok(true).to_response())
}
#[utoipa::path(
post,
path = "/api/me/notifications/read-all",
responses(
(status = 200, description = "Mark all notifications as read"),
(status = 401, description = "Unauthorized"),
),
tag = "Room"
)]
pub async fn notification_mark_all_read(
service: web::Data<AppService>,
session: Session,
) -> Result<HttpResponse, ApiError> {
let user_id = session
.user()
.ok_or_else(|| ApiError::from(service::error::AppError::Unauthorized))?;
let ctx = WsUserContext::new(user_id);
let count = service
.room
.notification_mark_all_read(&ctx)
.await
.map_err(ApiError::from)?;
Ok(ApiResponse::ok(count).to_response())
}
#[utoipa::path(
post,
path = "/api/me/notifications/{notification_id}/archive",
params(
("notification_id" = Uuid, Path),
),
responses(
(status = 200, description = "Archive notification"),
(status = 401, description = "Unauthorized"),
(status = 404, description = "Not found"),
),
tag = "Room"
)]
pub async fn notification_archive(
service: web::Data<AppService>,
session: Session,
path: web::Path<Uuid>,
) -> Result<HttpResponse, ApiError> {
let notification_id = path.into_inner();
let user_id = session
.user()
.ok_or_else(|| ApiError::from(service::error::AppError::Unauthorized))?;
let ctx = WsUserContext::new(user_id);
service
.room
.notification_archive(notification_id, &ctx)
.await
.map_err(ApiError::from)?;
Ok(ApiResponse::ok(true).to_response())
}