Files
markbase/docs/filetree.md
Warren e3d6b60825 feat: MarkBase initial version
Phase 1 (Infrastructure):
- Docs: README.md, AGENTS.md, CHANGELOG.md
- Tests: 26 tests (modes_test, filetree_api_test)
- Examples: examples/sample.md, sample.json
- CI/CD: .gitea/workflows/test.yml, release.yml
- Runner: configuration scripts and guides

Phase 2 (Quality):
- Code quality: rustfmt/clippy config
- Security: environment variables
- Test coverage: 62 tests (+36)
- Documentation: CONTRIBUTING.md, docs/api.yaml
- Showcase: demo_features.md, developer_quickstart.md

Test coverage: 75%
Test pass rate: 100%
2026-05-16 15:37:37 +08:00

413 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# File Tree Architecture
## Overview
File Tree是MarkBase的核心模組提供檔案樹管理功能。
**Location:** `src/filetree/`
**Total Lines:** 1234行
---
## Module Structure
```
src/filetree/
├── mod.rs (553行) -核心CRUD操作
├── convert.rs (253行) -檔案轉換功能
├── mode.rs (43行) - DisplayMode trait定義
├── node.rs (82行) -節點資料結構
└── modes/
├── tree.rs (57行) -樹狀顯示模式
├── list.rs (87行) -列表顯示模式
├── grid_sm.rs (72行) -小格狀顯示模式
├── grid_lg.rs (83行) -大格狀顯示模式
└── mod.rs (4行) -模式匯出
```
---
## Database Design
### SQLite Tables
**Location:** `data/users/<user_id>.sqlite`
|Table |Purpose |
|------|--------|
| file_registry |檔案註冊資訊 |
| file_nodes |檔案樹節點 |
| file_locations |檔案位置記錄 |
### file_nodes Schema
```sql
CREATE TABLE file_nodes (
node_id TEXT PRIMARY KEY,
label TEXT NOT NULL,
aliases_json TEXT NOT NULL DEFAULT '{}',
file_uuid TEXT,
sha256 TEXT,
parent_id TEXT,
children_json TEXT NOT NULL DEFAULT '[]',
node_type TEXT NOT NULL DEFAULT 'folder',
icon TEXT,
color TEXT,
bg_color TEXT,
file_size INTEGER,
registered_at TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
sort_order INTEGER NOT NULL DEFAULT 0
);
```
### Node Types
- **folder** -資料夾節點(可包含子節點)
- **file** -檔案節點(指向實體檔案)
---
## Public API13 Functions
### CRUD Operationsmod.rs
|Function |Location |Description |
|----------|----------|-------------|
| user_db_path | 58 |取得資料庫路徑 |
| init_user_db | 62 |初始化資料庫 |
| open_user_db | 74 |開啟資料庫連接 |
| load | 79 |載入檔案樹 |
| insert_node | 120 |插入節點 |
| update_node | 149 |更新節點屬性 |
| update_node_alias | 187 |更新多語言別名 |
| delete_node | 214 |刪除節點 |
| move_node | 220 |移動節點位置 |
| build_tree | 240 |建立樹狀結構 |
### Node Creationnode.rs
|Function |Location |Description |
|----------|----------|-------------|
| new_folder | 27 |建立資料夾節點 |
| new_file_node | 300 |建立檔案節點 |
### Utilities
|Function |Location |Description |
|----------|----------|-------------|
| add_location | 346 |新增檔案位置 |
| get_file_info | 359 |取得檔案資訊 |
---
## REST API7 Routes
### Endpoints
|Route |Method |Function |server.rs |
|------|--------|----------|-----------|
| `/api/v2/tree/:user_id` | GET | get_tree | 61 |
| `/api/v2/tree/:user_id` | DELETE | delete_all_nodes | 64 |
| `/api/v2/tree/:user_id/node` | POST | create_node | 62 |
| `/api/v2/tree/:user_id/node/:node_id` | PUT | update_node | 63 |
| `/api/v2/tree/:user_id/node/:node_id` | DELETE | delete_node | 63 |
| `/api/v2/tree/:user_id/node/:node_id/move` | PUT | move_node | 71 |
| `/api/v2/tree/:user_id/node/:node_id/alias` | PATCH | update_alias | 72 |
| `/api/v2/tree/:user_id/restore` | POST | restore_tree | 65 |
### Query Parameters
- `mode` -顯示模式tree, list, grid_sm, grid_lg
### Examples
```bash
#取得檔案樹(樹狀顯示)
curl http://localhost:11438/api/v2/tree/demo?mode=tree
#取得檔案樹(列表顯示)
curl http://localhost:11438/api/v2/tree/demo?mode=list
#建立節點
curl -X POST http://localhost:11438/api/v2/tree/demo/node \
-H "Content-Type: application/json" \
-d '{"label":"NewFolder", "node_type":"folder"}'
#更新別名
curl -X PATCH http://localhost:11438/api/v2/tree/demo/node/<node_id>/alias \
-H "Content-Type: application/json" \
-d '{"lang":"zh_tw", "value":"新資料夾"}'
```
---
## DisplayMode Trait
### Definitionmode.rs:19
```rust
pub trait DisplayMode: Send + Sync {
fn name(&self) -> &'static str;
fn render(&self, tree: &FileTree) -> Value;
fn sort_options(&self) -> Vec<SortOption>;
fn filter_options(&self) -> Vec<FilterOption>;
}
```
### Implementations
|Mode |File |Purpose |
|------|------|---------|
| Tree | modes/tree.rs |層級樹狀結構顯示 |
| List | modes/list.rs |簡潔列表顯示 |
| GridSm | modes/grid_sm.rs |緊湊格狀顯示 |
| GridLg | modes/grid_lg.rs |寬鬆格狀顯示 |
### Usage
```rust
//取得顯示模式
let mode = filetree::mode::get_mode("tree");
//渲染檔案樹
let rendered = mode.render(&tree);
//取得排序選項
let sort_options = mode.sort_options();
//取得過濾選項
let filter_options = mode.filter_options();
```
---
## File Conversionconvert.rs
### Supported Formats
|Tool |Formats |
|------|---------|
| textutilmacOS | doc, docx, rtf |
| macOS Tools | pages, key, numbers |
| soffice/qlmanage | pptx, ppt, xlsx, xls, odt, epub |
### Functions
- `is_document_ext(ext)` - 檢查是否為文檔格式
- `is_textutil_ext(ext)` - 檢查是否為textutil支援格式
- `is_apple_format_ext(ext)` - 檢查是否為Apple格式
- `get_cached_preview(file_uuid, ext)` - 生成緩存預覽
### Cache Directory
**Location:** `data/cache/`
---
## Testing
### Current Tests7 Tests
|Test |Status |Description |
|------|--------|-------------|
| test_init_and_load_empty_tree | ✅ OK |初始化空檔案樹 |
| test_insert_and_load_node | ✅ OK |插入節點 |
| test_update_node | ✅ OK |更新節點屬性 |
| test_delete_node | ✅ OK |刪除節點 |
| test_move_node | ✅ OK |移動節點位置 |
| test_update_alias | ✅ OK |更新多語別別名 |
| test_build_tree | ✅ OK |建立樹狀結構 |
### Missing Tests
- ❌ convert.rs -檔案轉換功能
- ❌ modes/*.rs - DisplayMode渲染
- ❌ REST API - endpoint測試
### Test Cleanup
Tests create temporary databases: `data/users/test_*.sqlite`
```bash
#清理暫存資料庫
rm data/users/test_*.sqlite
```
---
## Development Examples
### Create Folder
```rust
use crate::filetree::{FileTree, FileNode};
//建立資料夾節點
let folder = FileTree::new_folder("Videos", None);
//插入到資料庫
let conn = FileTree::open_user_db("demo")?;
let mut tree = FileTree::load(&conn, "demo")?;
tree.insert_node(&conn, &folder)?;
```
### Create File Node
```rust
//建立檔案節點
let (file_node, register_sql) = FileTree::new_file_node(
"demo.mp4",
"abc123def456...", // file_uuid
Some("sha256hash"), // sha256
"demo.mp4", // original_name
Some(1024000), // file_size
Some("video/mp4"), // file_type
None, // registered_at
Some(folder.node_id), // parent_id
);
//插入到資料庫
tree.insert_node(&conn, &file_node)?;
```
### Load and Query
```rust
//載入檔案樹
let conn = FileTree::open_user_db("demo")?;
let tree = FileTree::load(&conn, "demo")?;
//建立樹狀結構
let roots = tree.build_tree();
//取得特定顯示模式
let mode = filetree::mode::get_mode("tree");
let rendered = mode.render(&tree);
```
### Update Alias
```rust
//更新多語言別名
tree.update_node_alias(&conn, &node_id, "zh_tw", "影片")?;
tree.update_node_alias(&conn, &node_id, "en_us", "Videos")?;
tree.update_node_alias(&conn, &node_id, "ja_jp", "動画")?;
```
---
## Demo Database
**Location:** `data/users/demo.sqlite`
**Statistics:**
- Total Nodes: 50
- Folders: 5
- Files: 45
**Structure:**
```
Home根資料夾
├── Movies9個檔案
│ ├── view7.mp4
│ ├── Charade_YouTube_24fps.mp4
│ └── ...
├── Marketing26個檔案
│ ├── Screenshot *.png
│ ├── diagram-*.svg
│ └── ...
├── Cartoons5個檔案
│ ├── animal11.jpg
│ ├── animal10.jpg
│ └── ...
└── Other4個檔案
├── people.jpg
└── ...
```
---
## Architecture Diagram
```
┌─────────────────────────────────────┐
│ server.rs │
│ REST API HandlersAxum
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ filetree/mod.rs │
│ FileTree CRUD Operations │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ SQLite Database │
│ data/users/<user_id>.sqlite │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ filetree/mode.rs │
│ DisplayMode Trait │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ filetree/modes/*.rs │
│ Tree, List, GridSm, GridLg │
└─────────────────────────────────────┘
```
---
## Best Practices
### Database Management
- Each user has independent database
- Use UUID for node_id
- Maintain parent-child relationships via parent_id
- Update updated_at timestamp on modifications
### Performance
- Use spawn_blocking for SQLite operationsAxum async
- Cache file_tree in memory if frequently accessed
- Batch operations when possible
### Security
- Validate node_type before insertion
- Check parent_id existence before moving
- Sanitize aliases_json input
---
## Future Improvements
### Planned Features
- Pagination for large file trees
- Search and filter functionality
- File versioning
- Trash binsoft delete
- Batch import/export
### Performance Optimization
- Database connection pooling
- Caching layerRedis
- Async SQLite drivertokio-rusqlite
### Testing Coverage
- convert.rs tests
- DisplayMode tests
- REST API integration tests
- Performance benchmarks
---
**Last Updated:** 2026-05-16
**Version:** 1.0