Files
Oxicloud/src/interfaces/api/handlers/recent_handler.rs
T

216 lines
6.2 KiB
Rust
Raw Normal View History

2025-04-02 05:08:30 +02:00
use axum::{
2026-02-14 01:29:34 +01:00
Json,
extract::{Path, Query, State},
2025-04-02 05:08:30 +02:00
http::StatusCode,
response::IntoResponse,
};
2025-04-04 21:31:41 +02:00
use serde::Deserialize;
2026-02-14 01:29:34 +01:00
use std::sync::Arc;
2025-04-02 05:08:30 +02:00
use tracing::{error, info};
use crate::application::ports::recent_ports::RecentItemsUseCase;
use crate::application::services::recent_service::RecentService;
use crate::interfaces::middleware::auth::AuthUser;
2025-04-02 05:08:30 +02:00
/// Query parameters for getting recent items
2025-04-02 05:08:30 +02:00
#[derive(Deserialize)]
pub struct GetRecentParams {
#[serde(default)]
limit: Option<i32>,
}
/// Get user's recent items
#[utoipa::path(
get,
path = "/api/recent",
responses(
(status = 200, description = "List of recent items", body = Vec<crate::application::dtos::recent_dto::RecentItemDto>)
),
security(("bearerAuth" = [])),
tag = "recent"
)]
2025-04-02 05:08:30 +02:00
pub async fn get_recent_items(
State(recent_service): State<Arc<RecentService>>,
2026-02-07 04:02:38 +01:00
auth_user: AuthUser,
2025-04-02 05:08:30 +02:00
Query(params): Query<GetRecentParams>,
) -> impl IntoResponse {
let user_id = auth_user.id;
2026-02-14 01:29:34 +01:00
2025-04-02 05:08:30 +02:00
match recent_service.get_recent_items(user_id, params.limit).await {
Ok(items) => {
info!("Retrieved {} recent items for user", items.len());
2025-04-02 05:08:30 +02:00
(StatusCode::OK, Json(items)).into_response()
2026-02-14 01:29:34 +01:00
}
2025-04-02 05:08:30 +02:00
Err(err) => {
error!("Error retrieving recent items: {}", err);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::INTERNAL_SERVER_ERROR,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"error": "Failed to retrieve recent items"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
2025-04-02 05:08:30 +02:00
}
}
}
/// Record access to an item
#[utoipa::path(
post,
path = "/api/recent/{item_type}/{item_id}",
params(
("item_type" = String, Path, description = "Item type (file or folder)"),
("item_id" = String, Path, description = "Item ID")
),
responses(
(status = 200, description = "Access recorded"),
(status = 400, description = "Invalid item type")
),
security(("bearerAuth" = [])),
tag = "recent"
)]
2025-04-02 05:08:30 +02:00
pub async fn record_item_access(
State(recent_service): State<Arc<RecentService>>,
2026-02-07 04:02:38 +01:00
auth_user: AuthUser,
2025-04-02 05:08:30 +02:00
Path((item_type, item_id)): Path<(String, String)>,
) -> impl IntoResponse {
let user_id = auth_user.id;
2026-02-14 01:29:34 +01:00
// Validate item type
2025-04-02 05:08:30 +02:00
if item_type != "file" && item_type != "folder" {
return (
2026-02-14 01:29:34 +01:00
StatusCode::BAD_REQUEST,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"error": "Item type must be 'file' or 'folder'"
2026-02-14 01:29:34 +01:00
})),
)
.into_response();
2025-04-02 05:08:30 +02:00
}
2026-02-14 01:29:34 +01:00
match recent_service
.record_item_access(user_id, &item_id, &item_type)
.await
{
2025-04-02 05:08:30 +02:00
Ok(_) => {
info!("Recorded access to {} '{}' in recents", item_type, item_id);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::OK,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"message": "Access recorded successfully"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
}
2025-04-02 05:08:30 +02:00
Err(err) => {
error!("Error recording access in recents: {}", err);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::INTERNAL_SERVER_ERROR,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"error": "Failed to record access"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
2025-04-02 05:08:30 +02:00
}
}
}
/// Remove an item from recents
#[utoipa::path(
delete,
path = "/api/recent/{item_type}/{item_id}",
params(
("item_type" = String, Path, description = "Item type (file or folder)"),
("item_id" = String, Path, description = "Item ID")
),
responses(
(status = 200, description = "Item removed from recents"),
(status = 404, description = "Item not in recents")
),
security(("bearerAuth" = [])),
tag = "recent"
)]
2025-04-02 05:08:30 +02:00
pub async fn remove_from_recent(
State(recent_service): State<Arc<RecentService>>,
2026-02-07 04:02:38 +01:00
auth_user: AuthUser,
2025-04-02 05:08:30 +02:00
Path((item_type, item_id)): Path<(String, String)>,
) -> impl IntoResponse {
let user_id = auth_user.id;
2026-02-14 01:29:34 +01:00
match recent_service
.remove_from_recent(user_id, &item_id, &item_type)
.await
{
2025-04-02 05:08:30 +02:00
Ok(removed) => {
if removed {
info!("Removed {} '{}' from recents", item_type, item_id);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::OK,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"message": "Item removed from recents"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
2025-04-02 05:08:30 +02:00
} else {
info!("Item {} '{}' was not in recents", item_type, item_id);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::NOT_FOUND,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"message": "Item was not in recents"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
2025-04-02 05:08:30 +02:00
}
2026-02-14 01:29:34 +01:00
}
2025-04-02 05:08:30 +02:00
Err(err) => {
error!("Error removing from recents: {}", err);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::INTERNAL_SERVER_ERROR,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"error": "Failed to remove from recents"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
2025-04-02 05:08:30 +02:00
}
}
}
/// Clear all recent items
#[utoipa::path(
delete,
path = "/api/recent/clear",
responses(
(status = 200, description = "Recent items cleared")
),
security(("bearerAuth" = [])),
tag = "recent"
)]
2025-04-02 05:08:30 +02:00
pub async fn clear_recent_items(
State(recent_service): State<Arc<RecentService>>,
2026-02-07 04:02:38 +01:00
auth_user: AuthUser,
2025-04-02 05:08:30 +02:00
) -> impl IntoResponse {
let user_id = auth_user.id;
2026-02-14 01:29:34 +01:00
2025-04-02 05:08:30 +02:00
match recent_service.clear_recent_items(user_id).await {
Ok(_) => {
info!("Cleared all recent items for user");
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::OK,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"message": "Recent items cleared successfully"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
}
2025-04-02 05:08:30 +02:00
Err(err) => {
error!("Error clearing recent items: {}", err);
2025-04-02 05:08:30 +02:00
(
2026-02-14 01:29:34 +01:00
StatusCode::INTERNAL_SERVER_ERROR,
2025-04-02 05:08:30 +02:00
Json(serde_json::json!({
"error": "Failed to clear recent items"
2026-02-14 01:29:34 +01:00
})),
)
.into_response()
2025-04-02 05:08:30 +02:00
}
}
2026-02-14 01:29:34 +01:00
}