feat: add migrations, test scripts, and utility tools
- Add database migrations (006-028) for face recognition, identity, file_uuid - Add test scripts for ASR, face, search, processing - Add portal frontend (Tauri) - Add config, benchmark, and monitoring utilities - Add model checkpoints and pretrained model references
This commit is contained in:
111
new_handlers.txt
Normal file
111
new_handlers.txt
Normal file
@@ -0,0 +1,111 @@
|
||||
async fn search_bm25(
|
||||
State(state): State<AppState>,
|
||||
Json(req): Json<SearchRequest>,
|
||||
) -> Result<Json<SearchResponse>, StatusCode> {
|
||||
let limit = req.limit.unwrap_or(10);
|
||||
let query_hash = generate_query_hash(&req.query, req.uuid.as_deref(), limit);
|
||||
let cache_key = keys::bm25_search(&query_hash);
|
||||
let ttl = state.mongo_cache.ttl_search();
|
||||
|
||||
let response = state
|
||||
.mongo_cache
|
||||
.get_or_fetch(&cache_key, ttl, keys::CATEGORY_SEARCH, || async {
|
||||
let pg = PostgresDb::init()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("PG init failed: {}", e))?;
|
||||
|
||||
let bm25_results = pg
|
||||
.search_bm25(&req.query, req.uuid.as_deref(), limit)
|
||||
.await?;
|
||||
|
||||
let results: Vec<SearchResult> = bm25_results
|
||||
.into_iter()
|
||||
.map(|r| SearchResult {
|
||||
uuid: r.uuid,
|
||||
chunk_id: r.chunk_id,
|
||||
chunk_type: r.chunk_type,
|
||||
start_time: r.start_time,
|
||||
end_time: r.end_time,
|
||||
text: r.text,
|
||||
score: r.bm25_score,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok::<SearchResponse, anyhow::Error>(SearchResponse {
|
||||
results,
|
||||
query: req.query.clone(),
|
||||
})
|
||||
})
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
async fn n8n_search_bm25(
|
||||
State(state): State<AppState>,
|
||||
Json(req): Json<SearchRequest>,
|
||||
) -> Result<Json<N8nSearchResponse>, StatusCode> {
|
||||
let limit = req.limit.unwrap_or(10);
|
||||
let query_hash = generate_query_hash(&req.query, req.uuid.as_deref(), limit);
|
||||
let cache_key = keys::n8n_bm25_search(&query_hash);
|
||||
let ttl = state.mongo_cache.ttl_search();
|
||||
|
||||
let response = state
|
||||
.mongo_cache
|
||||
.get_or_fetch(&cache_key, ttl, keys::CATEGORY_N8N_SEARCH, || async {
|
||||
let pg = PostgresDb::init()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("PG init failed: {}", e))?;
|
||||
|
||||
let bm25_results = pg
|
||||
.search_bm25(&req.query, req.uuid.as_deref(), limit)
|
||||
.await?;
|
||||
|
||||
let mut hits = Vec::new();
|
||||
|
||||
for r in bm25_results {
|
||||
if let Some(chunk) = pg
|
||||
.get_chunk_by_chunk_id_and_uuid(&r.chunk_id, &r.uuid)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
{
|
||||
let text = r.text; // Use text from BM25 result
|
||||
let title = extract_title_from_content(&chunk.content);
|
||||
|
||||
let file_path = if chunk.uuid.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let video = pg.get_video_by_uuid(&chunk.uuid).await.ok().flatten();
|
||||
video.map(|v| v.file_path)
|
||||
};
|
||||
|
||||
hits.push(N8nSearchHit {
|
||||
id: chunk.chunk_id.clone(),
|
||||
vid: chunk.uuid.clone(),
|
||||
start: chunk.start_time().seconds(),
|
||||
end: chunk.end_time().seconds(),
|
||||
title: if title.is_empty() {
|
||||
format!("Chunk {}", chunk.chunk_id)
|
||||
} else {
|
||||
title
|
||||
},
|
||||
text,
|
||||
score: r.bm25_score,
|
||||
file_path,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok::<N8nSearchResponse, anyhow::Error>(N8nSearchResponse {
|
||||
query: req.query.clone(),
|
||||
count: hits.len(),
|
||||
hits,
|
||||
})
|
||||
})
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
Reference in New Issue
Block a user