Release v1.0.0 candidate

This commit is contained in:
Accusys
2026-05-08 00:48:15 +08:00
parent 26d9c33419
commit 573714788f
17 changed files with 5040 additions and 895 deletions

View File

@@ -26,6 +26,7 @@ use super::identity_api;
use super::identity_binding;
use super::middleware::api_key_validation;
use super::search::search_routes;
use super::trace_agent_api;
use super::universal_search::universal_search_routes;
use super::visual_chunk_search;
use crate::core::chunk::types::Chunk;
@@ -794,8 +795,6 @@ async fn register_single_file(
.arg(&cut_script)
.arg(&canonical_path)
.arg(&cut_path)
.arg("--threshold")
.arg("27")
.output();
if let Ok(output) = cut_output {
if output.status.success() {
@@ -2246,42 +2245,58 @@ async fn list_jobs(Query(params): Query<JobsQuery>) -> Result<Json<JobListRespon
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
// TODO: 需要修改 PostgresDb::get_pending_jobs 以支持分頁和狀態過濾
// 目前先使用現有方法,獲取所有工作然後手動分頁
let jobs = pg
.get_pending_jobs(1000) // 臨時解決方案:獲取較多工作
let table = crate::core::db::schema::table_name("monitor_jobs");
// Build status IN clause
let statuses: Vec<String> = status_filter
.split(',')
.map(|s| format!("'{}'", s.trim()))
.collect();
let status_clause = statuses.join(",");
let query = format!(
"SELECT id, uuid, video_path, status, current_processor, progress_total, progress_current,
error_count, last_error, started_at::TEXT, updated_at::TEXT, created_at::TEXT,
processors, completed_processors, failed_processors, video_id
FROM {}
WHERE status IN ({})
ORDER BY created_at DESC
LIMIT {} OFFSET {}",
table, status_clause, page_size, offset
);
let count_query = format!(
"SELECT COUNT(*) FROM {} WHERE status IN ({})",
table, status_clause
);
let total_count: i64 = sqlx::query_scalar(&count_query)
.fetch_one(pg.pool())
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
// 過濾狀態
let filtered_jobs: Vec<_> = jobs
.into_iter()
.filter(|j| {
let job_status = j.status.as_str();
status_filter.split(',').any(|s| s.trim() == job_status)
})
.collect();
use crate::core::db::MonitorJobStatus;
let total_count = filtered_jobs.len() as i64;
let rows = sqlx::query(&query)
.fetch_all(pg.pool())
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
// 手動分頁
let paginated_jobs: Vec<_> = filtered_jobs
let job_infos: Vec<JobInfoResponse> = rows
.into_iter()
.skip(offset as usize)
.take(page_size)
.collect();
let job_infos: Vec<JobInfoResponse> = paginated_jobs
.into_iter()
.map(|j| JobInfoResponse {
id: j.id,
uuid: j.uuid,
status: j.status.as_str().to_string(),
current_processor: j.current_processor,
progress_current: j.progress_current,
progress_total: j.progress_total,
created_at: j.created_at.to_string(),
started_at: j.started_at.map(|t| t.to_string()),
.map(|r| {
let status_str: String = r.try_get("status").unwrap_or_default();
let status = MonitorJobStatus::from_db_str(&status_str).unwrap_or(MonitorJobStatus::Pending);
JobInfoResponse {
id: r.try_get("id").unwrap_or(0),
uuid: r.try_get("uuid").unwrap_or_default(),
status: status.as_str().to_string(),
current_processor: r.try_get("current_processor").ok(),
progress_current: r.try_get("progress_current").unwrap_or(0),
progress_total: r.try_get("progress_total").unwrap_or(0),
created_at: r.try_get::<String, _>("created_at").unwrap_or_default(),
started_at: r.try_get::<String, _>("started_at").ok(),
}
})
.collect();
@@ -2537,6 +2552,7 @@ pub async fn start_server(host: &str, port: u16) -> anyhow::Result<()> {
.merge(super::identity_agent_api::identity_agent_routes()) // Phase 5 Routes
.merge(five_w1h_agent_api::five_w1h_agent_routes()) // Phase 3 Routes (5W1H Agent)
.merge(super::media_api::bbox_routes()) // Media: video/bbox/thumbnail
.merge(super::trace_agent_api::trace_agent_routes()) // Trace listing
.merge(search_routes()) // Smart search drill-down
.merge(universal_search_routes()) // Universal / frames / persons search
.merge(protected_routes)
@@ -3242,7 +3258,7 @@ async fn list_pre_chunks(
let data_query = format!(
"SELECT id, processor_type, coordinate_type, coordinate_index,
start_frame, end_frame, start_time, end_time, fps,
data, identity_id, confidence, created_at
data, created_at
FROM {}
WHERE file_uuid = $1 {}
ORDER BY coordinate_index ASC
@@ -3261,8 +3277,6 @@ async fn list_pre_chunks(
Option<f64>,
Option<f64>,
serde_json::Value,
Option<uuid::Uuid>,
Option<f64>,
chrono::DateTime<chrono::Utc>,
)> = sqlx::query_as(&data_query)
.bind(&uuid)
@@ -3283,9 +3297,9 @@ async fn list_pre_chunks(
end_time: row.7,
fps: row.8,
data: row.9.clone(),
identity_id: row.10.map(|id| id.to_string()),
confidence: row.11,
created_at: row.12.to_rfc3339(),
identity_id: None,
confidence: None,
created_at: row.10.to_rfc3339(),
})
.collect();