2026-02-25 23:47:51 +01:00
|
|
|
use std::sync::Arc;
|
2025-03-19 00:44:27 +01:00
|
|
|
|
2026-02-14 01:29:34 +01:00
|
|
|
use crate::application::dtos::folder_dto::{
|
|
|
|
|
CreateFolderDto, FolderDto, MoveFolderDto, RenameFolderDto,
|
|
|
|
|
};
|
2026-02-15 23:45:11 +01:00
|
|
|
use crate::application::dtos::search_dto::{
|
|
|
|
|
SearchCriteriaDto, SearchResultsDto, SearchSuggestionsDto,
|
|
|
|
|
};
|
2025-03-19 00:44:27 +01:00
|
|
|
use crate::common::errors::DomainError;
|
|
|
|
|
|
2026-02-12 09:41:25 +01:00
|
|
|
/// Primary port for folder operations
|
2025-03-19 00:44:27 +01:00
|
|
|
pub trait FolderUseCase: Send + Sync + 'static {
|
2026-02-12 09:41:25 +01:00
|
|
|
/// Creates a new folder
|
2025-03-19 00:44:27 +01:00
|
|
|
async fn create_folder(&self, dto: CreateFolderDto) -> Result<FolderDto, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-12 09:41:25 +01:00
|
|
|
/// Gets a folder by its ID
|
2025-03-19 00:44:27 +01:00
|
|
|
async fn get_folder(&self, id: &str) -> Result<FolderDto, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-03-05 10:30:39 +01:00
|
|
|
/// Gets a folder by its ID, enforcing that `caller_id` is the owner.
|
|
|
|
|
///
|
|
|
|
|
/// Returns `NotFound` if the folder does not exist **or** belongs to
|
|
|
|
|
/// another user. All user-facing handlers should use this method.
|
|
|
|
|
async fn get_folder_owned(&self, id: &str, caller_id: &str) -> Result<FolderDto, DomainError>;
|
|
|
|
|
|
2026-02-12 09:41:25 +01:00
|
|
|
/// Gets a folder by its path
|
2025-03-19 00:44:27 +01:00
|
|
|
async fn get_folder_by_path(&self, path: &str) -> Result<FolderDto, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-12 09:41:25 +01:00
|
|
|
/// Lists folders within a parent folder
|
2025-03-19 00:44:27 +01:00
|
|
|
async fn list_folders(&self, parent_id: Option<&str>) -> Result<Vec<FolderDto>, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-15 23:45:11 +01:00
|
|
|
/// Lists folders scoped to a specific owner (for user-facing endpoints).
|
|
|
|
|
/// At root level, only returns folders belonging to this user.
|
|
|
|
|
async fn list_folders_for_owner(
|
|
|
|
|
&self,
|
|
|
|
|
parent_id: Option<&str>,
|
|
|
|
|
owner_id: &str,
|
|
|
|
|
) -> Result<Vec<FolderDto>, DomainError>;
|
|
|
|
|
|
2026-02-12 09:41:25 +01:00
|
|
|
/// Lists folders with pagination
|
2025-03-19 00:44:27 +01:00
|
|
|
async fn list_folders_paginated(
|
2026-02-14 01:29:34 +01:00
|
|
|
&self,
|
2025-03-19 00:44:27 +01:00
|
|
|
parent_id: Option<&str>,
|
2026-02-14 01:29:34 +01:00
|
|
|
pagination: &crate::application::dtos::pagination::PaginationRequestDto,
|
2025-03-19 00:44:27 +01:00
|
|
|
) -> Result<crate::application::dtos::pagination::PaginatedResponseDto<FolderDto>, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-16 00:22:42 +01:00
|
|
|
/// Lists folders with pagination, scoped to a specific owner.
|
|
|
|
|
async fn list_folders_for_owner_paginated(
|
|
|
|
|
&self,
|
|
|
|
|
parent_id: Option<&str>,
|
|
|
|
|
owner_id: &str,
|
|
|
|
|
pagination: &crate::application::dtos::pagination::PaginationRequestDto,
|
|
|
|
|
) -> Result<crate::application::dtos::pagination::PaginatedResponseDto<FolderDto>, DomainError>;
|
|
|
|
|
|
|
|
|
|
/// Renames a folder (ownership verified against caller_id)
|
2026-02-21 13:33:18 +01:00
|
|
|
async fn rename_folder(
|
|
|
|
|
&self,
|
|
|
|
|
id: &str,
|
|
|
|
|
dto: RenameFolderDto,
|
|
|
|
|
caller_id: &str,
|
|
|
|
|
) -> Result<FolderDto, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-16 00:22:42 +01:00
|
|
|
/// Moves a folder to another parent (ownership verified against caller_id)
|
2026-02-21 13:33:18 +01:00
|
|
|
async fn move_folder(
|
|
|
|
|
&self,
|
|
|
|
|
id: &str,
|
|
|
|
|
dto: MoveFolderDto,
|
|
|
|
|
caller_id: &str,
|
|
|
|
|
) -> Result<FolderDto, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-16 00:22:42 +01:00
|
|
|
/// Deletes a folder (ownership verified against caller_id)
|
|
|
|
|
async fn delete_folder(&self, id: &str, caller_id: &str) -> Result<(), DomainError>;
|
2026-02-16 16:18:39 +01:00
|
|
|
|
|
|
|
|
/// Creates a root-level home folder for a user during registration.
|
2026-02-21 13:33:18 +01:00
|
|
|
async fn create_home_folder(
|
|
|
|
|
&self,
|
|
|
|
|
user_id: &str,
|
|
|
|
|
name: String,
|
|
|
|
|
) -> Result<FolderDto, DomainError>;
|
2026-02-24 12:18:38 +01:00
|
|
|
|
|
|
|
|
/// Lists every folder in a subtree rooted at `folder_id` (inclusive),
|
|
|
|
|
/// ordered by path. Uses ltree `<@` — single GiST-indexed query.
|
|
|
|
|
///
|
|
|
|
|
/// Default: returns an empty vec (stubs / mocks).
|
2026-02-25 10:28:34 +01:00
|
|
|
async fn list_subtree_folders(&self, folder_id: &str) -> Result<Vec<FolderDto>, DomainError> {
|
2026-02-24 12:18:38 +01:00
|
|
|
let _ = folder_id;
|
|
|
|
|
Ok(Vec::new())
|
|
|
|
|
}
|
2025-03-19 00:44:27 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-27 01:13:34 +01:00
|
|
|
/**
|
2026-02-15 23:45:11 +01:00
|
|
|
* Primary port for file and folder search.
|
2026-02-14 01:29:34 +01:00
|
|
|
*
|
2026-02-15 23:45:11 +01:00
|
|
|
* All search processing (filtering, scoring, sorting, categorization)
|
|
|
|
|
* is handled server-side in Rust for maximum efficiency.
|
2025-03-27 01:13:34 +01:00
|
|
|
*/
|
|
|
|
|
pub trait SearchUseCase: Send + Sync + 'static {
|
2026-02-15 23:45:11 +01:00
|
|
|
/// Performs a full search based on the specified criteria.
|
2026-02-24 17:15:36 +01:00
|
|
|
///
|
2026-02-25 23:47:51 +01:00
|
|
|
/// Returns `Arc<SearchResultsDto>` so the cache and the caller share
|
|
|
|
|
/// the same allocation — zero-copy on both insert and hit.
|
2026-02-24 17:15:36 +01:00
|
|
|
/// `user_id` identifies the authenticated user so that SQL queries filter
|
|
|
|
|
/// by owner and the result cache is isolated per tenant.
|
2026-02-25 10:28:34 +01:00
|
|
|
async fn search(
|
|
|
|
|
&self,
|
|
|
|
|
criteria: SearchCriteriaDto,
|
|
|
|
|
user_id: &str,
|
2026-02-25 23:47:51 +01:00
|
|
|
) -> Result<Arc<SearchResultsDto>, DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
|
2026-02-15 23:45:11 +01:00
|
|
|
/// Returns quick suggestions for autocomplete (lightweight, fast).
|
|
|
|
|
async fn suggest(
|
|
|
|
|
&self,
|
|
|
|
|
query: &str,
|
|
|
|
|
folder_id: Option<&str>,
|
|
|
|
|
limit: usize,
|
|
|
|
|
) -> Result<SearchSuggestionsDto, DomainError>;
|
|
|
|
|
|
|
|
|
|
/// Clears the search results cache.
|
2025-03-27 01:13:34 +01:00
|
|
|
async fn clear_search_cache(&self) -> Result<(), DomainError>;
|
2026-02-14 01:29:34 +01:00
|
|
|
}
|