adding recent feature + bug fixed

This commit is contained in:
DioCrafts
2025-04-02 05:08:30 +02:00
parent 21e2eb1ea9
commit a79c335b73
21 changed files with 1112 additions and 15 deletions
+1
View File
@@ -7,6 +7,7 @@ pub mod trash_handler;
pub mod search_handler;
pub mod share_handler;
pub mod favorites_handler;
pub mod recent_handler;
/// Tipo de resultado para controladores de API
pub type ApiResult<T> = Result<T, (axum::http::StatusCode, String)>;
@@ -0,0 +1,152 @@
use std::sync::Arc;
use axum::{
extract::{Path, State, Query},
http::StatusCode,
response::IntoResponse,
Json,
};
use serde::{Deserialize, Serialize};
use tracing::{error, info};
use crate::application::ports::recent_ports::RecentItemsUseCase;
/// Parámetros de consulta para obtener elementos recientes
#[derive(Deserialize)]
pub struct GetRecentParams {
#[serde(default)]
limit: Option<i32>,
}
/// Obtener elementos recientes del usuario
pub async fn get_recent_items(
State(recent_service): State<Arc<dyn RecentItemsUseCase>>,
Query(params): Query<GetRecentParams>,
) -> impl IntoResponse {
// Para pruebas, usando ID de usuario fijo
let user_id = "00000000-0000-0000-0000-000000000000";
match recent_service.get_recent_items(user_id, params.limit).await {
Ok(items) => {
info!("Recuperados {} elementos recientes para usuario", items.len());
(StatusCode::OK, Json(items)).into_response()
},
Err(err) => {
error!("Error al recuperar elementos recientes: {}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(serde_json::json!({
"error": format!("Fallo al recuperar elementos recientes: {}", err)
}))
).into_response()
}
}
}
/// Registrar acceso a un elemento
pub async fn record_item_access(
State(recent_service): State<Arc<dyn RecentItemsUseCase>>,
Path((item_type, item_id)): Path<(String, String)>,
) -> impl IntoResponse {
// Para pruebas, usando ID de usuario fijo
let user_id = "00000000-0000-0000-0000-000000000000";
// Validar tipo de elemento
if item_type != "file" && item_type != "folder" {
return (
StatusCode::BAD_REQUEST,
Json(serde_json::json!({
"error": "El tipo de elemento debe ser 'file' o 'folder'"
}))
).into_response();
}
match recent_service.record_item_access(user_id, &item_id, &item_type).await {
Ok(_) => {
info!("Registrado acceso a {} '{}' en recientes", item_type, item_id);
(
StatusCode::OK,
Json(serde_json::json!({
"message": "Acceso registrado correctamente"
}))
).into_response()
},
Err(err) => {
error!("Error al registrar acceso en recientes: {}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(serde_json::json!({
"error": format!("Fallo al registrar acceso: {}", err)
}))
).into_response()
}
}
}
/// Eliminar un elemento de recientes
pub async fn remove_from_recent(
State(recent_service): State<Arc<dyn RecentItemsUseCase>>,
Path((item_type, item_id)): Path<(String, String)>,
) -> impl IntoResponse {
// Para pruebas, usando ID de usuario fijo
let user_id = "00000000-0000-0000-0000-000000000000";
match recent_service.remove_from_recent(user_id, &item_id, &item_type).await {
Ok(removed) => {
if removed {
info!("Eliminado {} '{}' de recientes", item_type, item_id);
(
StatusCode::OK,
Json(serde_json::json!({
"message": "Elemento eliminado de recientes"
}))
).into_response()
} else {
info!("Elemento {} '{}' no estaba en recientes", item_type, item_id);
(
StatusCode::NOT_FOUND,
Json(serde_json::json!({
"message": "Elemento no estaba en recientes"
}))
).into_response()
}
},
Err(err) => {
error!("Error al eliminar de recientes: {}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(serde_json::json!({
"error": format!("Fallo al eliminar de recientes: {}", err)
}))
).into_response()
}
}
}
/// Limpiar todos los elementos recientes
pub async fn clear_recent_items(
State(recent_service): State<Arc<dyn RecentItemsUseCase>>,
) -> impl IntoResponse {
// Para pruebas, usando ID de usuario fijo
let user_id = "00000000-0000-0000-0000-000000000000";
match recent_service.clear_recent_items(user_id).await {
Ok(_) => {
info!("Limpiados todos los elementos recientes para usuario");
(
StatusCode::OK,
Json(serde_json::json!({
"message": "Elementos recientes limpiados correctamente"
}))
).into_response()
},
Err(err) => {
error!("Error al limpiar elementos recientes: {}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(serde_json::json!({
"error": format!("Fallo al limpiar elementos recientes: {}", err)
}))
).into_response()
}
}
}
+20 -1
View File
@@ -26,6 +26,7 @@ use crate::application::ports::trash_ports::TrashUseCase;
use crate::application::ports::inbound::SearchUseCase;
use crate::application::ports::share_ports::ShareUseCase;
use crate::application::ports::favorites_ports::FavoritesUseCase;
use crate::application::ports::recent_ports::RecentItemsUseCase;
use crate::interfaces::api::handlers::folder_handler::FolderHandler;
use crate::interfaces::api::handlers::file_handler::FileHandler;
@@ -45,6 +46,7 @@ pub fn create_api_routes(
search_service: Option<Arc<dyn SearchUseCase>>,
share_service: Option<Arc<dyn ShareUseCase>>,
favorites_service: Option<Arc<dyn FavoritesUseCase>>,
recent_service: Option<Arc<dyn RecentItemsUseCase>>,
) -> Router<crate::common::di::AppState> {
// Create a simplified AppState for the trash view
// Setup required components for repository construction
@@ -109,12 +111,14 @@ pub fn create_api_routes(
search_service: search_service.clone(), // Include the search service
share_service: share_service.clone(), // Include the share service
favorites_service: favorites_service.clone(), // Include the favorites service
recent_service: recent_service.clone(), // Include the recent service
},
db_pool: None,
auth_service: None,
trash_service: trash_service.clone(), // This is the important part - include the trash service
share_service: share_service.clone(), // Include the share service for routes
favorites_service: favorites_service.clone() // Include the favorites service for routes
favorites_service: favorites_service.clone(), // Include the favorites service for routes
recent_service: recent_service.clone() // Include the recent service for routes
};
// Inicializar el servicio de operaciones por lotes
let batch_service = Arc::new(BatchOperationService::default(
@@ -340,6 +344,20 @@ pub fn create_api_routes(
} else {
Router::new()
};
// Create routes for recent items if the service is available
let recent_router = if let Some(recent_service) = recent_service.clone() {
use crate::interfaces::api::handlers::recent_handler;
Router::new()
.route("/", get(recent_handler::get_recent_items))
.route("/{item_type}/{item_id}", post(recent_handler::record_item_access))
.route("/{item_type}/{item_id}", delete(recent_handler::remove_from_recent))
.route("/clear", delete(recent_handler::clear_recent_items))
.with_state(recent_service.clone())
} else {
Router::new()
};
let mut router = Router::new()
.nest("/folders", folders_router)
@@ -349,6 +367,7 @@ pub fn create_api_routes(
.nest("/shares", share_router)
.nest("/s", public_share_router)
.nest("/favorites", favorites_router)
.nest("/recent", recent_router)
;
// Store the share service in app_state for future use