feat: Make upload handler work independently without external API

Critical improvement:
- Removed dependency on localhost:3002 register API
- MarkBase now generates file_uuid locally (UUID v4)
- Directly saves to user SQLite database

Changes:
- Removed curl call to external API
- file_uuid = uuid::Uuid::new_v4().replace('-', '')
- Added database save logic:
  * INSERT into file_registry (file_uuid, sha256, file_size)
  * INSERT into file_locations (file_uuid, file_path)
  * INSERT into file_nodes (node_id, label, file_uuid)

Result:
- Files uploaded → immediately saved to database 
- Tree API shows nodes immediately 
- No external API dependency 
- Works for all users (demo, warren, momentry) 

Test result:
 warren upload → file saved to database
 Tree API shows uploaded file
 No empty tree problem

Files:
- src/server.rs (removed external API, added local database save)
This commit is contained in:
Warren
2026-05-17 02:23:45 +08:00
parent 2898935932
commit 95c529b377

View File

@@ -799,30 +799,59 @@ async fn upload_file(
let file_path = format!("{}/{}", user_dir, filename);
// Register with 3002 API via curl
let api_key = "muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69";
let register_json = format!(
r#"{{"file_name":"{}","file_path":"{}"}}"#,
filename, file_path
);
let register_output = std::process::Command::new("curl")
.args([
"-s",
"-X",
"POST",
"http://localhost:3002/api/v1/files/register",
])
.args(["-H", &format!("X-API-Key: {}", api_key)])
.args(["-H", "Content-Type: application/json"])
.args(["-d", &register_json])
.output()
.map(|o| String::from_utf8_lossy(&o.stdout).to_string())
.unwrap_or_default();
// Generate file_uuid locally (no external API dependency)
let file_uuid = uuid::Uuid::new_v4().to_string().replace('-', "");
let file_uuid = serde_json::from_str::<serde_json::Value>(&register_output)
.ok()
.and_then(|v| v["file_uuid"].as_str().map(|s| s.to_string()))
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string().replace('-', ""));
// Save to database (user-specific SQLite)
let db_path = crate::filetree::FileTree::user_db_path(&user_id);
let db_result = tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
let conn = crate::filetree::FileTree::open_user_db(&db_path)?;
// Register file
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
conn.execute(
"INSERT INTO file_registry (file_uuid, sha256, file_size, mime_type, registered_at)
VALUES (?1, ?2, ?3, ?4, ?5)",
rusqlite::params![
&file_uuid,
&file_hash,
file_size,
"", // mime_type (optional)
now
],
)?;
// Add file location
conn.execute(
"INSERT OR IGNORE INTO file_locations (file_uuid, location, created_at)
VALUES (?1, ?2, ?3)",
rusqlite::params![&file_uuid, &file_path, now],
)?;
// Create file node
let node_id = format!("node-{}", uuid::Uuid::new_v4().to_string().replace('-', "")[0..8]);
conn.execute(
"INSERT INTO file_nodes (node_id, label, file_uuid, sha256, node_type, file_size, created_at, updated_at)
VALUES (?1, ?2, ?3, ?4, 'file', ?5, ?6, ?7)",
rusqlite::params![
&node_id,
&filename,
&file_uuid,
&file_hash,
file_size,
now,
now
],
)?;
Ok(())
})
.await;
// Add to file tree
let sha_clone = file_hash.clone();