chore: translate all Spanish comments and log messages to English

This commit is contained in:
Dionisio
2026-02-12 09:41:25 +01:00
parent bc169de8f6
commit d31a413e57
89 changed files with 2480 additions and 2482 deletions
+18 -18
View File
@@ -65,49 +65,49 @@ pub trait TokenServicePort: Send + Sync + 'static {
#[async_trait]
pub trait UserStoragePort: Send + Sync + 'static {
/// Crea un nuevo usuario
/// Creates a new user
async fn create_user(&self, user: User) -> Result<User, DomainError>;
/// Obtiene un usuario por ID
/// Gets a user by ID
async fn get_user_by_id(&self, id: &str) -> Result<User, DomainError>;
/// Obtiene un usuario por nombre de usuario
/// Gets a user by username
async fn get_user_by_username(&self, username: &str) -> Result<User, DomainError>;
/// Obtiene un usuario por correo electrónico
/// Gets a user by email
async fn get_user_by_email(&self, email: &str) -> Result<User, DomainError>;
/// Actualiza un usuario existente
/// Updates an existing user
async fn update_user(&self, user: User) -> Result<User, DomainError>;
/// Actualiza solo el uso de almacenamiento de un usuario
/// Updates only the storage usage of a user
async fn update_storage_usage(&self, user_id: &str, usage_bytes: i64) -> Result<(), DomainError>;
/// Lista usuarios con paginación
/// Lists users with pagination
async fn list_users(&self, limit: i64, offset: i64) -> Result<Vec<User>, DomainError>;
/// Lista usuarios por rol (por ejemplo, "admin" o "user")
/// Lists users by role (e.g., "admin" or "user")
async fn list_users_by_role(&self, role: &str) -> Result<Vec<User>, DomainError>;
/// Elimina un usuario por su ID
/// Deletes a user by their ID
async fn delete_user(&self, user_id: &str) -> Result<(), DomainError>;
/// Cambia la contraseña de un usuario
/// Changes a user's password
async fn change_password(&self, user_id: &str, password_hash: &str) -> Result<(), DomainError>;
/// Finds a user by OIDC provider + subject pair
async fn get_user_by_oidc_subject(&self, provider: &str, subject: &str) -> Result<User, DomainError>;
/// Activa o desactiva un usuario
/// Activates or deactivates a user
async fn set_user_active_status(&self, user_id: &str, active: bool) -> Result<(), DomainError>;
/// Cambia el rol de un usuario
/// Changes a user's role
async fn change_role(&self, user_id: &str, role: &str) -> Result<(), DomainError>;
/// Actualiza la cuota de almacenamiento de un usuario
/// Updates a user's storage quota
async fn update_storage_quota(&self, user_id: &str, quota_bytes: i64) -> Result<(), DomainError>;
/// Cuenta el número total de usuarios
/// Counts the total number of users
async fn count_users(&self) -> Result<i64, DomainError>;
}
@@ -156,15 +156,15 @@ pub trait OidcServicePort: Send + Sync + 'static {
#[async_trait]
pub trait SessionStoragePort: Send + Sync + 'static {
/// Crea una nueva sesión
/// Creates a new session
async fn create_session(&self, session: Session) -> Result<Session, DomainError>;
/// Obtiene una sesión por token de actualización
/// Gets a session by refresh token
async fn get_session_by_refresh_token(&self, refresh_token: &str) -> Result<Session, DomainError>;
/// Revoca una sesión específica
/// Revokes a specific session
async fn revoke_session(&self, session_id: &str) -> Result<(), DomainError>;
/// Revoca todas las sesiones de un usuario
/// Revokes all sessions of a user
async fn revoke_all_user_sessions(&self, user_id: &str) -> Result<u64, DomainError>;
}
+8 -8
View File
@@ -22,22 +22,22 @@ pub trait FavoritesUseCase: Send + Sync {
// Outbound port — persistence abstraction
// ─────────────────────────────────────────────────────
/// Puerto secundario (outbound) para persistencia de favoritos.
/// Secondary (outbound) port for favorites persistence.
///
/// Los servicios de aplicación dependen de este trait en lugar de
/// acceder directamente a `PgPool`. La implementación concreta
/// vive en `infrastructure::repositories::pg`.
/// Application services depend on this trait instead of
/// accessing `PgPool` directly. The concrete implementation
/// lives in `infrastructure::repositories::pg`.
#[async_trait]
pub trait FavoritesRepositoryPort: Send + Sync + 'static {
/// Obtiene todos los favoritos de un usuario.
/// Gets all favorites for a user.
async fn get_favorites(&self, user_id: &str) -> Result<Vec<FavoriteItemDto>>;
/// Añade un ítem a favoritos. Devuelve `Ok(())` si ya existía (idempotente).
/// Adds an item to favorites. Returns `Ok(())` if it already existed (idempotent).
async fn add_favorite(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<()>;
/// Elimina un ítem de favoritos. Devuelve `true` si existía.
/// Removes an item from favorites. Returns `true` if it existed.
async fn remove_favorite(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<bool>;
/// Comprueba si un ítem está en favoritos.
/// Checks if an item is in favorites.
async fn is_favorite(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<bool>;
}
+15 -15
View File
@@ -22,10 +22,10 @@ pub enum UploadStrategy {
Streaming,
}
/// Puerto primario para operaciones de subida de archivos
/// Primary port for file upload operations
#[async_trait]
pub trait FileUploadUseCase: Send + Sync + 'static {
/// Sube un nuevo archivo desde bytes
/// Uploads a new file from bytes
async fn upload_file(
&self,
name: String,
@@ -47,10 +47,10 @@ pub trait FileUploadUseCase: Send + Sync + 'static {
total_size: usize,
) -> Result<(FileDto, UploadStrategy), DomainError>;
/// Crea un nuevo archivo en la ruta especificada (para WebDAV)
/// Creates a new file at the specified path (for WebDAV)
async fn create_file(&self, parent_path: &str, filename: &str, content: &[u8], content_type: &str) -> Result<FileDto, DomainError>;
/// Actualiza el contenido de un archivo existente (para WebDAV)
/// Updates the content of an existing file (for WebDAV)
async fn update_file(&self, path: &str, content: &[u8]) -> Result<(), DomainError>;
}
@@ -76,22 +76,22 @@ pub enum OptimizedFileContent {
Stream(Pin<Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send>>),
}
/// Puerto primario para operaciones de recuperación de archivos
/// Primary port for file retrieval operations
#[async_trait]
pub trait FileRetrievalUseCase: Send + Sync + 'static {
/// Obtiene un archivo por su ID
/// Gets a file by its ID
async fn get_file(&self, id: &str) -> Result<FileDto, DomainError>;
/// Obtiene un archivo por su ruta (para WebDAV)
/// Gets a file by its path (for WebDAV)
async fn get_file_by_path(&self, path: &str) -> Result<FileDto, DomainError>;
/// Lista archivos en una carpeta
/// Lists files in a folder
async fn list_files(&self, folder_id: Option<&str>) -> Result<Vec<FileDto>, DomainError>;
/// Obtiene contenido de archivo como bytes (para archivos pequeños)
/// Gets file content as bytes (for small files)
async fn get_file_content(&self, id: &str) -> Result<Vec<u8>, DomainError>;
/// Obtiene contenido de archivo como stream (para archivos grandes)
/// Gets file content as a stream (for large files)
async fn get_file_stream(&self, id: &str) -> Result<Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send>, DomainError>;
/// Optimized multi-tier download.
@@ -119,16 +119,16 @@ pub trait FileRetrievalUseCase: Send + Sync + 'static {
// Management port (delete, move)
// ─────────────────────────────────────────────────────
/// Puerto primario para operaciones de gestión de archivos
/// Primary port for file management operations
#[async_trait]
pub trait FileManagementUseCase: Send + Sync + 'static {
/// Mueve un archivo a otra carpeta
/// Moves a file to another folder
async fn move_file(&self, file_id: &str, folder_id: Option<String>) -> Result<FileDto, DomainError>;
/// Renombra un archivo
/// Renames a file
async fn rename_file(&self, file_id: &str, new_name: &str) -> Result<FileDto, DomainError>;
/// Elimina un archivo
/// Deletes a file
async fn delete_file(&self, id: &str) -> Result<(), DomainError>;
/// Smart delete: trash-first with dedup reference cleanup.
@@ -145,7 +145,7 @@ pub trait FileManagementUseCase: Send + Sync + 'static {
) -> Result<bool, DomainError>;
}
/// Factory para crear implementaciones de casos de uso de archivos
/// Factory for creating file use case implementations
pub trait FileUseCaseFactory: Send + Sync + 'static {
fn create_file_upload_use_case(&self) -> Arc<dyn FileUploadUseCase>;
fn create_file_retrieval_use_case(&self) -> Arc<dyn FileRetrievalUseCase>;
+17 -17
View File
@@ -4,58 +4,58 @@ use crate::application::dtos::folder_dto::{CreateFolderDto, FolderDto, MoveFolde
use crate::application::dtos::search_dto::{SearchCriteriaDto, SearchResultsDto};
use crate::common::errors::DomainError;
/// Puerto primario para operaciones de carpetas
/// Primary port for folder operations
#[async_trait]
pub trait FolderUseCase: Send + Sync + 'static {
/// Crea una nueva carpeta
/// Creates a new folder
async fn create_folder(&self, dto: CreateFolderDto) -> Result<FolderDto, DomainError>;
/// Obtiene una carpeta por su ID
/// Gets a folder by its ID
async fn get_folder(&self, id: &str) -> Result<FolderDto, DomainError>;
/// Obtiene una carpeta por su ruta
/// Gets a folder by its path
async fn get_folder_by_path(&self, path: &str) -> Result<FolderDto, DomainError>;
/// Lista carpetas dentro de una carpeta padre
/// Lists folders within a parent folder
async fn list_folders(&self, parent_id: Option<&str>) -> Result<Vec<FolderDto>, DomainError>;
/// Lista carpetas con paginación
/// Lists folders with pagination
async fn list_folders_paginated(
&self,
parent_id: Option<&str>,
pagination: &crate::application::dtos::pagination::PaginationRequestDto
) -> Result<crate::application::dtos::pagination::PaginatedResponseDto<FolderDto>, DomainError>;
/// Renombra una carpeta
/// Renames a folder
async fn rename_folder(&self, id: &str, dto: RenameFolderDto) -> Result<FolderDto, DomainError>;
/// Mueve una carpeta a otro padre
/// Moves a folder to another parent
async fn move_folder(&self, id: &str, dto: MoveFolderDto) -> Result<FolderDto, DomainError>;
/// Elimina una carpeta
/// Deletes a folder
async fn delete_folder(&self, id: &str) -> Result<(), DomainError>;
}
/**
* Puerto primario para búsqueda de archivos y carpetas
* Primary port for file and folder search
*
* Define las operaciones relacionadas con la búsqueda avanzada de
* archivos y carpetas basándose en diversos criterios.
* Defines the operations related to advanced search of
* files and folders based on various criteria.
*/
#[async_trait]
pub trait SearchUseCase: Send + Sync + 'static {
/**
* Realiza una búsqueda basada en los criterios especificados
* Performs a search based on the specified criteria
*
* @param criteria Criterios de búsqueda que incluyen texto, fechas, tamaños, etc.
* @return Resultados de la búsqueda que contienen archivos y carpetas coincidentes
* @param criteria Search criteria including text, dates, sizes, etc.
* @return Search results containing matching files and folders
*/
async fn search(&self, criteria: SearchCriteriaDto) -> Result<SearchResultsDto, DomainError>;
/**
* Limpia la caché de resultados de búsqueda
* Clears the search results cache
*
* @return Resultado indicando éxito o error
* @return Result indicating success or error
*/
async fn clear_search_cache(&self) -> Result<(), DomainError>;
}
+27 -27
View File
@@ -9,71 +9,71 @@ pub use crate::domain::repositories::folder_repository::FolderRepository;
use super::storage_ports::{FileReadPort, FileWritePort};
/// Puerto secundario para operaciones de almacenamiento
/// Secondary port for storage operations
#[async_trait]
pub trait StoragePort: Send + Sync + 'static {
/// Resuelve una ruta de dominio a una ruta física
/// Resolves a domain path to a physical path
fn resolve_path(&self, storage_path: &StoragePath) -> PathBuf;
/// Crea directorios si no existen
/// Creates directories if they don't exist
async fn ensure_directory(&self, storage_path: &StoragePath) -> Result<(), DomainError>;
/// Verifica si existe un archivo en la ruta dada
/// Checks if a file exists at the given path
async fn file_exists(&self, storage_path: &StoragePath) -> Result<bool, DomainError>;
/// Verifica si existe un directorio en la ruta dada
/// Checks if a directory exists at the given path
async fn directory_exists(&self, storage_path: &StoragePath) -> Result<bool, DomainError>;
}
/// Puerto unificado para persistencia de archivos (backward-compatible).
/// Unified port for file persistence (backward-compatible).
///
/// Ahora es un **supertrait** de `FileReadPort + FileWritePort`.
/// Cualquier tipo que implemente ambos ports obtiene `FileStoragePort`
/// automáticamente via blanket impl. Esto permite migrar consumidores
/// gradualmente a los ports granulares mientras los existentes siguen
/// funcionando sin cambios.
/// Now it is a **supertrait** of `FileReadPort + FileWritePort`.
/// Any type that implements both ports gets `FileStoragePort`
/// automatically via blanket impl. This allows consumers to be migrated
/// gradually to granular ports while existing ones continue
/// working without changes.
pub trait FileStoragePort: FileReadPort + FileWritePort {}
/// Blanket implementation: cualquier tipo que implemente ambos ports
/// es automáticamente un FileStoragePort.
/// Blanket implementation: any type that implements both ports
/// is automatically a FileStoragePort.
impl<T: FileReadPort + FileWritePort> FileStoragePort for T {}
/// Puerto secundario para persistencia de carpetas (application layer).
/// Secondary port for folder persistence (application layer).
///
/// Tiene la misma firma que `FolderRepository` del dominio.
/// Las implementaciones concretas deben implementar `FolderRepository`,
/// obteniendo `FolderStoragePort` automáticamente vía blanket impl.
/// Has the same signature as the domain's `FolderRepository`.
/// Concrete implementations must implement `FolderRepository`,
/// getting `FolderStoragePort` automatically via blanket impl.
pub trait FolderStoragePort: FolderRepository {}
/// Blanket implementation: cualquier tipo que implemente FolderRepository
/// es automáticamente un FolderStoragePort.
/// Blanket implementation: any type that implements FolderRepository
/// is automatically a FolderStoragePort.
impl<T: FolderRepository> FolderStoragePort for T {}
/// Puerto secundario para mapeo de IDs
/// Secondary port for ID mapping
#[async_trait]
pub trait IdMappingPort: Send + Sync + 'static {
/// Obtiene o crea un ID para una ruta
/// Gets or creates an ID for a path
async fn get_or_create_id(&self, path: &StoragePath) -> Result<String, DomainError>;
/// Obtiene una ruta por su ID
/// Gets a path by its ID
async fn get_path_by_id(&self, id: &str) -> Result<StoragePath, DomainError>;
/// Actualiza la ruta para un ID existente
/// Updates the path for an existing ID
async fn update_path(&self, id: &str, new_path: &StoragePath) -> Result<(), DomainError>;
/// Elimina un ID del mapeo
/// Removes an ID from the mapping
async fn remove_id(&self, id: &str) -> Result<(), DomainError>;
/// Guarda cambios pendientes
/// Saves pending changes
async fn save_changes(&self) -> Result<(), DomainError>;
/// Obtiene la ruta de archivo como PathBuf
/// Gets the file path as a PathBuf
async fn get_file_path(&self, file_id: &str) -> Result<PathBuf, DomainError> {
let storage_path = self.get_path_by_id(file_id).await?;
Ok(PathBuf::from(storage_path.to_string()))
}
/// Actualiza la ruta de un archivo
/// Updates a file's path
async fn update_file_path(&self, file_id: &str, new_path: &PathBuf) -> Result<(), DomainError> {
let storage_path = StoragePath::from_string(&new_path.to_string_lossy().to_string());
self.update_path(file_id, &storage_path).await
+13 -13
View File
@@ -2,19 +2,19 @@ use async_trait::async_trait;
use crate::common::errors::Result;
use crate::application::dtos::recent_dto::RecentItemDto;
/// Define operaciones para gestionar elementos recientes del usuario
/// Defines operations for managing user recent items
#[async_trait]
pub trait RecentItemsUseCase: Send + Sync {
/// Obtener todos los elementos recientes de un usuario
/// Get all recent items for a user
async fn get_recent_items(&self, user_id: &str, limit: Option<i32>) -> Result<Vec<RecentItemDto>>;
/// Registrar acceso a un elemento
/// Record access to an item
async fn record_item_access(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<()>;
/// Eliminar un elemento de recientes
/// Remove an item from recents
async fn remove_from_recent(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<bool>;
/// Limpiar toda la lista de elementos recientes
/// Clear the entire recent items list
async fn clear_recent_items(&self, user_id: &str) -> Result<()>;
}
@@ -22,24 +22,24 @@ pub trait RecentItemsUseCase: Send + Sync {
// Outbound port — persistence abstraction
// ─────────────────────────────────────────────────────
/// Puerto secundario (outbound) para persistencia de elementos recientes.
/// Secondary (outbound) port for recent items persistence.
///
/// Abstrae el acceso a la tabla `auth.user_recent_files` para que
/// `RecentService` no dependa directamente de `PgPool`.
/// Abstracts access to the `auth.user_recent_files` table so that
/// `RecentService` does not depend directly on `PgPool`.
#[async_trait]
pub trait RecentItemsRepositoryPort: Send + Sync + 'static {
/// Obtiene los últimos elementos recientes de un usuario (ordenados por fecha desc).
/// Gets the latest recent items for a user (ordered by date desc).
async fn get_recent_items(&self, user_id: &str, limit: i32) -> Result<Vec<RecentItemDto>>;
/// Registra/actualiza el acceso a un ítem (upsert por user+item+type).
/// Records/updates access to an item (upsert by user+item+type).
async fn upsert_access(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<()>;
/// Elimina un ítem de recientes. Devuelve `true` si existía.
/// Removes an item from recents. Returns `true` if it existed.
async fn remove_item(&self, user_id: &str, item_id: &str, item_type: &str) -> Result<bool>;
/// Elimina todos los elementos recientes de un usuario.
/// Removes all recent items for a user.
async fn clear_all(&self, user_id: &str) -> Result<()>;
/// Elimina elementos que excedan `max_items` (los más antiguos).
/// Removes items exceeding `max_items` (the oldest ones).
async fn prune(&self, user_id: &str, max_items: i32) -> Result<()>;
}
+37 -37
View File
@@ -17,28 +17,28 @@ pub use crate::domain::repositories::folder_repository::FolderRepository;
// FileReadPort — application-layer alias for FileReadRepository
// ─────────────────────────────────────────────────────
/// Puerto secundario para **lectura** de archivos.
/// Secondary port for file **reading**.
///
/// Encapsula toda operación que consulta estado sin modificarlo:
/// get, list, content, stream, mmap, range, resolución de rutas.
/// Encapsulates every operation that queries state without modifying it:
/// get, list, content, stream, mmap, range, path resolution.
#[async_trait]
pub trait FileReadPort: Send + Sync + 'static {
/// Obtiene un archivo por su ID.
/// Gets a file by its ID.
async fn get_file(&self, id: &str) -> Result<File, DomainError>;
/// Lista archivos en una carpeta.
/// Lists files in a folder.
async fn list_files(&self, folder_id: Option<&str>) -> Result<Vec<File>, DomainError>;
/// Obtiene contenido completo como bytes (solo archivos pequeños/medianos).
/// Gets the full content as bytes (small/medium files only).
async fn get_file_content(&self, id: &str) -> Result<Vec<u8>, DomainError>;
/// Obtiene contenido como stream (ideal para archivos grandes).
/// Gets content as a stream (ideal for large files).
async fn get_file_stream(
&self,
id: &str,
) -> Result<Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send>, DomainError>;
/// Stream de un rango de bytes (HTTP Range Requests, video seek).
/// Stream of a byte range (HTTP Range Requests, video seek).
async fn get_file_range_stream(
&self,
id: &str,
@@ -46,13 +46,13 @@ pub trait FileReadPort: Send + Sync + 'static {
end: Option<u64>,
) -> Result<Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send>, DomainError>;
/// Memory-map de archivo para acceso zero-copy (10–100 MB).
/// Memory-map of a file for zero-copy access (10–100 MB).
async fn get_file_mmap(&self, id: &str) -> Result<Bytes, DomainError>;
/// Obtiene la ruta de almacenamiento lógica de un archivo.
/// Gets the logical storage path of a file.
async fn get_file_path(&self, id: &str) -> Result<StoragePath, DomainError>;
/// Obtiene el ID de la carpeta padre a partir de una ruta (WebDAV).
/// Gets the parent folder ID from a path (WebDAV).
async fn get_parent_folder_id(&self, path: &str) -> Result<String, DomainError>;
}
@@ -60,13 +60,13 @@ pub trait FileReadPort: Send + Sync + 'static {
// FileWritePort — all write / mutate operations
// ─────────────────────────────────────────────────────
/// Puerto secundario para **escritura** de archivos.
/// Secondary port for file **writing**.
///
/// Cubre: upload (buffered + streaming), move, delete, update,
/// y el registro diferido para write-behind cache.
/// Covers: upload (buffered + streaming), move, delete, update,
/// and deferred registration for the write-behind cache.
#[async_trait]
pub trait FileWritePort: Send + Sync + 'static {
/// Guarda un nuevo archivo desde bytes.
/// Saves a new file from bytes.
async fn save_file(
&self,
name: String,
@@ -75,7 +75,7 @@ pub trait FileWritePort: Send + Sync + 'static {
content: Vec<u8>,
) -> Result<File, DomainError>;
/// Upload en streaming — escribe chunks a disco sin acumular en RAM.
/// Streaming upload — writes chunks to disk without accumulating in RAM.
async fn save_file_from_stream(
&self,
name: String,
@@ -84,30 +84,30 @@ pub trait FileWritePort: Send + Sync + 'static {
stream: std::pin::Pin<Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send>>,
) -> Result<File, DomainError>;
/// Mueve un archivo a otra carpeta.
/// Moves a file to another folder.
async fn move_file(
&self,
file_id: &str,
target_folder_id: Option<String>,
) -> Result<File, DomainError>;
/// Renombra un archivo (same folder, different name).
/// Renames a file (same folder, different name).
async fn rename_file(
&self,
file_id: &str,
new_name: &str,
) -> Result<File, DomainError>;
/// Elimina un archivo.
/// Deletes a file.
async fn delete_file(&self, id: &str) -> Result<(), DomainError>;
/// Actualiza el contenido de un archivo existente.
/// Updates the content of an existing file.
async fn update_file_content(&self, file_id: &str, content: Vec<u8>) -> Result<(), DomainError>;
/// Registra metadatos de archivo SIN escribir contenido a disco (write-behind).
/// Registers file metadata WITHOUT writing content to disk (write-behind).
///
/// Devuelve `(File, PathBuf)` donde `PathBuf` es la ruta destino para la
/// escritura diferida que realizará el `WriteBehindCache`.
/// Returns `(File, PathBuf)` where `PathBuf` is the destination path for the
/// deferred write that the `WriteBehindCache` will perform.
async fn register_file_deferred(
&self,
name: String,
@@ -118,13 +118,13 @@ pub trait FileWritePort: Send + Sync + 'static {
// ── Trash operations ──
/// Mueve un archivo a la papelera
/// Moves a file to the trash
async fn move_to_trash(&self, file_id: &str) -> Result<(), DomainError>;
/// Restaura un archivo desde la papelera a su ubicación original
/// Restores a file from the trash to its original location
async fn restore_from_trash(&self, file_id: &str, original_path: &str) -> Result<(), DomainError>;
/// Elimina un archivo permanentemente (usado por la papelera)
/// Permanently deletes a file (used by the trash)
async fn delete_file_permanently(&self, file_id: &str) -> Result<(), DomainError>;
}
@@ -132,40 +132,40 @@ pub trait FileWritePort: Send + Sync + 'static {
// Auxiliary ports (unchanged)
// ─────────────────────────────────────────────────────
/// Puerto secundario para resolución de rutas de archivos
/// Secondary port for file path resolution
#[async_trait]
pub trait FilePathResolutionPort: Send + Sync + 'static {
/// Obtiene la ruta de almacenamiento de un archivo
/// Gets the storage path of a file
async fn get_file_path(&self, id: &str) -> Result<StoragePath, DomainError>;
/// Resuelve una ruta de dominio a una ruta física
/// Resolves a domain path to a physical path
fn resolve_path(&self, storage_path: &StoragePath) -> PathBuf;
}
/// Puerto secundario para verificación de existencia de archivos/directorios
/// Secondary port for file/directory existence verification
#[async_trait]
pub trait StorageVerificationPort: Send + Sync + 'static {
/// Verifica si existe un archivo en la ruta dada
/// Checks whether a file exists at the given path
async fn file_exists(&self, storage_path: &StoragePath) -> Result<bool, DomainError>;
/// Verifica si existe un directorio en la ruta dada
/// Checks whether a directory exists at the given path
async fn directory_exists(&self, storage_path: &StoragePath) -> Result<bool, DomainError>;
}
/// Puerto secundario para gestión de directorios
/// Secondary port for directory management
#[async_trait]
pub trait DirectoryManagementPort: Send + Sync + 'static {
/// Crea directorios si no existen
/// Creates directories if they do not exist
async fn ensure_directory(&self, storage_path: &StoragePath) -> Result<(), DomainError>;
}
/// Puerto secundario para gestión de uso de almacenamiento
/// Secondary port for storage usage management
#[async_trait]
pub trait StorageUsagePort: Send + Sync + 'static {
/// Actualiza estadísticas de uso de almacenamiento para un usuario
/// Updates storage usage statistics for a user
async fn update_user_storage_usage(&self, user_id: &str) -> Result<i64, DomainError>;
/// Actualiza estadísticas de uso de almacenamiento para todos los usuarios
/// Updates storage usage statistics for all users
async fn update_all_users_storage_usage(&self) -> Result<(), DomainError>;
}