From 2ed56b7973ecd222661350c3fc83235168d7a4bd Mon Sep 17 00:00:00 2001 From: Accusys Date: Sun, 19 Jul 2026 21:58:03 +0800 Subject: [PATCH] feat: add sync-status endpoint to update file status based on processor files --- src/api/files.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/api/files.rs b/src/api/files.rs index fe3df14..1300fb8 100644 --- a/src/api/files.rs +++ b/src/api/files.rs @@ -1602,4 +1602,55 @@ pub fn file_routes() -> Router { "/api/v1/file/:file_uuid/metadata", post(update_file_metadata), ) + .route( + "/api/v1/file/:file_uuid/sync-status", + post(sync_file_status), + ) +} + +async fn sync_file_status( + Path(file_uuid): Path, + State(state): State, +) -> Result, StatusCode> { + use crate::core::config::OUTPUT_DIR; + + let output_dir = OUTPUT_DIR.as_str(); + let required_processors = ["face.json", "asrx.json", "ocr.json", "pose.json", "appearance.json"]; + + let mut completed_count = 0; + for processor in &required_processors { + let path = std::path::Path::new(output_dir) + .join(format!("{}.{}", file_uuid, processor)); + if path.exists() { + completed_count += 1; + } + } + + let all_complete = completed_count == required_processors.len(); + let new_status = if all_complete { "completed" } else { "processing" }; + + let videos_table = schema::table_name("videos"); + let result = sqlx::query(&format!( + "UPDATE {} SET status = $1, updated_at = NOW() WHERE file_uuid = $2", + videos_table + )) + .bind(new_status) + .bind(&file_uuid) + .execute(state.db.pool()) + .await; + + match result { + Ok(res) if res.rows_affected() > 0 => Ok(Json(serde_json::json!({ + "success": true, + "file_uuid": file_uuid, + "status": new_status, + "processors_complete": completed_count, + "processors_total": required_processors.len() + }))), + Ok(_) => Err(StatusCode::NOT_FOUND), + Err(e) => { + tracing::error!("[SYNC_STATUS] Update failed: {}", e); + Err(StatusCode::INTERNAL_SERVER_ERROR) + } + } }