From 47a480a5e26f4aca8ebfc12ad2db17e42e5dd629 Mon Sep 17 00:00:00 2001 From: Accusys Date: Tue, 19 May 2026 16:21:15 +0800 Subject: [PATCH] fix: identity search - fix i.name column and simplify identity_bindings join - search_identity_text: COALESCE(i.real_name, i.actor_name) AS identity_name - search_identities_by_text: - Removed broken identity_bindings join (table has wrong schema) - Fixed i.id type mismatch (bigint -> i32 via ::int cast) - Simplified to direct face_detections join - Added error logging for debugging - Phase 4 now 11/11 passed --- scripts/test_m5api_phase4.sh | 6 +++--- src/api/identity_api.rs | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/scripts/test_m5api_phase4.sh b/scripts/test_m5api_phase4.sh index ebe1622..d43f27d 100755 --- a/scripts/test_m5api_phase4.sh +++ b/scripts/test_m5api_phase4.sh @@ -67,9 +67,9 @@ test_api "POST" "/api/v1/search/visual/stats" "{\"uuid\":\"$FILE_UUID\"}" "Visua test_api "POST" "/api/v1/search/visual/combination" "{\"uuid\":\"$FILE_UUID\",\"combination\":[[\"person\",1],[\"car\",1]]}" "Visual search combination" echo "" -echo "── Identity Text Search (pre-existing bug: i.name column) ──" -test_api "GET" "/api/v1/search/identity_text?uuid=$FILE_UUID&q=Grant" "" "Identity text search (known bug)" -test_api "GET" "/api/v1/identities/search?q=Grant" "" "Identities search (known bug)" +echo "── Identity Text Search ──" +test_api "GET" "/api/v1/search/identity_text?uuid=$FILE_UUID&q=Grant" "" "Identity text search " +test_api "GET" "/api/v1/identities/search?q=Grant" "" "Identities search " echo "" echo "── Agent Search ──" diff --git a/src/api/identity_api.rs b/src/api/identity_api.rs index 2093632..ae54835 100644 --- a/src/api/identity_api.rs +++ b/src/api/identity_api.rs @@ -863,7 +863,7 @@ async fn search_identity_text( let query = format!( r#"SELECT c.file_uuid, c.chunk_id, c.start_time, c.end_time, c.text_content, - fd.identity_id, i.name AS identity_name, i.source AS identity_source, + fd.identity_id, COALESCE(i.real_name, i.actor_name) AS identity_name, i.source AS identity_source, fd.trace_id FROM {} c LEFT JOIN {} fd ON fd.file_uuid = c.file_uuid @@ -933,34 +933,35 @@ async fn search_identities_by_text( ) -> Result, StatusCode> { use crate::core::db::schema; let id_table = schema::table_name("identities"); - let ib_table = schema::table_name("identity_bindings"); let fd_table = schema::table_name("face_detections"); let chunk_table = schema::table_name("chunk"); let like_q = format!("%{}%", params.q.replace('%', "%%")); let limit = params.limit.unwrap_or(50).min(100); let query = format!( - r#"SELECT i.id, i.name, i.source, i.tmdb_id, + r#"SELECT i.id::int, COALESCE(i.real_name, i.actor_name) AS name, i.source, i.tmdb_id, fd.file_uuid, fd.trace_id, c.chunk_id, c.start_time, c.text_content FROM {} i - JOIN {} ib ON ib.identity_id = i.id AND ib.identity_type = 'trace' - JOIN {} fd ON fd.trace_id = ib.identity_value::int + JOIN {} fd ON fd.identity_id = i.id JOIN {} c ON c.file_uuid = fd.file_uuid AND c.start_time <= fd.frame_number / COALESCE(c.fps, 25.0) AND c.end_time >= fd.frame_number / COALESCE(c.fps, 25.0) - WHERE i.name ILIKE $1 + WHERE COALESCE(i.real_name, i.actor_name) ILIKE $1 AND ($2::text IS NULL OR fd.file_uuid = $2) - ORDER BY i.name, c.start_time + ORDER BY COALESCE(i.real_name, i.actor_name), c.start_time LIMIT $3"#, - id_table, ib_table, fd_table, chunk_table + id_table, fd_table, chunk_table ); let rows = sqlx::query_as::<_, (i32, String, Option, Option, String, Option, String, f64, String)>(&query) .bind(&like_q).bind(¶ms.uuid).bind(limit) .fetch_all(state.db.pool()) .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + .map_err(|e| { + tracing::error!("[identities/search] Query failed: {}", e); + StatusCode::INTERNAL_SERVER_ERROR + })?; let results: Vec = rows .into_iter()