Folders
The FolderRepository manages hierarchical folder organization for resources. Folders support nesting, breadcrumb path resolution, and safe movement with cycle detection.
pub struct FolderRow { pub id: String, pub name: String, pub parent_id: Option<String>, pub created_by: String, pub created_at: DateTime<Utc>, pub updated_at: DateTime<Utc>,}
pub struct CreateFolder { pub name: String, pub parent_id: Option<String>,}parent_id: None means the folder is at root level.
Repository Methods
Section titled “Repository Methods”Folder CRUD
Section titled “Folder CRUD”| Method | Purpose |
|---|---|
get(id) | Fetch single folder |
root_folders(user_id) | List top-level folders |
subfolders(folder_id) | List child folders |
folder_path(id) | Recursive ancestors (for breadcrumbs) |
has_subfolders(id) | Boolean check |
create(input) | Insert new folder |
create_with_id(id, input) | Insert with specific ID |
rename(id, name) | Rename folder |
delete(id, keep_children) | Delete folder |
Folder Movement
Section titled “Folder Movement”| Method | Purpose |
|---|---|
move_folder(id, target_id) | Move into target folder (with cycle detection) |
move_folder_to_parent(id) | Move up one level |
move_folder_to_root(id) | Move to root |
Resource Movement
Section titled “Resource Movement”| Method | Purpose |
|---|---|
move_resource_to_folder(resource_id, folder_id) | Move single resource |
move_resources_to_folder(resource_ids, folder_id) | Batch move |
move_resource_to_parent(resource_id) | Move resource up one level |
move_resource_to_root(resource_id) | Move resource to root |
Cycle Detection
Section titled “Cycle Detection”move_folder walks the ancestor chain of the target to ensure the source folder is not an ancestor, preventing circular references:
pub async fn move_folder(&self, id: &str, target_id: &str) -> Result<()> { // Walk ancestors of target_id // If id is found in the chain → error (would create cycle) // Otherwise, UPDATE folders SET parent_id = target_id WHERE id = id}Delete Behavior
Section titled “Delete Behavior”delete(id, keep_children) supports two modes:
keep_children: true— reparent child folders and resources to the deleted folder’s parent (or root if no parent)keep_children: false— cascade delete all children
Folder Path
Section titled “Folder Path”folder_path(id) returns the full ancestor chain from root to the folder, used for breadcrumb navigation in the UI:
pub async fn folder_path(&self, id: &str) -> Result<Vec<FolderRow>> { // Recursive CTE: walk parent_id chain to root // Returns [root, ..., parent, self]}Migrations
Section titled “Migrations”| Migration | Purpose |
|---|---|
002 | Create folders table with parent_id self-reference |
003 | Add folder_id foreign key to resources table |